首页 > 代码库 > OpenCV Tutorials —— Video Input with OpenCV and similarity measurement
OpenCV Tutorials —— Video Input with OpenCV and similarity measurement
OpenCV 的视频操作都与 VideoCapture 相关
If this argument is an integer then you will bind the class to a camera, a device. The number passed here is the ID of the device, assigned by the operating system.
If you have a single camera attached to your system its ID will probably be zero and further ones increasing from there.
If the parameter passed to these is a string it will refer to a video file, and the string points to the location and name of the file.
1,通过构造函数或者 open 来打开视频流
2,通过 isOpen 判断是否打开成功
3,通过 >> 将frame信息读入Mat 中
4,empty 来检测是否完结
5,获取视频其他信息,用get
Size refS = Size((int) captRefrnc.get(CV_CAP_PROP_FRAME_WIDTH), (int) captRefrnc.get(CV_CAP_PROP_FRAME_HEIGHT)),cout << "Reference frame resolution: Width=" << refS.width << " Height=" << refS.height << " of nr#: " << captRefrnc.get(CV_CAP_PROP_FRAME_COUNT) << endl;set 设置信息:
captRefrnc.set(CV_CAP_PROP_POS_MSEC, 1.2); // go to the 1.2 second in the videocaptRefrnc.set(CV_CAP_PROP_POS_FRAMES, 10); // go to the 10th frame of the video
Image similarity - PSNR and SSIM
PSNR (aka Peak signal-to-noise ratio). The simplest definition of this starts out from the mean squad error. Let there be two images: I1 and I2; with a two dimensional size i and j, composed of c number of channels.
Then the PSNR is expressed as:
Here the is the maximum valid value for a pixel.
其中两像素相减会发生除数为零的情况,需要在程序中区分对待
程序的目的是比较原始视频和压缩视频每帧图像的相似度(信息损失度)
Code
#include "stdafx.h"#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/imgproc/imgproc.hpp> // Gaussian Blur#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)#include <opencv2/highgui/highgui.hpp> // OpenCV window I/Ousing namespace std;using namespace cv;double getPSNR ( const Mat& I1, const Mat& I2);Scalar getMSSIM( const Mat& I1, const Mat& I2);void help(){ cout << "\n--------------------------------------------------------------------------" << endl << "This program shows how to read a video file with OpenCV. In addition, it tests the" << " similarity of two input videos first with PSNR, and for the frames below a PSNR " << endl << "trigger value, also with MSSIM."<< endl << "Usage:" << endl << "./video-source referenceVideo useCaseTestVideo PSNR_Trigger_Value Wait_Between_Frames " << endl << "--------------------------------------------------------------------------" << endl << endl;}int main(int argc, char *argv[], char *window_name){ help(); /* if (argc != 5) { cout << "Not enough parameters" << endl; return -1; }*/ stringstream conv; const string sourceReference = "video/Megamind.avi",sourceCompareWith = "video/Megamind_bug.avi"; int psnrTriggerValue, delay; conv << "35" << endl << "10"; // put in the strings conv >> psnrTriggerValue >> delay;// take out the numbers char c; int frameNum = -1; // Frame counter VideoCapture captRefrnc(sourceReference), // 通过构造函数打开视频流 captUndTst(sourceCompareWith); if ( !captRefrnc.isOpened()) { cout << "Could not open reference " << sourceReference << endl; return -1; } if( !captUndTst.isOpened()) { cout << "Could not open case test " << sourceCompareWith << endl; return -1; } Size refS = Size((int) captRefrnc.get(CV_CAP_PROP_FRAME_WIDTH), (int) captRefrnc.get(CV_CAP_PROP_FRAME_HEIGHT)), uTSi = Size((int) captUndTst.get(CV_CAP_PROP_FRAME_WIDTH), (int) captUndTst.get(CV_CAP_PROP_FRAME_HEIGHT)); if (refS != uTSi) { cout << "Inputs have different size!!! Closing." << endl; return -1; } const char* WIN_UT = "Under Test"; const char* WIN_RF = "Reference"; // Windows namedWindow(WIN_RF, CV_WINDOW_AUTOSIZE ); namedWindow(WIN_UT, CV_WINDOW_AUTOSIZE ); cvMoveWindow(WIN_RF, 400 , 0); //750, 2 (bernat =0) cvMoveWindow(WIN_UT, refS.width, 0); //1500, 2 cout << "Reference frame resolution: Width=" << refS.width << " Height=" << refS.height << " of nr#: " << captRefrnc.get(CV_CAP_PROP_FRAME_COUNT) << endl; cout << "PSNR trigger value " << setiosflags(ios::fixed) << setprecision(3) << psnrTriggerValue << endl; Mat frameReference, frameUnderTest; double psnrV; Scalar mssimV; while( true) //Show the image captured in the window and repeat { captRefrnc >> frameReference; captUndTst >> frameUnderTest; if( frameReference.empty() || frameUnderTest.empty()) { cout << " < < < Game over! > > > "; break; } ++frameNum; cout <<"Frame:" << frameNum <<"# "; ///////////////////////////////// PSNR //////////////////////////////////////////////////// psnrV = getPSNR(frameReference,frameUnderTest); //get PSNR cout << setiosflags(ios::fixed) << setprecision(3) << psnrV << "dB"; //////////////////////////////////// MSSIM ///////////////////////////////////////////////// if (psnrV < psnrTriggerValue && psnrV) { mssimV = getMSSIM(frameReference,frameUnderTest); cout << " MSSIM: " << " R " << setiosflags(ios::fixed) << setprecision(2) << mssimV.val[2] * 100 << "%" << " G " << setiosflags(ios::fixed) << setprecision(2) << mssimV.val[1] * 100 << "%" << " B " << setiosflags(ios::fixed) << setprecision(2) << mssimV.val[0] * 100 << "%"; } cout << endl; ////////////////////////////////// Show Image ///////////////////////////////////////////// imshow( WIN_RF, frameReference); imshow( WIN_UT, frameUnderTest); c = cvWaitKey(delay); if (c == 27) break; } return 0;}double getPSNR(const Mat& I1, const Mat& I2){ Mat s1; absdiff(I1, I2, s1); // |I1 - I2| s1.convertTo(s1, CV_32F); // cannot make a square on 8 bits s1 = s1.mul(s1); // |I1 - I2|^2 Scalar s = sum(s1); // sum elements per channel double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels if( sse <= 1e-10) // for small values return zero return 0; else { double mse =sse /(double)(I1.channels() * I1.total()); double psnr = 10.0*log10((255*255)/mse); return psnr; }}Scalar getMSSIM( const Mat& i1, const Mat& i2){ const double C1 = 6.5025, C2 = 58.5225; /***************************** INITS **********************************/ int d = CV_32F; Mat I1, I2; i1.convertTo(I1, d); // cannot calculate on one byte large values i2.convertTo(I2, d); Mat I2_2 = I2.mul(I2); // I2^2 Mat I1_2 = I1.mul(I1); // I1^2 Mat I1_I2 = I1.mul(I2); // I1 * I2 /*************************** END INITS **********************************/ Mat mu1, mu2; // PRELIMINARY COMPUTING GaussianBlur(I1, mu1, Size(11, 11), 1.5); GaussianBlur(I2, mu2, Size(11, 11), 1.5); Mat mu1_2 = mu1.mul(mu1); Mat mu2_2 = mu2.mul(mu2); Mat mu1_mu2 = mu1.mul(mu2); Mat sigma1_2, sigma2_2, sigma12; GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5); sigma1_2 -= mu1_2; GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5); sigma2_2 -= mu2_2; GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5); sigma12 -= mu1_mu2; ///////////////////////////////// FORMULA //////////////////////////////// Mat t1, t2, t3; t1 = 2 * mu1_mu2 + C1; t2 = 2 * sigma12 + C2; t3 = t1.mul(t2); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2)) t1 = mu1_2 + mu2_2 + C1; t2 = sigma1_2 + sigma2_2 + C2; t1 = t1.mul(t2); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2)) Mat ssim_map; divide(t3, t1, ssim_map); // ssim_map = t3./t1; Scalar mssim = mean( ssim_map ); // mssim = average of ssim map return mssim;}
OpenCV Tutorials —— Video Input with OpenCV and similarity measurement