惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
A
About on SuperTechFans
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Blog — PlanetScale
Blog — PlanetScale
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
Vercel News
Vercel News
G
Google Developers Blog
J
Java Code Geeks
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
Cloudbric
Cloudbric
L
LINUX DO - 最新话题
MyScale Blog
MyScale Blog
H
Heimdal Security Blog
PCI Perspectives
PCI Perspectives
Attack and Defense Labs
Attack and Defense Labs
S
Security @ Cisco Blogs
Latest news
Latest news
I
Intezer
L
Lohrmann on Cybersecurity
C
CXSECURITY Database RSS Feed - CXSecurity.com
月光博客
月光博客
T
Threatpost
博客园 - 【当耐特】
S
Schneier on Security
P
Privacy International News Feed
G
GRAHAM CLULEY
T
Tenable Blog
AWS News Blog
AWS News Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
雷峰网
雷峰网
博客园 - Franky
Engineering at Meta
Engineering at Meta
美团技术团队
S
Secure Thoughts
T
Troy Hunt's Blog
Microsoft Security Blog
Microsoft Security Blog
SecWiki News
SecWiki News
V
Visual Studio Blog
人人都是产品经理
人人都是产品经理
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Cisco Talos Blog
Cisco Talos Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Martin Fowler
Martin Fowler
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - 凤凰_1

多边形近似:最小周长多边形算法MPP 多阈值otsu的opencv实现 在Opencv中自定义了一个相位函数,获取复数矩阵的相位 cvIsInf与cvIsNan函数 Mandelbrot set 以parallel_for_实现 opencv的并行操作parallel_for_的问题 CV_WRAP和CV_EXPORTS_W opencv超级像素示例 opencv中自定义的双线性二次插值的图像旋转及缩放 在Qt中,如何在sheets末端添加新的sheet opencv4.x 中的plot函数绘制二维Mat C++版DNN最简主体框架 C++版全连接神经网络 C++版的神经网络训练用的图像集合加载 c\c++宏定义,四个参数求最大值 - 凤凰_1 - 博客园 自定义c++二维动态数组 用Cmake 编译OpenCV常见的错误 Opencv中的dft()和idft()示例 C++仿Matlab的bsxfun函数
C++版加载MNIST图像集合
凤凰_1 · 2022-07-16 · via 博客园 - 凤凰_1

参考了一下两个链接:

Parsing MNIST data, save as bmp images · GitHub

(20条消息) C++读取MNIST数据集_N3verL4nd的博客-CSDN博客_c++读取mnist

大小端转换程序1:

void reverseInt(int& i)
{
    unsigned char ch1, ch2, ch3, ch4;
    ch1 = i & 255;
    ch2 = (i >> 8) & 255;
    ch3 = (i >> 16) & 255;
    ch4 = (i >> 24) & 255;
    i=((int)ch1 << 24) + ((int)ch2 << 16) + ((int)ch3 << 8) + ch4;
}

大小端转换程序2:

void swap_endian(uint32_t& val)
{
    val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
   val=(val << 16) | (val >> 16);
}

MNIST类:

class MNIST
{
public:

    Mat* m;//图库指针
    int* label;//标号指针。标号与图片一一对应。
    static int magic_num_l;//Label的魔数
    static int numOfImages_l;//Label与图片一一对应,该参数是图片数
    static int magic_num_i; //图库的魔数
    static int numOfImages_i;//图库的图片数,要与Label一一对应
};
int MNIST::magic_num_l=0;
int MNIST::numOfImages_l=0;
int MNIST:: magic_num_i=0; //图库的魔数
int MNIST::numOfImages_i=0;//图库的图片数,要与Label一一对应

加载图像集函数:

void readMnist(MNIST&mnist,string labelpath,string imgpath)
{
//    string filename="D:/Qt/MyImage/MNIST/train-labels.idx1-ubyte";

    ifstream file(labelpath, ios::binary);//打开Label文件的对象
    ifstream imgfile(imgpath, ios::binary);//打开图库的对象
    if(!file.is_open())
    {
        cerr<<"label open err!"<<endl;
        exit(1);
    }
    if(!file.is_open())
    {
        cerr<<"images set open err!"<<endl;
        exit(1);
    }
    int magic_num_l=0,numOfImages_l=0;//通过file读取Label的魔数和图片数,之后再赋值给MNIST成员变量
    int magic_num_i=0,numOfImages_i=0;//通过imgfile读取图库的魔数和图片数,之后再赋值给MNIST成员变量
    //读取图片label集的magic number和图片数量number of image.
    file.read((char*)&magic_num_l,sizeof(magic_num_l));
    file.read((char*)&numOfImages_l,sizeof(numOfImages_l));
    //读取image集合的magic number和图片数量number of image.
    imgfile.read((char*)&magic_num_i,sizeof(magic_num_i));
    imgfile.read((char*)&numOfImages_i,sizeof(numOfImages_i));
    //大小端转换
    reverseInt(magic_num_l);//label大小端转换
    reverseInt(numOfImages_l);//label大小端转换
    reverseInt(magic_num_i);//img magic number大小端转换
    reverseInt(numOfImages_i);//img number大小端转换
    cout<<"magic_num_l="<<magic_num_l<<" , numOfImages_l="<<numOfImages_l<<endl;
    cout<<"magic_num_i="<<magic_num_i<<" , numOfImages_i="<<numOfImages_i<<endl;
//     mnist=new MNIST[numOfImages_l];
     mnist.magic_num_l=magic_num_l;
     mnist.numOfImages_l=numOfImages_l;
     unsigned char * label=new unsigned char[numOfImages_l];
     mnist.label=new int[numOfImages_l];//为标号label分配内存
     mnist.m=new Mat[numOfImages_l];//为图像集分配内存
      file.read((char*)label,sizeof(char)*numOfImages_l);;//读取标号
//读取一副图片的行、列数
      uint img_rows,img_cols;
      imgfile.read((char*)&img_rows,sizeof(img_rows));
      imgfile.read((char*)&img_cols,sizeof(img_cols));
      swap_endian(img_rows);
      swap_endian(img_cols);
      cout<<"img_rows="<<img_rows<<" , img_cols="<<img_cols<<endl;
      //读取图像
      uchar *pixs=new uchar[img_rows*img_cols*numOfImages_i];
      imgfile.read((char*)pixs,img_rows*img_cols*numOfImages_i);


    for(int i=0;i<numOfImages_l;i++)
    {
       mnist.label[i]=label[i];
       uchar *p=pixs +i*img_cols*img_rows;
       mnist.m[i]=Mat(img_rows,img_cols,CV_8U,p);
    }

    file.close();
    imgfile.close();

}

演示程序:

int main()
{
    MNIST mnist;
    string labelpath="D:/Qt/MyImage/MNIST/train-labels.idx1-ubyte";
    string imgpath="D:/Qt/MyImage/MNIST/train-images.idx3-ubyte";
    readMnist(mnist,labelpath,imgpath);
    int blank=4;//图片之间间隔
    int width=(28+blank),height=(28+blank);
    Mat imgPlay(height*10,height*10,CV_8U,Scalar(255));
    for(int i=0;i<100;i++)
    {
        int y=i/10,x=i%10;
        Mat temp=imgPlay(Rect(x*width,y*height,width,height));
        Mat mi;
        copyMakeBorder(mnist.m[i],mi,0,blank,0,blank,BORDER_CONSTANT,Scalar(255));
        mi.copyTo(temp);
    }
    imshow("image demo",imgPlay);
    waitKey();
    return 0;
}

演示结果如下: