要计算协方差首先要知道协方差的数学原理。
定义 Cov(X,Y) = E{ [X-E(X)][Y-E(Y)] }为随机量X与Y的协方差。
其中E(X)为随机变量X的期望(均值),E(Y)为随机变量Y的期望(均值)。
我们通常用下面的这个公式计算协方差。
Cov(X,Y)=E(XY)-E(X)E(Y)
另外,大家还可以注意一下方差与协方差之间的关系,如下:
D(X+Y) = D(X)+D(Y)+2Cov(X,Y)
知道了原理,就可借助代码实现了。
OpenCV环境下实现求两幅图像C++源码的代码如下:
代码中用到的两幅图像百度网盘下载链接:
https://pan.baidu.com/s/11sObYLhjzSQ1ejTpD3Selw?pwd=1h9c
[C++] 纯文本查看 复制代码
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术
//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询
//OpenCV版本 OpenCV3.0
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
// 读取幅待计算协方差值的图像
cv::Mat srcImage1 = cv::imread("F:/material/images/2022/2022-11/PSNR-SSIM/hand1.jpg", 1);
if (srcImage1.empty())
return -1;
cv::Mat srcImage2 = cv::imread("F:/material/images/2022/2022-11/PSNR-SSIM/hand2.jpg", 1);
if (srcImage2.empty())
return -1;
cv::Mat I1, I2;
// 转换成32浮点数进行平方操作
srcImage1.convertTo(I1, CV_32F);
srcImage2.convertTo(I2, CV_32F);
Mat I1I2;
multiply(I1, I2, I1I2);
cv::Scalar E_I1, E_I2, E_I1I2;
E_I1 = mean(I1); //对应于公式中的E(X)
E_I2 = mean(I2); //对应于公式中的E(Y)
E_I1I2 = mean(I1I2); //对应于公式中的E(XY)
cv::Scalar E_I1_I2; //对应于公式中的E(X)E(Y)
multiply(E_I1, E_I2, E_I1_I2);
cv::Scalar Cov_I1I2; //对应于公式中的Cov(X,Y),即两幅图像的协方差
subtract(E_I1I2, E_I1_I2, Cov_I1I2);
cout << "两幅图像各通道的协方差分别为:\n" << Cov_I1I2 << endl;
}
运行结果如下:
如果您对代码中的“cv::Scalar”对象不太清楚,那么可以参考下面这篇博文:
https://www.hhai.cc/thread-144-1-1.html
如果您对代码中的矩阵元素乘法、加法、减法不太清楚,那么可以参考下面这篇博文:
https://www.hhai.cc/thread-143-1-1.html |