opencv(二)-Mat矩阵操作

1. Mat矩阵操作

1.1 创建矩阵

//第一个参数是rows,第二个参数是cols
	Mat image(240, 320, CV_8UC3);
	//不能为矩阵设置初值,在改变尺寸是重新分配image矩阵
	image.create(480, 640, CV_8UC3);
	//定义并初始化一个3×3的32bit浮点数矩阵,每个元素都设为5
	Mat A(3, 3, CV_32F, Scalar(5));
	Mat B(3, 3, CV_32F);
	B = Scalar(5);
	Mat C = Mat::ones(3, 3, CV_32F) * 5;
	Mat D = Mat::zeros(3, 3, CV_32F) + 5;
	//使用数组初始化矩阵
/***用Bdata数组里的值初始化,然后克隆一下赋给E矩阵。之所以克隆,是因为用一个数组去初始化一个矩阵,这个矩阵引用了数组的内存地址。不克隆的话,上面例程的后果是Bdata数组、Mat(2,2…)这个临时变量矩阵、E矩阵都指向统一内存空间。***/
	double a = CV_PI / 3;
	float Bdata[] = { cos(a), -sin(a), sin(a), cos(a) };
	Mat E = Mat(2, 2, CV_32F, Bdata).clone();
  //对小矩阵使用逗号分隔符初始化函数
	Mat F = (Mat_<double>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
	//符合正太分布的随机数矩阵,第二个参数是随机数下限,包含该数;第三个参数是随机数上限,不包含该数。
	randu(image, Scalar(0), Scalar(256));
	//高斯分布的随机数矩阵;第二个参数是均值,第三个参数是标差。
	randn(image, Scalar(128), Scalar(10));

1.2 赋值运算

/***赋值运算符和复制构造函数 (构造函数)只复制头,没有数据***/
Mat A,C;    //仅创建了头部
Mat B(A);    //复制构造函数
C=A;    //复制运算
src.copyTo(dst);    //把src矩阵中的数据拷贝到dst
src.convertTo(dst, type, scale, shift);//缩放并转换,type负值(常用-1)则输出矩阵和输入矩阵类型相同
//创建一个矩阵头,指向m矩阵的对角线,i=0时表示主对角线,i>0表示下半边的对角线,i<0表示上半边的对角线。
m.diag(i);
//翻转矩阵,dir是翻转方向,0表示沿x轴翻转,1表示沿y轴翻转,-1表示沿x轴和y轴都进行翻转。
flip(src,dst,dir);

1.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.乘法
	 //mul:两个Mat矩阵对应位的乘积,计算结果是跟A或B行列数一致的一个Mat矩阵
	 //若声明AB时没有定义AB的数据类型,则默认AB的数据类型跟A和B保存一致;
	 I = I.mul(I);    //点乘,I.mul(I,3);-->I=3*I.^2
	 Mat C = A.mul(5 / B);    //==divide(A,B,C,5);
	 multiply();
	 mulTransposed()//计算矩阵和矩阵的转置的乘积,AT * A
	 // A*B要求矩阵类型是CV_32F、 CV_64FC1、 CV_32FC2、 CV_64FC2 。若选用其他类型,比如CV_8UC1,编译器会报错:
	 A * B;    //矩阵相乘
	 
	 A.dot(B);    //A和B点乘,然后求所有元素和,向量积
	 
	 pow(src, double p, dst);    //求幂,如果p是整数dst(I)=src(I)^p;其他|src(I)|^p
	 sqrt()//计算矩阵逐元素的平方根
	 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;    //都是点除
	//5.转置
	A.t()
	transpose()
	//6.求逆
	//Type: CV_LU - 最佳主元选取的高斯消除法
    //CV_SVD - 奇异值分解法 (SVD)
    //CV_SVD_SYM - 对正定对称矩阵的 SVD 方法
	A.inv(type)
	invert(temp, temp1,  DECOMP_SVD);
	//7.解方程
	/***Flag可以为空即:SVD::compute(A,D,U,V),D为列矩阵,元素为A的特征值,
	A=U*diag(D)*V ,diag(D)是把D变成对角阵,与matlab相比,U与matlab值相同,正负号不同,
	V为matlab中V的转置,正负号不同。***/
	SVD::compute(A,D,U,V,flag=0;
	solve()//求出线性方程组的解
	solveCubic()//找到三次方程的实根
	solvePoly()//找到多项式方程的复根
	//8.最大最小值,均值
	mean()//求均值
	//均值和标准差,src为多通道或多维矩阵时,则函数分别计算不同通道的均值与标准差,
	//因此返回的mean和stddev为对应维度的向量;
	meanStdDev(src,mean,stddev)
	[minMaxLoc() vs minMaxIdx()](https://blog.csdn.net/fangyan90617/article/details/100540020)
	//9.矩阵行列求和
	/**dim :0一行,1一列,-1时维数将根据输出向量的大小自动选择.
    rtype :
    简化操作的方式,FLAG:
    CV_REDUCE_SUM-输出是矩阵的所有行/列的和.
    CV_REDUCE_AVG-输出是矩阵的所有行/列的平均向量.
    CV_REDUCE_MAX-输出是矩阵的所有行/列的最大值.
    CV_REDUCE_MIN-输出是矩阵的所有行/列的最小值.**/
	reduce( inputArry src, outputArry, int dim, int rtype,int dtype=-1);
	sum()//矩阵所有元素求和
	determinant()//计算矩阵的行列式
	//10.计算矩阵的特征值和特征向量;
	//正定矩阵(positive definite matrix):矩阵的特征值都是正数;
	//半正定矩阵(semi-definite matrix):矩阵的特征值都是非负数(正数和0);
	//判断矩阵是否正定或者半正定就需要计算矩阵的特征值和特征向量,
	eigen(myMat, eValuesMat, eVectorsMat);
	//11.傅里叶变换和余弦变换
	dct, idct正、逆离散余弦变换,idct同dct(src, dst, flags | DCT_INVERSE);
     dft, idft正、逆离散傅立叶变换, idft同dft(src, dst, flags | DTF_INVERSE)mulSpecturms()//两个傅立叶频谱间逐元素的乘法
	//12.归一化
	norm()//求范数,1-范数、2-范数、无穷范数
	normalize()//标准化
	//13.向量
	magnitude()//计算向量的长度
	phase()//相位计算,即两个向量之间的夹角
	polarToCart()//已知角度和幅度,计算对应的二维向量
	mahalanobis()//马氏距离,协方差的逆
    //其他
	trace()//计算矩阵的迹
	calcCovarMatrix()//计算协方差阵
	countNonZero()//计算矩阵中的非零元素个数,用于计算物体的像素或面积
	setIdentity()设置单元矩阵
	cartToPolar, polarToCart笛卡尔坐标与极坐标之间的转换

2. Mat子矩阵操作

2.1子矩阵创建

//1.使用Range定义ROI
 Mat a=m(Range(i1, i2), Range(j1, j2));    //Range(i1,i2)包含i1不包含i2  行列编号从0开始
Mat b=m(Range::all(), Range(j1, j2));    //Range::all()表示所有行 [j1,j2]列
//2.使用Rect定义ROI
Mat a=m(Rect(200,200,300,400)); 

//示例
Mat src1 = Mat::zeros(Size(400, 400), CV_8UC3);
Rect rect(100, 100, 100, 100);
src1(rect) = Scalar(0, 0, 255);

2.2子矩阵赋值

//矩阵A的子矩阵都赋值为1个常数2
A(Range(row, row + n), Range(col, col + m)) = 3;
//将矩阵A赋值给矩阵B的1个子矩阵
A.copyTo(B(Range(row, row + n), Range(col, col + m)));

3. Mat矩阵变形

//1.变形
//参数cn:新的通道数;如果cn值为0表示变换前后通道数不变
//参数rows:新的行数;如果rows值为0表示变换后矩阵的行数不变
//该函数会为当前矩阵创建一个新的矩阵头(指针),不用复制矩阵数据.
//A要为单独矩阵,不能直接为矩阵的一部分。
A.reshape(int cn, int rows);
//2.合并
hconcat(A,B,dst1)   水平方向合并
vconcat(A,B,dst2)   垂直方向合并
//3.矩阵底部添加、删除元素
A.push_back(B);    //B添加在A的底部,B可以是常数
A.pop_back(m);    //从A的底部删除m行

参考

1. 原文链接:https://blog.csdn.net/qq_18150255/article/details/90648407

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值