码迷,mamicode.com
首页 > 其他好文 > 详细

OpenCV Tutorials —— Video Input with OpenCV and similarity measurement

时间:2014-11-24 18:31:39      阅读:353      评论:0      收藏:0      [点我收藏+]

标签:style   http   io   ar   color   os   sp   for   strong   

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 video
captRefrnc.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.

bubuko.com,布布扣

Then the PSNR is expressed as:

bubuko.com,布布扣

Here the bubuko.com,布布扣 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/O

using 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

标签:style   http   io   ar   color   os   sp   for   strong   

原文地址:http://www.cnblogs.com/sprint1989/p/4118996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!