1. 程式人生 > >Opencv 自帶提取前景(背景建模)

Opencv 自帶提取前景(背景建模)

官方教程原始碼稍加修改:

讀入視訊(圖片序列)->bei

//opencv
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
//C
#include <stdio.h>
//C++
#include <iostream>
#include <sstream>
using namespace cv;
using namespace std;
// Global variables
Mat frame; //current frame
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor
int keyboard; //input from keyboard
void help();
void processVideo(char* videoFilename);
void processImages(char* firstFrameFilename);

int main(int argc, char* argv[])
{
    //print help information
    //help();
    //check for the input parameter correctness
	/*
    if(argc != 3) {
        cerr <<"Incorret input list" << endl;
        cerr <<"exiting..." << endl;
        return EXIT_FAILURE;
    }
	*/
    //create GUI windows
    namedWindow("Frame");
    namedWindow("FG Mask MOG 2");
    //create Background Subtractor objects
    pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
	
    processVideo("測試視訊.avi");
	
    //destroy GUI windows
    destroyAllWindows();
    return EXIT_SUCCESS;
}
void processVideo(char* videoFilename) {
    //create the capture object
    VideoCapture capture(videoFilename);
    if(!capture.isOpened()){
        //error in opening the video input
        cerr << "Unable to open video file: " << videoFilename << endl;
        exit(EXIT_FAILURE);
    }
    //read input data. ESC or 'q' for quitting
    while( (char)keyboard != 'q' && (char)keyboard != 27 ){
        //read the current frame
        if(!capture.read(frame)) {
            cerr << "Unable to read next frame." << endl;
            cerr << "Exiting..." << endl;
            exit(EXIT_FAILURE);
        }
        //update the background model
        pMOG2->apply(frame, fgMaskMOG2);
        //get the frame number and write it on the current frame
        stringstream ss;
        rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
                  cv::Scalar(255,255,255), -1);//繪製方塊


        ss << capture.get(CAP_PROP_POS_FRAMES);
        string frameNumberString = ss.str();
        putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
                FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));//方塊中寫入幀數



        //show the current frame and the fg masks
        imshow("Frame", frame);
		//medianBlur(fgMaskMOG2, fgMaskMOG2, 9);//中值濾波160309
		//erode(fgMaskMOG2, fgMaskMOG2, NULL);
		//dilate(fgMaskMOG2, fgMaskMOG2,NULL);
		imshow("FG Mask MOG 2", fgMaskMOG2);
		if ((char)keyboard != 's')
		{
			imwrite("src.jpg", frame);
			IplImage imgTmp = fgMaskMOG2;
			IplImage *fgMaskMOG2_ip = cvCloneImage(&imgTmp);
			cvSaveImage("dst.jpg", fgMaskMOG2_ip);
			cvReleaseImage(&fgMaskMOG2_ip);
		}
        //get the input from the keyboard
        keyboard = waitKey( 30 );
    }
    //delete capture object
    capture.release();
}


說明:

1.pMOG2->apply(frame, fgMaskMOG2);

apply可以新增第三個引數:Every frame is used both for calculating the foreground mask and for updating the background. If you want to change the learning rate used for updating the background model, it is possible to set a specific learning rate by passing a third parameter to the 'apply' method.

learningRate The value between 0 and 1 that indicates how fast the background model is  learnt. Negative parameter value makes the algorithm to use some automatically chosen learning   rate. 0 means that the background model is not updated at all, 1 means that the background model   is completely reinitialized from the last frame.

  CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate=-1) = 0;

2.我用的720的監控視訊,速度有些慢,如果對沒幀進行縮小可能會好些。

效果:視訊中某幀



~~程式碼可執行,有問題留言~~