Opencv Mat矩阵操作

1.生成矩阵:

Mat image(240, 320, CV8UC3);

第一个参数是rows,该矩阵的行数;第二个参数是cols,该矩阵的列数;第三个参数是该矩阵元素的类型。这句话表示创建一个大小为240×320的矩阵,里面的元素为8位unsigned型,通道数(channel)有3个。

image.create(480, 640, CV8UC3);

分配(或重新分配)image矩阵,把大小设为480×640,类型设为CV8UC3。

Mat A33(3, 3,CV_32F, Scalar(5));

定义并初始化一个3×3的32bit浮点数矩阵,每个元素都设为5。

Mat B33(3, 3,CV_32F);
B33 = Scalar(5);

和上面的作用一样。

Mat C33 =Mat::ones(3, 3, CV32F)*5.0;

ones函数很像MATLAB里的语句。这句的意思是先定义一个3×3的32bit浮点数矩阵,元素全为1,所有元素再乘以5.0。

Mat D33 =Mat::zeros(3, 3, CV32F) + 5.0;

和上面类似,先定义个3×3的32bit浮点数矩阵,元素全为0,再将所有元素加上5.0;

Mat D33 = Mat::eye(4,4,CV_64F);//对角矩阵
double a = CV_PI/3;
Mat A22 = (Mat_(2, 2) << cos(a), -sin(a), sin(a), cos(a));

CV_PI就是圆周率。是创建一个2×2的float矩阵,把后面四个三角函数值分别赋给4个元素。

float B22data[] ={cos(a), -sin(a), sin(a), cos(a)};
Mat B22 = Mat(2, 2, CV32F, B22data).clone();

第一句创建一个普通数组B22data,第二句创建一个2×2的32bit浮点数矩阵,并使用用B22data数组里的值初始化,然后克隆一下赋给B22矩阵。
为什么这里还要克隆一下,不是多此一举吗?不是,因为用一个数组去初始化一个矩阵的话,你会发现这个矩阵引用了数组的内存地址。不克隆的话,上面例程的后果是B22data数组、Mat(2,2…)这个临时变量矩阵、B22矩阵这三把勺子都插在同一个碗里。

randu(image,Scalar(0), Scalar(256));

把image弄成一个符合正太分布的随机数矩阵,rand表示random,u表示uniform;第二个参数是随机数下限,包含该数;第三个参数是随机数上限,不包含该数。

randn(image,Scalar(128), Scalar(10));

高斯分布的随机数矩阵;第二个参数是均值,第三个参数是标差。

矩阵输出:

cout<< "M = " << endl << " " << M<< endl << endl;

2. 赋值运算

Mat A,C;    //仅创建了头部
Mat B(A);    //复制构造函数
C=A;    //复制运算

**注:**赋值运算符和复制构造函数 (构造函数)只复制头,没有数据。

src.copyTo(dst);    //把src矩阵中的数据拷贝到dst
src.convertTo(dst, type, scale, shift);

缩放并转换到另外一种数据类型:dst:目的矩阵 type:需要的输出矩阵类型,或者更明确的,是输出矩阵的深度,如果是负值(常用-1)则输出矩阵和输入矩阵类型相同 scale和shift:缩放参数,也可以写为alpha和beta这个命令也等价于下面的转换公式:opencv释放mat对象 opencv mat操作_数组

m.row(i), m.col(i);

创建一个矩阵头,指向m矩阵的第i行/列,新的矩阵头所代表的矩阵和m矩阵的第i行/列共享数据。

m.rowRange(Range(i1,i2));
m.colRange(Range(j1,j2));

创建一个矩阵头,指向m矩阵的第i1到i2行或者第j1到j2列

m.diag(i);

创建一个矩阵头,指向m矩阵的对角线,生成的是一个单列矩阵,O(1)复杂度,不拷贝数据。i=0时表示主对角线,i>0表示下半边的对角线,i<0表示上半边的对角线。

m(Range(i1,i2),Range(j1,j2));    //Range(i1,i2)包含i1不包含i2  行列编号从0开始

从矩阵m中的第i1行到第i2行以及第j1列到第j2列所划定的范围提取一个小矩阵。

m(Range::all(),Range(j1,j2));    //Range::all()表示所有行 [j1,j2]列
m.repeat(ny,nx);

把m矩阵贴马赛克,获取一个大矩阵,在y方向上重复ny次,在x方向上重复nx次。

flip(src,dst,dir);

