1. 程式人生 > >OpenCV 從視訊中獲取背景

OpenCV 從視訊中獲取背景

本例是從一段視訊中,獲取背景,去掉前景物體。思路是,N幀疊加再取平均值,只要N足夠,即可以消除前景物體。

#include <iostream>  
#include "opencv2/opencv.hpp"  
#include "opencv2/nonfree/features2d.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;
using namespace std;

void OverlayMat(Mat& src, unsigned int iBgk[240][960])
{
	int nRows = 240;
	int nCols = 320 * 3;
	for (int i = 0; i < nRows; ++i)
	{
		uchar* p = src.ptr<uchar>(i);
		for (int j = 0; j < nCols; ++j)
		{
			iBgk[i][j] += p[j];
		}
	}
}

int main(int argi, char** argv)
{
	printf("start!\n");
	VideoCapture cap;
	cap.open(argv[1]);

	if (!cap.isOpened())
	{
		printf("open file fail!\n");
		return -1;
	}
	printf("open file success!\n");
	Mat prevgray, gray, flow, cflow, frame;
	Mat bkg(240, 320, CV_8UC3);
	unsigned int iBkg[240][960] = { 0 };
	
	namedWindow("背景", 1);

	int total = 0;
	int temp = 0;
	for (;;)
	{
		double t = (double)cvGetTickCount();

		if (!cap.read(frame))
			break;
		

		OverlayMat(frame, iBkg);
		total++;
		imshow("原始", frame);
		if (waitKey(10) >= 0)
			break;
		
	}
	
	cout << "total frames:" << total << endl;
	cap.release();
	int ch = 3;
	int nRows = 240;
	int nCols = 320 * ch;
	uchar* p;
	for (int i = 0; i < nRows; ++i)
	{
		p = bkg.ptr<uchar>(i);
		for (int j = 0; j < nCols; ++j)
		{
			p[j] = iBkg[i][j] / total;
		}
	}


	imshow("背景", bkg);
	if (waitKey(0) >= 0)
		return 0;
	return 0;
}