1、遍历图像的4种方式:at<typename>(i,j)
通过上面的例子我们可以看出,at方法取图像中的点的用法:
image.at<uchar>(i,j):取出灰度图像中i行j列的点。
image.at<Vec3b>(i,j)[k]:取出彩色图像中i行j列第k通道的颜色点。其中uchar,Vec3b都是图像像素值的类型,不要对Vec3b这种类型感觉害怕,其实在core里它是通过typedef Vec<T,N>来定义的,N代表元素的个数,T代表类型。
2、高效一点:用指针来遍历图像
从上面的例子中可以看出,取出图像中第i行数据的指针:image.ptr<uchar>(i)。
值得说明的是:程序中将三通道的数据转换为1通道,在建立在每一行数据元素之间在内存里是连续存储的,每个像素三通道像素按顺序存储。也就是一幅图像数据最开始的三个值,是最左上角的那像素的三个通道的值。
image.at<uchar>(i,j)=image.data+i*image.step+j*image.elemSize();
我觉得应该是image.ptr<uchar>(i,j)=image.data+i*image.step+j*image.elemSize();
因为image.ptr<uchar>(i,j)取到的是指针,而image.at<uchar>(i,j)计算的是像素值。
提醒的是,image.at<uchar>(i,j)应该取地址。但是image.ptr<uchar>(i,j)这种写法是不对的,因为ptr这个方法是返回图像某一行的指针。文档里是这样描述的:Returns a pointer to the specified matrix row