昊虹君 发表于 2022-11-21 13:21

使用OpenCV计算两幅图像的协方差

要计算协方差首先要知道协方差的数学原理。

定义 Cov(X,Y) = E{ }为随机量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

//出处:昊虹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;

}
运行结果如下:
http://pic1.hhai.cc/pic1/2022/2022-11/005/01.png

如果您对代码中的“cv::Scalar”对象不太清楚,那么可以参考下面这篇博文:
https://www.hhai.cc/thread-144-1-1.html

如果您对代码中的矩阵元素乘法、加法、减法不太清楚,那么可以参考下面这篇博文:
https://www.hhai.cc/thread-143-1-1.html
页: [1]
查看完整版本: 使用OpenCV计算两幅图像的协方差