2013-06-01 23 views
0

对不起,这可能有点重复,但我无法修复它。我参与了手写OCR应用程序。我在这里使用MNIST数字数据库进行培训。我使用以下代码here从数据库读取像素并重新创建图像。程序不会给出任何错误,但它会给出无意义的图像(完全黑色和不清晰的像素图案)作为输出。有人能解释这个原因吗? plz帮助如何从MNIST数字数据库读取像素并创建iplimage

这里是我的代码

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; 
} 

回答

1

您有:

unsigned char temp=0; 
... 
file.read((char*)&temp,sizeof(temp)); 

与正在读一个字节到一个单一的字符,并用文件中的每个后续字节覆盖它。 当你这样做:

create_image(size,3, &temp, i); 

temp只有一个字符,并且只包含文件中的最后一个字节,所以你的形象最终成为只是无论发生什么事要在memeory温度后。 您需要分配一个数组来保存图像数据,并在填充数据时向其中增加一个指针。

此外,您正在创建3通道图像,但MNIST数据只有单通道,对不对?

此外,

imghead->imageData=(char *)data; 

应该是

cvSetData(imghead, data, size.width) 

unsigned char *arr[28][28]; 

应该是

unsigned char arr[28][28]; 
+0

编辑你的问题,以显示代码它是目前 – Bull

+0

我改变的问题与当前的代码 –

+0

非常感谢你考虑我的问题。它的工作很好。非常感谢你。 –

1

我也想用OpenCV使用MNIST,这个问题是我得到的最接近的。

我以为我发布了一个基于cv::Mat而不是iplimage的“复制& paste-> be happy”版本,因为这样更容易处理。另外,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; 
} 
相关问题