基于帧间差分法的前景提取的实现(C++)

一种最简单的前景(移动区域)提取方怯就是一帧(或之后的几帧)减去另 一帧,然后将“足够不同”的地方标为前景。这个过程会捕捉到移动物体的边缘。简单起见,我们考虑三个单通道图片frameTime1,frameTime2和frameForeground 。图片frameTime1是过去的一张灰度图片,frameTime2是当前的灰度图片。我们用下面的接口来检测前景,将差分的值(绝对值)保存在frameForeground 中。

cv::absdiff(

frameTime1, // First input array

frameTime2, // Second input array

frameForeground // Result array

);

由于像素总是存在噪音和波动,我们应该忽略帧间微小的不同(例如小于20),并标记出(设为 255)大的不同。调用阈值化处理函数达到这一目的。

C++实现代码:

// 帧间差分法
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

using namespace std;

int N = 4; //N帧的帧间差分

int main()
{
	using namespace cv;

	cv::VideoCapture cap;
	if (!cap.open("test.avi"))
	{
		cerr << "Couldn't open video file" << endl;
		return -1;
	}

	vector<Mat> frames;
	for (int i = 1; ; i++)
	{
		Mat frame, frame_gray;
		cap >> frame;
		if( !frame.data ) break;
		if (i > 10 && i <= 10 + N)
		{
			cvtColor(frame, frame_gray, CV_RGB2GRAY); // 将彩色图像转换为灰度图像;
			frames.push_back(frame_gray);
		}
	}

	int row = frames[0].rows;
	int col = frames[0].cols;

	vector<Mat> alldiff(N-1, Mat(row, col, CV_8UC1)); // 生成一个Mat容器alldiff用于存储最终的各个帧的差分结果        

	for (int i = 0; i < N - 1; i++)
	{
		Mat diff = Mat(row, col, CV_8UC1);
		absdiff(frames[i], frames[i+1], diff); //帧间差分
		threshold(diff, diff, 20, 255, CV_8UC1); //阈值化处理
		alldiff.push_back(~diff);
		string n = to_string(i);
		string name = "diff_" + n + ".jpg";
		imwrite(name, ~diff);
	}

	waitKey(0);

	return 0;
}

 原视频:

帧间差分结果:

frame11-frame10
frame12-frame11
frame13-frame12

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值