这是我的代码
int reverseInt(int i) {
unsigned char c1, c2, c3, c4;
c1 = i & 255;
c2 = (i >> 8) & 255;
c3 = (i >> 16) & 255;
c4 = (i >> 24) & 255;
return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;
}
void create_image(CvSize size, int channels, unsigned char* data[28][28], int imagenumber) {
string imgname; ostringstream imgstrm;string fullpath;
imgstrm << imagenumber;
imgname=imgstrm.str();
fullpath="D:\\"+imgname+".jpg";
IplImage *imghead=cvCreateImageHeader(size, IPL_DEPTH_16S, channels);
imghead->imageData=(char *)data;
cvSaveImage(fullpath.c_str(),imghead);
}
int main(){
ifstream file ("D:\\train-images.idx3-ubyte",ios::binary);
if (file.is_open())
{
int magic_number=0; int number_of_images=0;int r; int c;
int n_rows=0; int n_cols=0;CvSize size;unsigned char temp=0;
file.read((char*)&magic_number,sizeof(magic_number));
magic_number= reverseInt(magic_number);
file.read((char*)&number_of_images,sizeof(number_of_images));
number_of_images= reverseInt(number_of_images);
file.read((char*)&n_rows,sizeof(n_rows));
n_rows= reverseInt(n_rows);
file.read((char*)&n_cols,sizeof(n_cols));
n_cols= reverseInt(n_cols);
unsigned char *arr[28][28];
for(int i=0;i<number_of_images;++i)
{
for(r=0;r<n_rows;++r)
{
for(c=0;c<n_cols;++c)
{
file.read((char*)&temp,sizeof(temp));
arr[r][c]= &temp;
}
}
size.height=r;size.width=c;
create_image(size,1, arr, i);
}
}
return 0;
}
答案 0 :(得分:1)
你有:
unsigned char temp=0;
...
file.read((char*)&temp,sizeof(temp));
这样你就可以将一个字节读入一个字符,然后用文件中的每个后续字节覆盖它。 当你这样做时:
create_image(size,3, &temp, i);
temp
只有一个字符长,只包含文件中的最后一个字节,所以你的图像最终只是在临时后记忆中出现的任何内容。
您需要分配一个数组来保存图像数据,并在填充数据时将指针递增到它。
您也在创建3通道图像,但MNIST数据只是单通道,对吗?
另外,
imghead->imageData=(char *)data;
应该是
cvSetData(imghead, data, size.width)
和
unsigned char *arr[28][28];
应该是
unsigned char arr[28][28];
答案 1 :(得分:1)
我也想将MNIST与OpenCV一起使用,这个问题是我最接近的问题。
我认为我发布的是基于cv::Mat
而不是iplimage
的“复制和粘贴 - >快乐”版本,因为这样更容易使用。此外,cv :: Mat是首选,因为 OpenCV 2.x 。
此方法可为您提供成对的cv::Mat
图像和标签int
s的向量。玩得开心。
std::vector<std::pair<cv::Mat,int>> loadBinary(const std::string &datapath, const std::string &labelpath){
std::vector<std::pair<cv::Mat,int>> dataset;
std::ifstream datas(datapath,std::ios::binary);
std::ifstream labels(labelpath,std::ios::binary);
if (!datas.is_open() || !labels.is_open())
throw std::runtime_error("binary files could not be loaded");
int magic_number=0; int number_of_images=0;int r; int c;
int n_rows=0; int n_cols=0; unsigned char temp=0;
// parse data header
datas.read((char*)&magic_number,sizeof(magic_number));
magic_number=reverseInt(magic_number);
datas.read((char*)&number_of_images,sizeof(number_of_images));
number_of_images=reverseInt(number_of_images);
datas.read((char*)&n_rows,sizeof(n_rows));
n_rows=reverseInt(n_rows);
datas.read((char*)&n_cols,sizeof(n_cols));
n_cols=reverseInt(n_cols);
// parse label header - ignore
int dummy;
labels.read((char*)&dummy,sizeof(dummy));
labels.read((char*)&dummy,sizeof(dummy));
for(int i=0;i<number_of_images;++i){
cv::Mat img(n_rows,n_cols,CV_32FC1);
for(r=0;r<n_rows;++r){
for(c=0;c<n_cols;++c){
datas.read((char*)&temp,sizeof(temp));
img.at<float>(r,c) = 1.0-((float)temp)/255.0; // inverse 0.255 values
}
}
labels.read((char*)&temp,sizeof(temp));
dataset.push_back(std::make_pair(img,(int)temp));
}
return dataset;
}
与上面相同:
int reverseInt(int i) {
unsigned char c1, c2, c3, c4;
c1 = i & 255; c2 = (i >> 8) & 255; c3 = (i >> 16) & 255; c4 = (i >> 24) & 255;
return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;
}