今天读取opencv中的Mat数组,已经被打败,真的是类型不对就读不出内容啊,真的要崩溃,故特此记录一下。
1、首先了解一下Mat中对应的各个类型
在opencv中像素点的数据类型能找到对应类似char,int,float,double的,比如说是分别为CV_8UC1,CV_16UC1,CV_32FC1, CV_64FC1,一定要注意是没有这一说法的CV_16FC1。
当Mat中数据的类型为CV_16UC1的时候,这里的16U并不是指unsigned int,而是指的是unsigned short int,因为在OpenCV框架中,int不是16位的,而是32位的
2、创建mat数组
<span style="font-size:14px;">Mat matpixel(rows, cols, types, Scalar(0));
例如:Mat matpixel(src.rows*src.cols, 2, CV_16UC1, Scalar(0));</span>
//对于一个数据类型为type的Mat a来说 type temp = a.at<type>(x,y);
当采用这种方法取元素值得时候,type成为一个麻烦的问题,因为一般我们生成Mat的时候,都是这样的:
Mat a; a.create(Size(x,y), CV_8UC1);
而取元素值时不能写成"a.at<CV_8UC1>(x,y)"或者"a.at<a.type()>(x,y)"。
所以这里列出OpenCV中定义的型别和C++中型别的对应关系,
CV_8SC1 -> char
CV_8UC1 -> unsigned char
CV_16SC1 -> short
CV_16UC1 -> unsigned short
CV_32SC1 -> int
CV_32FC1 -> float
CV_64FC1 -> double
OpenCv中的数据型别命名规则为:CV_(比特数)+(数据类型)+(Channel数),我们也可以直接根据命名规则得到相应的数据型别。
下面举例:
CV_16UC1类型的数据,访问像素(i,j) img.at<ushort>(i,j)即可。
若不知道所属的属性,则可以通过转变数据类型进行获取值。本人一般喜欢转为double型,代码如下:
Mat dta;//位置其数据类型 Mat data = cv::Mat_<double>(_data);//数据类型转换为double int N = data.rows; int D = data.cols; /// mean Mat m = Mat::zeros(1, D, data.type());//如果想新建一个相同数据类型的数组,使用type()即可 for (int j = 0; j<D; j++) { for (int i = 0; i<N; i++) { m.at<double>(0, j) += data.at<double>(i, j); } }
对于保存图片的Mat来说,下面给出读取Mat中数据的例子:
//对于单通道图像 //0表示读取的灰度图像(彩色图像将转换成灰度图像) Mat image_C1 = imread ( "lena.jpg", 0 ); uchar elem = image_C1.at<uchar>( x, y ); //对于彩色图像 Mat image_C3 = imread ( "lena.jpg" ); Vec3b elem_3 = image_C3.at<Vec3b>(x,y); //里面包含三个元素:elem_3.val[0]、elem_3.val[1]、elem_3.val[2]