翻转矩阵,dir是翻转方向,0表示沿x轴翻转,1表示沿y轴翻转,-1表示沿x轴和y轴都进行翻转。

3、算术运算

1.加法

I = I1 + I2;    //等同add(I1,I2,I);
add(I1,I2,dst,mask,dtype);
scaleAdd(I1,scale,I2,dst);    //dst=scale*I1+I2;

2.减法

absdiff(I1,I2,I);    //I=|I1-I2|;
A-B;A-s;s-A;-A;
subtract(I1,I2,dst);

3.乘法

I = I.mul(I);    //点乘,I.mul(I,3);-->I=3*I.^2
Mat C=A.mul(5/B);    //==divide(A,B,C,5);
A * B;    //矩阵相乘
A.dot(B);    //A和B点乘,然后求所有元素和, 
pow(src,double p,dst);    //如果p是整数dst(I)=src(I)^p;其他|src(I)|^p
Mat::cross(Mat);    //三维向量(或矩阵)的叉乘,A.cross(B)

4.除法

divide(I1,I2,dst,scale,int dtype=-1);    //dst=saturate_cast(I1*scale/I2);
A/B;  alpha/A;    //都是点除

4、其他操作

1.矩阵元素访问
A.rows    //矩阵行数     
A.cols    //矩阵列数
A.row(i)    //取第i行  行编号从0开始
A.col(j)    //取第i列  列编号从0开始
A.at<type>(i,j)    //访问矩阵第(i,j)  注意矩阵A的类型,否则异常或取值出错 如:A为CV_32CF1时,type为int型时,所取值为异常值,不是矩阵值。
2.矩阵变形:
A.reshape(int cn, int rows);

参数cn:新的通道数;如果cn值为0表示变换前后通道数不变
参数rows:新的行数;如果rows值为0表示变换后矩阵的行数不变
该函数会为当前矩阵创建一个新的矩阵头(指针),新的矩阵拥有不同的尺寸或者不同的通道数,其优点在于运算复杂度为O(1),不用复制矩阵数据.正是因为不用复制数据,所以在转变过程中要保证原数据矩阵在数据上的连续性(这里的连续性是相对于原矩阵来说)。

注:A要为单独矩阵,不能直接为矩阵的一部分。

3.转置运算:
A.t()
4.矩阵求逆:
A.inv(type)

Type: CV_LU - 最佳主元选取的高斯消除法
CV_SVD - 奇异值分解法 (SVD)
CV_SVD_SYM - 对正定对称矩阵的 SVD 方法

5.SVD分解:
SVD::compute(A,D,U,V,flag=0);

Flag可以为空即:SVD::compute(A,D,U,V),D为列矩阵,元素为A的特征值,A=U*diag(D)*V ,diag(D)是把D变成对角阵,与matlab相比,U与matlab值相同,正负号不同,V为matlab中V的转置,正负号不同。

6.最大最小值:

不需的值可以设成0,如: minMaxLoc(A, 0, 0, 0, &max_loc); 求A中最大值的位置,max_loc定义为:Point max_loc max_loc.x为横坐标,对应图像的列,max_loc.y为纵坐标,对应图像的行。

7.矩阵合并

hconcat(A,B,dst1)   水平方向合并
vconcat(A,B,dst2)   垂直方向合并

A=[1 ,2; B=[5,6; dst1=[ 1 2 5 6;
  3 ,4 ]   7,8]    3 4 7 8 ]
dst2=[1 2;
   3 4;
   5 6;
   7 8]

8.矩阵底部添加、删除元素
A.push_back(B);    //B添加在A的底部,B可以是常数
A.pop_back(m);    //从A的底部删除m行

注:添加时A,B的类型和行数必须相同,删除时,m不能大于A的行数,否则异常,另外,添加和删除后的矩阵,不能用于算术运算,否则异常。

9.矩阵行列求和
Reduce( inputArry src, outputArry, int dim, int rtype,int dtype=-1);

dim :
矩阵被简化后的维数索引.0意味着矩阵被处理成一行,1意味着矩阵被处理成为一列,-1时维数将根据输出向量的大小自动选择.
rtype :
简化操作的方式,可以有以下几种取值:
CV_REDUCE_SUM-输出是矩阵的所有行/列的和.
CV_REDUCE_AVG-输出是矩阵的所有行/列的平均向量.
CV_REDUCE_MAX-输出是矩阵的所有行/列的最大值.
CV_REDUCE_MIN-输出是矩阵的所有行/列的最小值.