Video Input with OpenCV and similarity measurement(使用opencv测量两个视频的相似度)
参考示例程序及视频文件下载:
一.先决条件
1.两种检查相似度的方法
(1)PSNR:
psnr是“Peak Signal to Noise Ratio”的缩写,即峰值信噪比,是一种评价图像的客观标准,它具有局限性,一般是用于最大值信号和背景噪音之间的一个工程项目。
peak的中文意思是顶点。而ratio的意思是比率或比列的。整个意思就是到达噪音比率的顶点信号,psnr一般是用于最大值信号和背景噪音之间的一个工程项目。通常在经过影像压缩之后,输出的影像都会在某种程度与原始影像不同。为了衡量经过处理后的影像品质,我们通常会参考PSNR值来衡量某个处理程序能否令人满意。它是原图像与被处理图像之间的均方误差相对于(2n-1)2的对数值(信号最大值的平方,n是每个采样值的比特数),它的单位是dB。 MATLAB用法的公式如下:
PSNR=10*log10((2^n-1)^2/MSE)
其数学公式如下图所示:
其中,MSE是原图像与处理图像之间均方误差。
Peak就是指8bits表示法的最大值255。MSE指MeanSquareError,I(角标n)指原始影像第n个pixel值,P(角标n)指经处理后的影像第n个pixel值。PSNR的单位为dB。所以PSNR值越大,就代表失真越少。
(2)SSIM:
SSIM(structural similarity index),结构相似性,是一种衡量两幅图像相似度的指标。该指标首先由德州大学奥斯丁分校的图像和视频工程实验室(Laboratory for Image and Video Engineering)提出。SSIM使用的两张图像中,一张为未经压缩的无失真图像,另一张为失真后的图像。
**SSIM(structural similarity)**结构相似性,也是一种全参考的图像质量评价指标,它分别从亮度、对比度、结构三方面度量图像相似性。
其中ux、uy分别表示图像X和Y的均值,σX、σY分别表示图像X和Y的方差,σXY表示图像X和Y的协方差,即
C1、C2、C3为常数,为了避免分母为0的情况,通常取C1=(K1L)^2, C2=(K2L)^2, C3=C2/2, 一般地K1=0.01, K2=0.03, L=255. 则
SSIM取值范围[0,1],值越大,表示图像失真越小.
在实际应用中,可以利用滑动窗将图像分块,令分块总数为N,考虑到窗口形状对分块的影响,采用高斯加权计算每一窗口的均值、方差以及协方差,然后计算对应块的结构相似度SSIM,最后将平均值作为两图像的结构相似性度量,即平均结构相似性MSSIM:
参考博客:
http://www.cnblogs.com/vincent2012/archive/2012/10/13/2723152.html
https://baike.baidu.com/item/SSIM
https://baike.baidu.com/item/psnr/2925132?fr=aladdin
2.VideoCapture
Public Member Functions | |
---|---|
VideoCapture () | |
Default constructor. More… | |
VideoCapture (const String &filename) | |
Open video file or a capturing device or a IP video stream for video capturing. More… | |
VideoCapture (const String &filename, int apiPreference) | |
Open video file or a capturing device or a IP video stream for video capturing with API Preference. More… | |
VideoCapture (int index) | |
Open a camera for video capturing. More… | |
virtual | ~VideoCapture () |
Default destructor. More… |
上面是四种打开方式,还有一个析构函数
官方文档网址:
https://docs.opencv.org/3.4.0/d8/dfe/classcv_1_1VideoCapture.html
二.示例代码详解
1.主要的函数声明
double getPSNR ( const Mat& I1, const Mat& I2);//计算PSNR
这个是计算PSNR
,至于函数内部实现,参考先决条件中提到的内容以及官方文档中MSE做分母时为零的问题.
在考察压缩后的视频时,这个函数返回值大约在30到50之间,数字越大则表明压缩质量越好。如果图像差异很明显,就可能会得到15甚至更低的值。但是其呈现的差异值有时候和人的主观感受不成比例(就是当这个PSNR的返回值很小时可能肉眼看去相似度还是很高的),就需要用到下面的MSSIM。
ps:PSNR算法简单,检查的速度也很快
Scalar getMSSIM( const Mat& I1, const Mat& I2);//计算MSSIM
这个是计算MSSIM
,MSSIM为SSIM的均值.
注意:MSSIM
计算量比较大,所以比较两视频相似度时,先比较PSNR,如果PSNR < psnrTriggerValue
,PSNR无法很好比较,此时采用MSSIM比较
2.实现代码时的命令行参数
./<可执行文件名> <原视频名> <处理后视频名> <psnrTriggerValue(阈值)> <比较结束后窗口等待时间>
example:
./opencv_example Megamind.avi Megamind_bugy.avi 30 10
运行截图:
三.示例代码(附注释)
#include <iostream> // for standard I/O
#include <string> // for strings
#include <iomanip> // for controlling float print precision
#include <sstream> // string to number conversion
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2/imgproc.hpp> // Gaussian Blur
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp> // OpenCV window I/O
using namespace std