这是(II)中的Mat版本,特别注意一下accumulateWeighted这个函数的用法。
我将官方文档中的函数说明贴出来:
Updates a running average.
Parameters: |
|
---|
The function calculates the weighted sum of the input image src and the accumulator dst so that dst becomes a running average of a frame sequence:
That is, alpha regulates the update speed (how fast the accumulator “forgets” about earlier images). The function supports multi-channel images. Each channel is processed independently.
See also
accumulate(), accumulateSquare(), accumulateProduct()
代码:
//opencv2.0风格的视频前景提取 #include "cv.h" #include "highgui.h" #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <iostream> #include <cstdio> using namespace std; using namespace cv; int main() { Mat frame, frame_copy,img1,output,gray,frame_copy_8U; double learningRate = 0.01; // 控制背景累积学习的速率 char* input_name = "001.avi"; //从视频读入 VideoCapture capture(input_name); cvNamedWindow( "result", 1 ); if(capture.isOpened()/*capture*/) // 摄像头读取文件开关 { //对每一帧做处理 for(;;) { //frame = cvQueryFrame( capture ); // 摄像头读取文件开关 capture >> frame; if(!frame.empty()) { cvtColor(frame, gray, CV_BGR2GRAY); //进行处理 if (frame_copy.empty()) { //记录第一帧 gray.convertTo(frame_copy, CV_32F); } frame_copy.convertTo(frame_copy_8U, CV_8U); //做差分 absdiff(frame_copy_8U, gray, img1); // 对得到的前景进行阈值选取,去掉伪前景 threshold(img1, output, 30, 255, THRESH_BINARY_INV); accumulateWeighted(gray, frame_copy,0.01,output); imshow("src", frame); imshow("result", output); } else { printf(" --(!) No captured frame -- Break!"); break; } //10ms中按任意键进入此if块 if( cvWaitKey( 10 ) >= 0 ) break; } } return 0; }
更好版本(II):
//opencv2.0风格的视频前景提取 #include "cv.h" #include "highgui.h" #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <iostream> #include <cstdio> using namespace std; using namespace cv; int main() { Mat frame, frame_copy,img1,output,gray,frame_copy_8U; double learningRate; // 控制背景累积学习的速率 int nThreshold; //二值化阈值 char* input_name = "001.avi"; //从视频读入 VideoCapture capture(input_name); cvNamedWindow( "result", 1 ); if(capture.isOpened()/*capture*/) // 摄像头读取文件开关 { //对每一帧做处理 for(;;) { //frame = cvQueryFrame( capture ); // 摄像头读取文件开关 capture >> frame; if(!frame.empty()) { cvtColor(frame, gray, CV_BGR2GRAY); //进行处理 if (frame_copy.empty()) { //记录第一帧 gray.convertTo(frame_copy, CV_32F); } frame_copy.convertTo(frame_copy_8U, CV_8U); //做差分 absdiff(frame_copy_8U, gray, img1); // 对得到的前景进行阈值选取,去掉伪前景 nThreshold=30; threshold(img1, output, nThreshold, 255, THRESH_BINARY_INV); learningRate = 0.01; accumulateWeighted(gray, frame_copy,learningRate,output); imshow("src", frame); imshow("result", output); } else { printf(" --(!) No captured frame -- Break!"); break; } //10ms中按任意键进入此if块 if( cvWaitKey( 10 ) >= 0 ) break; } } return 0; }