简单代码示例:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
double getPSNR(const Mat& video1, const Mat& video2);
int main()
{
// 读取视频
VideoCapture videoCapture1("001.asf");
VideoCapture videoCapture2("002.asf");
// 判断视频能否打开
if (!videoCapture1.isOpened())
{
cout << "视频1打开失败" << endl;
return -1;
}
if (!videoCapture2.isOpened())
{
cout << "视频2打开失败" << endl;
return -1;
}
//判断两个视频帧尺寸是否一样
Size videoSize1 = Size(videoCapture1.get(CAP_PROP_FRAME_WIDTH), videoCapture1.get(CAP_PROP_FRAME_HEIGHT));
Size videoSize2 = Size(videoCapture2.get(CAP_PROP_FRAME_WIDTH), videoCapture2.get(CAP_PROP_FRAME_HEIGHT));
if (videoSize1 != videoSize2)
{
cout << "两个视频帧尺寸不一样" << endl;
return -1;
}
//输出视频的帧宽度、帧高度、帧数
cout << "帧宽度:" << videoSize1.width << "帧高度:" << videoSize1.height << "帧数:" << videoCapture1.get(CAP_PROP_FRAME_COUNT) << endl;
const char* videoStr1 = "视频1";
const char* videoStr2 = "视频2";
namedWindow(videoStr1, WINDOW_AUTOSIZE);
namedWindow(videoStr2, WINDOW_AUTOSIZE);
moveWindow(videoStr1, 400, 0);
moveWindow(videoStr2, videoSize1.width, 0);
double psnrValue;
Mat videoFrame1, videoFrame2;
int frameNum = 0;
while (1)
{
videoCapture1 >> videoFrame1;
videoCapture2 >> videoFrame2;
if (videoFrame1.empty() || videoFrame2.empty())
{
cout << "视频已读完" << endl;
break;
}
imshow(videoStr1, videoFrame1);
imshow(videoStr2, videoFrame2);
// 务必加上延迟
waitKey(30);
frameNum++;
psnrValue = getPSNR(videoFrame1, videoFrame2);
cout << setiosflags(ios::fixed) << setprecision(3);
cout << "两个视频帧的相似度:" << psnrValue << "dB" << endl;
}
waitKey(0);
return 0;
}
double getPSNR(const Mat& video1, const Mat& video2)
{
Mat similar;
absdiff(video1, video2, similar);
similar.convertTo(similar, CV_32F);
similar = similar.mul(similar);
Scalar s = sum(similar);
double see = s.val[0] + s.val[1] + s.val[2];
if (see < 1e-10)
{
cout << "相似度过低" << endl;
return 0;
}
else
{
double mse = see / (double)(video1.channels() * video1.total());
double psnr = 10.0 * log10((255 * 255) / mse);
return psnr;
}
}