Opencv Mat矩阵操作(整理借鉴+个人总结)

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.;
ones函数很像MATLAB里的语句吧。这句的意思是先定义一个3×3的32bit浮点数矩阵,元素全为1,所有元素再乘以5.0。
Mat D33 =Mat::zeros(3, 3, CV32F) + 5.;
和上面类似,先定义个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这个命令也等价于下面的转换公式:m(x,y) =saturate_cast(α(*this)(x,y)+β)

Mat A=m.clone();//复制

 

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轴都进行翻转。

三、算术运算

 

http://blog.sina.com.cn/s/blog_afe2af380101bqhz.html

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;都是点除

四、其他运算

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分解:

几种用法:http://blog.sina.com.cn/s/blog_6109b5d00101ag7a.html

SVD::computeA,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.矩阵合并

http://blog.csdn.net/yang6464158/article/details/12944799

 

hconcat(A,B,dst1)   水平方向合并

vconcat(A,B,dst2)   垂直方向合并

A=[1 ,2;       B=[5,6;          dst1=[ 1 2 5 6;     dst2=[1 2;

3 ,4 ]           7,8]                  3 4 7 8 ]            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-输出是矩阵的所有行/列的最小值.  

  • 8
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值