C++版加载MNIST图像集合
参考了一下两个链接:
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; }
演示结果如下:

 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号