贴上一段很简单的测试代码
int main()
{
Mat a(100,100,CV_8UC3,Scalar(366,366,366));
MatIterator_<Vec3b> it = a.begin<Vec3b>();
cout << int((*it)[0]) << endl;
imshow("a",a);
Mat b(100,100,CV_32FC3,Scalar(366,366,366));
MatIterator_<Vec3f> itc = b.begin<Vec3f>();
cout << (*itc)[0] << endl;
imshow("b",b);
waitKey(0);
return 0;
}输出结果如下图:
这段代码能够说明一些问题,即图片a中的CV_8UC3指的就是Mat里面的类型是uchar类型的,并且通道数是3,当我们用Scalar(366,366,366)给其赋值,输出他的B通道像素值还是255,这是由于uchar类型的范围就是在[0,255]之间决定的。
而图片b中的CV_32FC3指的就是Mat里面的类型是float类型的,并且通道数是3,当我们用Scalar(366,366,366)给其赋值,输出的B通道的像素值就是我们所赋的366,因为float类型的范围远大于366,是可以输出的,原因是一个float所占的内存也要比uchar多,uchar是一个字节,float是4个字节,所以其能表示的范围也更大。
在三通道的时候,我们用MatIterator迭代器或者Mat.at
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;你会发现根本没有Vec1b这一说,为什么呢?当时CV_8UC3的时候表示是3个通道每个通道是uchar类型的,而当时CV_8UC1的时候,表示一个通道,其类型是uchar,既然如此,都一个通道了,直接用uchar访问不就好了?还用得着Vec1b吗?当然以后可能opencv也会提供这样的访问方式,但本质上还是一个uchar。
同理可得,可看Vec3f的定义:
typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;同样还是没有Vec1f,原因同上,对类型为CV_32FC1访问的时候用float做模板类型即可访问,例
Mat c(100,100,CV_32FC1,Scalar(366));
MatIterator_itc;
写了以上这些,希望对大家能有一些帮助,最后总结下就是用迭代器或者at方法访问图片像素的时候,一定要根据Mat图片的数据类型(uchar,int,float,double)以及通道数
(1,2,3...)来决定,否则会出现一些因为数据类型不对而难以检查出来的bug。