C++调用opencv提取视频关键帧

用的灰度帧差法

编译平台:VS2017  x64

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

//#include "Timer.h"

//CV_BGR2GRAY未声明的标识符的解决办法
#include 

using namespace std;
using namespace cv;

#define Threshold_Value 0.75

#define VideoPath "test.flv"

int extractKeyFrame()
{
	long currentFrame = 1;
	float p;
	VideoCapture cap;
	//这里放置需要提取关键字的视频
	cap.open(VideoPath);

	if (!cap.isOpened())//如果视频不能正常打开则返回
	{
		cout << "cannot open video!" << endl;
		return 0;
	}
	Mat frame_key;
	bool b = cap.read(frame_key);

	if (frame_key.empty())
		cout << "frame_key is empty!" << endl;

	stringstream str;
	str << "./keyframes/" << currentFrame << ".jpg";
	cout << str.str() << endl;
	b = imwrite(str.str(), frame_key);
	Mat frame;
	Mat previousImage, currentImage, resultImage;


	//Timer t;
	while (1)
	{
		Mat frame;
		cap >> frame;
		if (frame.empty())
		{
			cout << "frame is empty!" << endl;
			break;
		}

		Mat srcImage_base, hsvImage_base;
		Mat srcImage_test1, hsvImage_test1;
		srcImage_base = frame_key;
		srcImage_test1 = frame;
		//将图像从BGR色彩空间转换到 HSV色彩空间
		cvtColor(srcImage_base, previousImage, CV_BGR2GRAY);
		cvtColor(srcImage_test1, currentImage, CV_BGR2GRAY);
		absdiff(currentImage, previousImage, resultImage);  //帧差法,相减
		threshold(resultImage, resultImage, 10, 255.0, CV_THRESH_BINARY); //二值化,像素值相差大于20则置为255,其余为0
		float counter = 0;
		float num = 0;
		// 统计两帧相减后图像素
		for (int i = 0; i < resultImage.rows; i++)
		{
			uchar* data = resultImage.ptr(i); //获取每一行的指针
			for (int j = 0; j < resultImage.cols; j++)
			{
				num = num + 1;
				if (data[j] == 255) //访问到像素值
				{
					counter = counter + 1;
				}
			}
		}
		p = counter / num;
		// counter  num  p 分别为  有变化的像素点数  总像素点数目  比例
		//printf(">>>>>>counter>>>>num>>>>p: %f  %f  %f  \n", counter, num, p);
		if (p > Threshold_Value) //达到阈值的像素数达到一定的数量则保存该图像
		{
			//cout << ">>>>>>>>>>>>>>>>>>>>.>>>>>>>.this frame is keyframe!" << endl;
			frame_key = frame;

			++currentFrame;
			//cout << "正在写第" << currentFrame << "帧" << endl;
			stringstream str;
			//写视频保存目录,我的是  ./keyframes/xx.jpg  xx为当前帧的序号
			str << "./keyframes/" << currentFrame << ".jpg";
			b = imwrite(str.str(), frame_key);
		}
		else
		{
		}

	}
	//cout << "duration: " << t.stop_delta() << "ms" << endl;
	return 0;
}

 

你可能感兴趣的:(opencv)