Bootstrap

opencv图像遍历中出现的问题

opencv图像遍历中出现的问题

    IplImage * src_id_img,*mask_img;
    uchar *pColor,*pMask;
    int imglen;

    cvNamedWindow("src");
    cvNamedWindow("dest");

    if ((src_id_img = cvLoadImage("9.png")) == NULL)
    {
        printf("can not find\n");
    };
    //原图像的所有像素长度
    imglen = src_id_img->width * src_id_img->height;
    //pcolor指向图像的像素数据
    pColor = (uchar*)src_id_img->imageData;
    //创建和原图像一样大的单通道图像
    mask_img = cvCreateImage(cvGetSize(src_id_img), 8, 1);
    //同pcolor类似
    pMask = (uchar*)mask_img->imageData;

    for (int m = 0; m < imglen; m++)
    {
        *pMask++ = *pColor;//将每个像素的第一个通道的值付给pmask
        pColor += 3;///原图为三通道 指向下一个像素
    }
    cvShowImage("src", src_id_img);
    cvShowImage("dest", mask_img);
    cvWaitKey();
    cvReleaseImage(&mask_img);

在如上代码中,我企图将9.png这幅图片的第一个通道(B)分离出来保存在mask_img中。其结果为:
这里写图片描述
这里写图片描述
发现分离后的图片发生了形变。

这是由于IPLImage对齐方式的影响,导致图片中有为了保持对齐的空像素点。
opencv中图片保存是,每4个字节对齐,如果不是4的整数倍就必须用空字节补齐,所以在IPLImage结构体中,有时候widthstep != width *3(对于8位三通道图像而言),原因就是每一行的最后往往有几个“凑数的像素”,对于上面的程序而言,就忽略了这几个“凑数的像素”,所以图片整体发生了偏移。

举个例子:
一幅8位三通道图像每行有413个像素,那width = 413,正常情况下,一行应该是1239个字节,也就是widthStep应该是1239,但实际widthstep是1240,增加了1个字节进行对齐。如果不考虑这一个字节的话就会发生上面的偏移情况。

;