Mat - 图像数据结构体(矩阵操作)

前言

Mat(图像数据结构体)代替了CvMat和IPIImage,并将功能模块化。

Mat它由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。

一 Mat 初始化

1.构造函数初始化

CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]

首先要定义其尺寸,即行数和列数,然后,需要指定存储元素的数据类型以及每个矩阵点的通道数。Scalar 是个short型vector。指定这个能够使用指定的定制化值来初始化矩阵。例如以下函数:

Mat (int rows, int cols, int type)

Mat (int rows, int cols, int type, const Scalar &s)

2.Create()function:函数

M.create(4,4,CV_8UC(2));

3.MATLAB形式的初始化方式:zeros(), ones(), :eyes() 。

使用以下方式指定尺寸和数据类型:

Mat E = Mat::eye(4, 4, CV_64F);

cout << “E = ” << endl << ” ” << E << endl << endl;

Mat O = Mat::ones(2, 2, CV_32F);

cout << “O = ” << endl << ” ” << O << endl << endl;

Mat Z = Mat::zeros(3,3, CV_8UC1);

cout << “Z = ” << endl << ” ” << Z << endl << endl;

*.Mat c = (Mat_<double>(3,3)<<0,1,2,3,4,5,6,7,8);

《Mat - 图像数据结构体(矩阵操作)》 Mat_快捷构造方法列表

*.随机填充randu()

Mat R = Mat(3, 2, CV_8UC3);

randu(R, Scalar::all(0), Scalar::all(255));

二 Mat 中像素的读取(矩阵元素读取)

很多时候,我们需要读取某个像素值,或者设置某个像素值;在更多的时候,我们需要对整个图像里的所有像素进行遍历。OpenCV提供了多种方法来实现图像的遍历。

函数at()来实现读去矩阵中的某个像素,或者对某个像素进行赋值操作。下面两行代码演示了at()函数的使用方法。

If matrix is of type CV_8U then use Mat.at<uchar>(y,x).

If matrix is of type CV_8S then use Mat.at<schar>(y,x).

If matrix is of type CV_16U then use Mat.at<ushort>(y,x).

If matrix is of type CV_16S then use Mat.at<short>(y,x).

If matrix is of type CV_32S then use Mat.at<int>(y,x).

If matrix is of type CV_32F then use Mat.at<float>(y,x).

If matrix is of type CV_64F then use Mat.at<double>(y,x).

例: uchar value = grayim.at(i,j);//读出第i行第j列像素值

         grayim.at(i,j)=128; //将第i行第j列像素值设置为128

当然Mat也提供迭代器使用去修改像素的值

MatIterator_<uchar> grayit,grayend;      

for( grayit = grayim.begin<uchar>(), grayend = grayim.end<uchar>(); grayit != grayend; ++grayit)

MatIterator_<Vec3b> grayit,grayend;   

for( grayit = grayim.begin<Vec3b>(), grayend = grayim.end<Vec3b>(); grayit != grayend; ++grayit)

最高效的遍历像素的方法就是使用指针了。

Vec3b *p = grayim.ptr<Vec3b>(i)

uchar *p = grayim.ptr<uchar>(i);

三 Mat 表达式

其实之前再看这个像素提取的时候有点懵,如果先介绍这个Mat表达式就好了,其实它提供的也就是一些矩阵的操作,加减乘除之类,至于像素提取,那就是将图像矩阵化,按照矩阵计算方法提取某行,某列,某个子矩阵。

在介绍Mat表达式的时候需要介绍一个另外的函数出cv::print()

po:其实OC这个语言兼容C/C++,使用printf,cout函数是没有问题的,在这里就用OpenCV的Print方法,他这里提供打印它的数据结构。

《Mat - 图像数据结构体(矩阵操作)》 print函数

下面给出Mat表达式所支持的运算。下面的列表中使用A和B表示Mat类型的对象,使用s表示Scalar对象,alpha表示double值。

加法,减法,取负:A+B,A-B,A+s,A-s,s+A,s-A,-A

缩放取值范围:A*alpha

矩阵对应元素的乘法和除法:A.mul(B),A/B,alpha/A

矩阵乘法:A*B(注意此处是矩阵乘法,而不是矩阵对应元素相乘)

矩阵转置:A.t()

矩阵求逆和求伪逆:A.inv()

矩阵比较运算:A cmpop B,A cmpop alpha,alpha cmpop A。此处cmpop可以是>,>=,==,!=,<=,<。如果条件成立,则结果矩阵(8U类型矩

阵)的对应元素被置为255;否则置0。

矩阵位逻辑运算:A logicop B,A logicop s,s logicop A,~A,此处logicop可以是&,|和^。

34

矩阵对应元素的最大值和最小值:min(A, B),min(A, alpha),max(A, B),max(A, alpha)。

矩阵中元素的绝对值:abs(A)

叉积和点积:A.cross(B),A.dot(B)

总结

OpenCV函数中输出图像的内存分配是自动完成的(如果不特别指定的话)。

使用OpenCV的C++接口时不需要考虑内存释放问题。

赋值运算符和拷贝构造函数( ctor )只拷贝信息头。

使用函数 clone() 或者 copyTo() 来拷贝一副图像的矩阵。

    原文作者:我的名字好长好长灬
    原文地址: https://www.jianshu.com/p/fe7c40974206
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