openCV 图像相加,位运算,协方差,绝对值,比较

本文详细介绍了OpenCV中的基本运算、位运算及矩阵操作,并通过一个实例对比了OpenCV与MATLAB在计算协方差矩阵上的不同结果。指出OpenCV计算的协方差矩阵比MATLAB大(n-1)倍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:http://blog.csdn.net/Dr_Neo/article/details/44107269

(1)基本运算

两图像相加:

add(InputArray src1,InputArray src2, OutputArray dst, InputArray mask=noArray(),int dtype=-1):如可用add(A,B,C)来计算C=A+B;如果指定了图像掩模mask(注:mask必须为单通道),则运算只在mask对应像素部位null的像素上进行,add(A,B,C,mask)意为if(mask[i]0)c[i]=a[i]+b[i];

addWeighted(InputArray src1,double alpha, InputArray src2, double beta, double gamma,OutputArraydst, int dtype=-1):计算加权和,如addWeighted(A,k1,B,k2,k3,C)表示C=k1*A+k2*B+k3;

scaleAdd(A,k1,B,C)表示C=k1*A+B

减:subtract(A,B,C)表示C=A-B

乘:mutiply(A,B,C,k)表示C=k*A*B

divide(InputArray src1,InputArray src2, OutputArray dst, double scale=1,int dtype=-1):除法,divide(A,B,C,k)表示C=(A*k/B);也可以直接用一个scale来除以array,divide(k,B,C)表示C=k/B

当然还有其他计算符,如log()、exp()

 

位运算:

bitwise_and(InputArray src1,InputArray src2, OutputArray dst, InputArray mask=noArray()):按位与,bitwise_and(A,B,C,mask)表示if(mask[i])a[i]^b[i]=c[i]

bitwise_not(A,B,mask):按位非,b[i] =~a[i]

bitwise_or(A,B,C):按位或,C=AB

bitewise_xor(A,B,C):按位异或,C=AB

 

此处需要注意的是,所有这些运算都会调用cv::saturate_cast函数来进行截断操作,以保证输出像素值都在合理的范围之内。另外,OpenCV对c++的很多操作符都进行了重载,所以可以直接使用运算符+,=,*,/,&,|,~,^,<,>等来对图像矩阵进行操作,矩阵求逆m.inv(),矩阵转置m.t(),行列式m.determinant(),向量模v.norm(),向量叉乘v1.cross(v2),向量点积v1.dot(v2)

 (2)矩阵操作

calcCovarMatrix():计算协方差矩阵

invert(InputArray src,OutputArray dst, int flags=DECOMP_LU):求逆矩阵

sqrt(InputArray src,OutputArray dst):计算平方根

求绝对值:

abs(const Mat& m):求绝对值,输入参数可是矩阵也可是表达式,如:C=abs(A),C=abs(A-B)

absdiff(InputArray src1,InputArray src2, OutputArray dst):absdiff(A,B,C)等价于C=abs(A-B)

cartToPolar(InputArray x, InputArray y,OutputArray magnitude, OutputArray angle, boolangleInDegrees=false):计算二维矢量的幅值和向角

dct(InputArray src,OutputArray dst, int flags=0):离散余弦变换

dft(InputArray src,OutputArray dst, int flags=0, int nonzeroRows=0):离散傅里叶变换

flip(InputArray src,OutputArray dst, int flipCode):对图像进行翻转,flipCode>0,进行垂直翻转;flipCode=0,进行水平翻转;flipCode<0,同时进行水平、垂直翻转;


 

(3)比较操作

CheckRange():用来判断输入array中的每个元素是否都处于某一范围内

compare(InputArray A, InputArray B,OutputArray C, int cmpop):根据参数cmpop的值来决定A和B比较的方式,其值有CMP_EQ,CMP_GT, CMP_GE, CMP_LT, CMP_LE, CMP_NE,结果输出为C;

min():如C=min(A,B)表示c[i]=min(a[i],b[i])

max():与min()类似


