Opencv矩阵操作基础笔记
来源:互联网 发布:c语言 bool取反 编辑:程序博客网 时间:2024/06/05 17:37
<下面为个人笔记积累,会持续更新内容,发现不对的希望帮忙指出来>
1.关于协方差矩阵:
Opencv中求协方差矩阵:
函数原型为:
//! computes covariation matrix of a set of samplesCV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean, int flags, int ctype=CV_64F);//! computes covariation matrix of a set of samplesCV_EXPORTS_W void calcCovarMatrix( const Mat& samples, CV_OUT Mat& covar, CV_OUT Mat& mean, int flags, int ctype=CV_64F);
举例:
假设有矩阵mu要求它的协方差矩阵Su,代码为:
MatSu;Matmeanu;calcCovarMatrix(mu,Su,meanu,CV_COVAR_ROWS|CV_COVAR_NORMAL);Su.convertTo(Su,CV_64FC1,1.0/(mu.rows-1));
其中,
CV_COVAR_ROWS:说明mu中每一行代表一个样本。
CV_COVAR_NORMAL:使用普通的方法求协方差矩阵。
meanu:是按列求出的mu的平均值,是一个行向量。
*跟maltab比较:
*由于opencv求协方差矩阵的时候默认的规范化|CV_COVAR_SCALE是除以mu.rows,而MATLAB是除以mu.rows-1,这里为了跟MATLAB算出的结果保持一致,在计算的时候先不规范化,算出后再人为的除以mu.rows-1。
2.关于矩阵的范数
向量和矩阵范数的求法:
向量的范数:1-范:所有元素的绝对值之和。
2-范:所有元素的平方之和再求平方根,即向量模。
无穷范:绝对值最大的元素的绝对值。
矩阵的范数:1-范:每列元素绝对值之和最大的那一列的绝对值之和。
2-范:矩阵的最大奇异值,即A.t()*A的最大非负特征值的平方根。
无穷范:每行元素绝对值之和最大的那一行的绝对值之和。
从上面内容可以看出,矩阵范数的求法和向量范数的求法并不相同。
MATLAB中norm();函数可以求向量的范数,也可以求矩阵的范数,但是,在opencv中norm();函数只能用来求向量的范数。如果用来求矩阵的范数,它会把矩阵当做向量来求,得到的结果当然跟maltab不一样。至于矩阵的范数,我没有找到封装,所以自己写了一个求2范的,并不复杂。
opencv求向量范数norm函数的原型:
//! computes norm of arrayCV_EXPORTS double norm(const Mat& src1, int normType=NORM_L2);//! computes norm of the difference between two arraysCV_EXPORTS double norm(const Mat& src1, const Mat& src2, int normType=NORM_L2);//! computes norm of the selected array partCV_EXPORTS_W double norm(const Mat& src1, int normType, const Mat& mask CV_WRAP_DEFAULT(Mat()));//! computes norm of selected part of the difference between two arraysCV_EXPORTS_W double norm(const Mat& src1, const Mat& src2, int normType, const Mat& mask CV_WRAP_DEFAULT(Mat()));
自己实现的求矩阵2范数的函数:
/************************************************//求矩阵的最大奇异值(2范数)//opencv自带的norm只能求向量的,不能求矩阵的!************************************************/double norm2ofMat(Mat src){ double norm2value=0; Mat srcT=src.t(); Mat multi=srcT*src; Mat eigenvalues; eigen(multi,eigenvalues); for(int i=0;i<eigenvalues.rows;i++){ for(int j=0;j<eigenvalues.cols;j++){ double eigenvalue=eigenvalues.ptr<double>(i)[j]; if(eigenvalue>0){ double eigenvalueSqrt=sqrt(eigenvalue); if(eigenvalueSqrt>norm2value) norm2value=eigenvalueSqrt; } } } return norm2value;}
3.Mat类的某些行或者列提取出来单独赋值
(1)假设有Mat类型行向量R和列向量C分别要赋值到矩阵A的第i行和第i列;
Mat ri=A.row(i);
R. copyTo(ri);
Mat ci=A.col(i);
C. copyTo(ci);
(2)假设有Mat类型的矩阵R要赋值到矩阵A的第1-r+1行,R的行数为r小于A的行数,列数等于A的列数。
Mat roi=A(Rect(0,1,A.cols,r+1));//roi起点(0,1)宽(A.cols)高(r+1)。
R. copyTo(roi);
4.矩阵算数运算:
【需要注意的是opencv对+、-、*等符号进行了重载,可以直接像标量算数运算那样进行矩阵算数运算,可逆矩阵求逆用Mat::inv();转置为Mat::t();】
Gemm函数:
在MATLAB中矩阵的广义乘法,就是行乘以列的那种,是gemm而不是Mat::dot,也不是multiply();Mat::dot和multiply();是对应的元素相乘,如果被乘数是标量,那么就是矩阵所有的元素乘以这个标量。
gemm函数原型:
//! implements generalized matrix product algorithm GEMM from BLASCV_EXPORTS_W void gemm(const Mat& src1, const Mat& src2, double alpha, const Mat& src3, double gamma, CV_OUT Mat& dst, int flags=0);
dst=( alpha*src1)xsrc2+(gamma*src3);
关于gemm函数举例:
doublec[2][2]={{1.0,1.0},{1.0,1.0}}; Matm1(2,2,CV_64FC1,c); cout<<"m1:"<<m1<<endl; doubled[2][2]={{2.0,2.0},{2.0,2.0}}; Matm2(2,2,CV_64FC1,d); cout<<"m2:"<<m2<<endl; MatE; Matzero(m1.size(),m1.type()); gemm(m1,m2,1,zero,1,E); cout<<"E=m1·m2:"<<endl;cout<<E<<endl;运算结果:
5.关于数组排序和除重的问题
/*这个是c++的,不是opencv的*/
/************************************************
//将输入的double类型的数组进行筛选然后按降序排列
//筛选规则:删除数组中重复的元素
//in:指向源数组,location指向in中元素在排序后的位置
//返回值:double类型的vector
************************************************/
vector<double> uniqueAndSort(double *in,int *location,int lenIn)
{
vector<double>vec(in,in+lenIn);
vector<double>::iterator iter = unique(vec.begin(),vec.end());
vec.erase(iter,vec.end());
sort(vec.begin(),vec.end());
reverse(vec.begin(),vec.end());
int m=0;
for(iter=vec.begin();iter!=vec.end();m++,iter++){
double value=*iter;
for(int i=0;i<lenIn;i++){
if(in[i]==value)
location[i]=m;
}
}
return vec;
}
int main(int argc, char *argv[]){ QCoreApplication a(argc, argv);
double labels[10]={1,1,1,3,3,3,2,2,2,4}; int location[10]; uniqueAndSort(labels,location,10); cout<<"labels: "; for(int i=0;i<10;i++) cout<<labels[i]<<" "; cout<<endl; cout<<"location: "; for(int i=0;i<10;i++) cout<<location[i]<<" "; cout<<endl;
return a.exec();}运行结果分析:
排序的结果数组A为:4,3,2,1这里函数没有返回,需要可以返回。
location表示labels中的元素在A中的位置,1在A中位置为3, 3在A中位置为1,2在A中位置为2,4在A中位置为0,所以location的结果为:3,3,3,1,1,1,2,2,2,0
- Opencv矩阵操作基础笔记
- OpenCV学习笔记:矩阵的掩码操作
- Matlab矩阵操作基础,学习笔记...
- opencv c++函数 基础3 矩阵的掩码操作
- opencv(Java)的矩阵创建与基础操作
- OpenCV学习笔记一:图像基础操作
- Opencv 矩阵基础
- OpenCV----矩阵操作
- OpenCV 矩阵操作 CvMat
- OPENCV矩阵操作
- opencv-矩阵操作总结
- OpenCV 矩阵操作
- OPENCV 矩阵操作
- Opencv矩阵操作
- OpenCv矩阵操作
- OpenCV 矩阵操作
- OpenCv矩阵操作
- opencv中的矩阵操作
- Spring常用注解
- Xms Xmx PermSize MaxPermSize 区别
- 第十一周项目3 中序线索化二叉树算法
- SSH框架中,请求返回500错误
- C/C++——引用和指针
- Opencv矩阵操作基础笔记
- UILable上如何添加背景图片
- C#关于iTextSharp将html转换为pdf不支持中文问题
- ListView中嵌套GridView关于GridView的高度显示问题
- QT程序图标和窗口图标
- java开发中常用的日期时间工具类 DateUtil
- IOS block
- LeetCode:Reverse Integer
- WebLogic11g-负载分发