在图像处理像素访问如果没有考虑字节对齐,会出现计算出的图像的数据是不正确的,出现“歪斜”现象。
图像使用拉布拉斯算子进行锐化,结果是不正确的。
//主程序
Mat image = imread("2.jpg");//源图像
Mat biggerImg_CUBIC(Row_B, Col_B, CV_8UC3);
resize(image, biggerImg_CUBIC, biggerImg_CUBIC.size(), 0, 0, INTER_CUBIC);
IplImage* psrc = &IplImage(biggerImg_CUBIC);
int widthstep1 = psrc->widthStep;
MatStep widthstep2 = biggerImg_CUBIC.step;
IplImage *output = cvCreateImage(CvSize(Col_B,Row_B),8,3);
IplImage *input = cvCloneImage(psrc);
sharpenImage(input, output);
//sharpenImage锐化
void sharpenImage(const IplImage* image, IplImage *result/*const CvArr &image, CvArr &result*/)
{
int rwidthstep = result->widthStep;
/*拉普拉斯滤波核3*3
0 -1 0
-1 5 -1
0 -1 0 */
//处理除最外围一圈外的所有像素值
int withstep = image->widthStep;
uchar* data = (uchar *)image->imageData;
int step = image->widthStep / sizeof(uchar);
int channels = image->nChannels;
/*;
if (NULL == data)
{
return;
}
*/
int bytes = 3 * image->width;
int widthstep = image->widthStep;
for (int i = 1; i<image->height - 1; i++)
{
//continue memery linear memery
const uchar * pre = (data + (i - 1)*widthstep);//前一行
const uchar * cur = (data + (i)*widthstep);//当前行,第i行
const uchar * next = (data + (i + 1)*widthstep);//下一行
int ch = image->nChannels;//通道个数
int startCol = ch;//每一行的开始处理点
int endCol = (image->width - 1)* ch;//每一行的处理结束点
//output image should be fixed to 4 bytes allignment
uchar * output = (uchar *)result->imageData + (i*(rwidthstep ))+ ch;//输出图像的第i行
for (int j = startCol; j < endCol; j++)
{
//saturate_cast<uchar>保证结果在uchar范围内
*output++ = saturate_cast<uchar>(5 * cur[j] - pre[j] - next[j] - cur[j - ch] - cur[j + ch]);
}
}
uchar pixel1 =*( (uchar *)result->imageData + (10*(rwidthstep )) + 10*3 );
}
尽管输入图像Mat,转化为IplImage*后,IplImage的widthstep仍然为3198,但是对应cvCreateImage创建出来的空间的widthstep并非是3198,需要考虑输出图像内存空间的对齐,采用自身的widthstep(3200)访问。
哈哈,Mat的内存存储估计和老版本的结构IPlImage有所区别吧,Mat结构得到MatStep对应的值也是3198,并不是3200字节对齐的值。