注意,此处所有函数在调用时都要加上命名空间cv::

opencv里面,基本上矩阵、向量能想到的操作都有相对应的函数,非常之多,在此不能一一列出,具体的在opencv的online documentation里面都有。建议大家在实际编程时,遇到跟矩阵相关的运算、操作时都先去查阅一下opencv的online documentation,要是里面有现成的函数就可以直接调用了,没有的再去自己想办法写。有关矩阵操作符的库函数主要集中在opencv_core模块中。


今天用到opencv求解矩阵的协方差矩阵,无意中发现了一个问题,写出来供大家参考。

  1. #include <opencv2/opencv.hpp>  
  2. #include <iostream>  
  3.   
  4. using namespace std;  
  5. using namespace cv;  
  6.   
  7. void displayMat(Mat& mat)  
  8. {  
  9.     for (int i = 0;i<mat.rows;i++)    
  10.     {    
  11.         for (int j = 0;j<mat.cols ;j++)    
  12.         {    
  13.             printf("%f  ",mat.at<double>(i,j));    
  14.         }    
  15.         printf("\n");    
  16.     }  
  17. }  
  18.   
  19. int main()  
  20. {  
  21.     double data[5][4] = { 1, 2, 3 , 4 ,    
  22.                   5, 6, 7 , 8 ,    
  23.                   9, 0, 1 , 3 ,    
  24.                   2, 4, 6 , 8 ,    
  25.                   1, 3, 5 , 9   
  26.                  };    
  27.     Mat mat(5,4,CV_64FC1) ;    
  28.     for (int i =0;i<mat.rows;i++)    
  29.     {    
  30.         for (int j = 0;j<mat.cols ;j++)    
  31.         {    
  32.             mat.at<double>(i,j) = data[i][j];    
  33.         }  
  34.     }  
  35.     Mat covMat;    
  36.     Mat meanMat;    
  37.   
  38.     calcCovarMatrix(mat,covMat,meanMat,CV_COVAR_NORMAL|CV_COVAR_ROWS);  
  39.     cout<<"cov:"<<endl;  
  40.     //打印矩阵  
  41.     displayMat(covMat);  
  42.     cout<<"mean:"<<endl;  
  43.     displayMat(meanMat);  
  44.     return 0;  
  45. }  

实验结果:

  1. cov:  
  2. 47.200000  -11.000000  -15.200000  -19.200000  
  3. -11.000000  20.000000  21.000000  19.000000  
  4. -15.200000  21.000000  23.200000  23.200000  
  5. -19.200000  19.000000  23.200000  29.200000  
  6. mean:  
  7. 3.600000  3.000000  4.400000  6.400000  

只看这个结果你肯定不会发现任何问题,下面让我们看看matlab中的结果
  1.  data=[1, 2, 3 , 4;  
  2.        5, 6, 7 , 8;  
  3.        9, 0, 1 , 3;   
  4.        2, 4, 6 , 8;  
  5.        1, 3, 5 , 9 ];  
  6.   
  7. >> cov(data)  
  8.   
  9. ans =  
  10.   
  11.    11.8000   -2.7500   -3.8000   -4.8000  
  12.    -2.7500    5.0000    5.2500    4.7500  
  13.    -3.8000    5.2500    5.8000    5.8000  
  14.    -4.8000    4.7500    5.8000    7.3000  
  15.   
  16. >> cov(data)*4  
  17.   
  18. ans =  
  19.   
  20.    47.2000  -11.0000  -15.2000  -19.2000  
  21.   -11.0000   20.0000   21.0000   19.0000  
  22.   -15.2000   21.0000   23.2000   23.2000  
  23.   -19.2000   19.0000   23.2000   29.2000  

这次你肯定会发现问题了,是的,OpenCV中求得的协方差矩阵要比matlab中的大4倍!

经过我多次实验的出结论:opencv中求得的协方差矩阵比matlab中的大(n-1)倍!(n是矩阵的行数)

不知道是什么原因,有知道的大神可以说一下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值