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

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/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;
}
时间: 2024-08-04 15:09:03

OpenCV Tutorials —— Video Input with OpenCV and similarity measurement的相关文章

OpenCV Tutorials &mdash;&mdash; Camera calibration With OpenCV

获取摄像机参数是为了来处理图像失真或者实现图像度量 ~~ Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determine

OpenCV Tutorials &mdash;&mdash; File Input and Output using XML and YAML files

They are two kinds of data structures you may serialize: mappings(like the STL map) and element sequence (like the STL vector>. The difference between these is that in a map every element has a unique name through what you may access it. For sequence

OpenCV Tutorials &mdash;&mdash; Creating a video with OpenCV

写video 需要用到 VideoWriter  视频文件可看作一个容器 视频的类型由视频文件的后缀名来指定   Due to this OpenCV for video containers supports only the avi extension, its first version. A direct limitation of this is that you cannot save a video file larger than 2 GB. Furthermore you ca

学习opencv tutorials

1.opencv里头动态库和静态库的区别 lib是动态库,staticlib是静态库. 这是opencv tutorials中对动态库和静态库的说明.动态库是在runtime时候才load的库文件.而静态库文件会在你build的时候build-in inside your exe file.优点是可以避免误删,缺点是应用程序变大,加载时间也会变长. 2.  Visual Studio中solution和project的关系 在VS中,一个solution中可以包含多个project. 3.  两

opencv第一站:配置opencv环境(2015-12-12)

今天论坛申请的书< OpenCV 计算机视觉编程攻略(中国工信出版社)>到了,准备研究研究机器视觉. 晚上安装了 vc2008 及 opencv 最新版 3.0.0,试了各种配置都是错误提示“error LNK2019: unresolved external symbol”,最后怀疑到版本上了,下载了 2.3.1 版本试了正常运行,真是折腾死了,想着要学就学最新版本嘛,竟然会遇到如此麻烦真是始料不及,不过也算是熟悉了一下配置.以后要多个心眼了,不是版本越高越好,还得开发环境支持才是. 按照官

【OpenCV入门教程之一】 OpenCV 2.4.8 +VS2010的开发环境配置

目录(?)[-] 因为读研期间的研究方向是图像处理所以浅墨这段时间闭门研究了很多OpenCV和图像处理相关的知识与内容眼看自己积累到一定的程度了于是决定开始开设这个OpenCV系列专栏总结自己所学也分享知识给大家 还是先放出待会儿的测试用图 下载和安装OpenCV SDK sources里面是源代码想查看完整的源代码需要用cmake来解包如何解包大家百度一下就可以或者下次浅墨来专门讲一讲这里就先不多说了 配置环境变量 工程包含include目录的配置 工程库lib目录的配置 链接库的配置 在Wi

(转) 安装OpenCV:OpenCV 2.4.8或OpenCV 2.4.9 +VS 开发环境配置

因为读研期间的研究方向是图像处理,所以浅墨这段时间闭门研究了很多OpenCV和图像处理相关的知识与内容.眼看自己积累到一定的程度了,于是决定开始开设这个OpenCV系列专栏,总结自己所学,也分享知识给大家. 好了,这篇文章作为OpenCV的启程篇,自然少不了先系统地介绍OpenCV开发环境的配置. 浅墨前后经历过OpenCV 2.4.6,OpenCV 2.4.7,OpenCV 2.4.8这三个版本的配置,有时候还要涉及到三个版本之间的转换,所以还是对OpenCV的配置有一定的理解的,希望自己的一

【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置

本系列文章由@浅墨_毛星云 出品.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/19809337 1.下载和安装OpenCV SDK VS2010不用说,肯定都安装了吧.来说说当前最新的OpenCV版本2.4.8(2014年2月24日),2.4.9 (2014年4月)的下载和安装.与其说是安装,不如叫解压更加合适,因为我们下载的exe安装文件就是一个自解压程序而已. 在官网:http://opencv.org/上找到OpenCV

安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/19809337 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 知乎:http://www.zhihu.com/people/mao-xing-yun 写作当前博文时配套使用的OpenCV版本: 2.4.8.2.4.9.3.0   ( 2014