Mat和IplImage的4字节对齐问题
首先说一下我发现这个神奇的问题的过程:我是在做产品的有效区域查找时发现,好好的算法有时候可以准确的提取产品有效区域,有时候会出问题,后来就将二值化图像像素值打印出来,最后发现有时候其中会出现一个、两个或者三个205,开始一直以为是我在某个地方对图像数据进行了操作,后来将所有操作都给取消,还是经常(为什么不说总是呢,因为确实有时候没出现)会出现205后来我调试的时候看到了这个:
我当时就惊讶了,这。。。这是为什么,后来看了http://blog.csdn.net/qianqing13579/article/details/41957463 之后我就豁然开朗,特别兴奋,因为这问题折磨了我三天(可能是我水平太差)。
以下是我所看的文章
Mat中的图像数据是不对齐的,而IplImage中的图像数据是4字节对齐的,
所以在访问IplImage图像数据的时候,要特别注意widthStep这个属性,每行的字节数不是width*nchannels而是widthStep,因为每行可能会有字节填充的
- //测试图片,9*7单通道灰度图
- void TestMat4ALigned()//测试Mat是否字节对齐
- {
- Mat mat=imread("D:/Image/Small/White.bmp",-1);
- int widthStep_Mat=mat.step[0];//9
- IplImage *iplImage=cvLoadImage("D:/Image/Small/White.bmp",-1);
- int widthStep_Ipl=iplImage->widthStep;//12
- int pixelCount=mat.cols*mat.rows;
- //打印出Mat
- uchar *imageData=mat.data;
- printf("Mat\n");
- for (int i=0;i<=pixelCount-1;++i)
- {
- printf("%d,",*imageData++);//挨个打印出来,没有填充的数据
- }
- printf("\n\n");
- //打印出IplImage
- uchar *imageData_Ipl=(uchar *)iplImage->imageData;
- printf("IplImage\n");
- for (int i=0;i<=pixelCount-1;++i)
- {
- printf("%d,",*imageData_Ipl++);//挨个打印出来,填充的数据
- }
- printf("\n\n");
- ////////////////////////////IplImage转为Mat//////////////////////////////////////////////
- //将字节对齐的IplImage转化为Mat,看看是否还是字节对齐
- Mat ipl2Mat_True(iplImage,true);//拷贝数据
- int withStep3=ipl2Mat_True.step[0];//9
- uchar *imageData2=ipl2Mat_True.data;
- printf("Mat ipl2Mat_True(iplImage,true)\n");
- for (int i=0;i<=pixelCount-1;++i)
- {
- printf("%d,",*imageData2++);//挨个打印出来,填充的数据
- }
- printf("\n\n");
- //将字节对齐的IplImage转化为Mat,看看是否还是字节对齐
- Mat ipl2Mat_false(iplImage,false);//修改为非拷贝数据
- int withStep4=ipl2Mat_false.step[0];//12
- uchar *imageData3=ipl2Mat_false.data;
- printf("Mat ipl2Mat_false(iplImage,false)\n");
- for (int i=0;i<=pixelCount-1;++i)
- {
- printf("%d,",*imageData3++);//挨个打印出来,填充的数据
- }
- }
结果:
当将IplImage转为Mat的时候
参数需要设置为ture,如果设置为false则每行还是4字节对齐
- IplImage iplImage;
- Mat mat(iplImage,true);//拷贝数据,此时mat就是非4字节对齐了