【OpenCV】视频/图像背景减除方法

来源:互联网 发布:数据库镜像与备份 编辑:程序博客网 时间:2024/05/17 03:29

  背景减除法(Background subtraction)常用于通过静态摄像头生成一个前景掩码,即场景中移动物体的二进制图像。


代码示例

#include "opencv2/imgcodecs.hpp"#include "opencv2/imgproc.hpp"#include "opencv2/highgui.hpp"#include "opencv2/videoio.hpp"#include "opencv2/video.hpp"#include <iostream>#include <sstream>using namespace std;using namespace cv;Mat frame;                              // 当前帧Mat fgMaskMOG2;                         // 前景模板,通过MOG2方法生成Ptr<BackgroundSubtractor> pMOG2;        // MOG2 背景消除char keyboard;                          // 按键响应const char* filename;void processVideo(const char* videoFilename);void processImages(const char* firstFrameFilename);int main(){    pMOG2 = createBackgroundSubtractorMOG2();                      // MOG2方法,背景消除    char video_or_image;    string s;    cout << "Pless choose Video or Image: ( V / I )\t";    cin >> video_or_image ;    if (video_or_image == 'V' || video_or_image == 'v')             // 视频    {        cout << "\n\nPlease input the address of the video:\t";        cin >> s;        filename = s.c_str();        namedWindow("Frame");        namedWindow("FG Mask MOG2");        processVideo(filename);    }    else if (video_or_image == 'I' || video_or_image == 'i')        // 图像    {        cout << "\n\nPlease input the address of the images:\t";        cin >> s;        filename = s.c_str();        namedWindow("Frame");        namedWindow("FG Mask MOG2");        processImages(filename);    }    else    {        cerr << "Wrong Input !" << endl;        return EXIT_FAILURE;    }    destroyAllWindows();    return EXIT_SUCCESS;}void processVideo(const char* videoFilename){    VideoCapture capture(videoFilename);                            // 捕获视频    if (!capture.isOpened()) { exit(EXIT_FAILURE); }    keyboard = 0;    while (keyboard != 'q'&&keyboard != 27)    {        if (!capture.read(frame)) { exit(EXIT_FAILURE); }           // 读取当前帧        pMOG2->apply(frame, fgMaskMOG2);                            // 获取前景掩模        stringstream ss;        ss << capture.get(CAP_PROP_POS_FRAMES);                     // 获取当前帧数        string frameNumberString = ss.str();        rectangle(frame, cv::Point(10, 2), cv::Point(100, 20), cv::Scalar(255, 255, 255), -1);        putText(frame, frameNumberString.c_str(), cv::Point(15, 15),            FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));        imshow("Frame", frame);        imshow("FG Mask MOG2", fgMaskMOG2);        keyboard = (char)waitKey(30);    }    capture.release();}void processImages(const char* fistFrameFilename) {    frame = imread(fistFrameFilename);    if (frame.empty()) { exit(EXIT_FAILURE); }    string fn(fistFrameFilename);    keyboard = 0;    while (keyboard != 'q' && keyboard != 27)     {        pMOG2->apply(frame, fgMaskMOG2);                    // 获取前景掩模        size_t index = fn.find_last_of("/");        if (index == string::npos)                          // 如果'/'不存在则搜寻'\\'            index = fn.find_last_of("\\");        size_t index2 = fn.find_last_of(".");        string prefix = fn.substr(0, index + 1);            // 图像路径前部分,前为起始位置,后为长度        string suffix = fn.substr(index2);                  // 图像路径后部分,图像格式        string frameNumberString = fn.substr(index + 1, index2 - index - 1);        istringstream iss(frameNumberString);        int frameNumber = 0;        iss >> frameNumber;        rectangle(frame, cv::Point(10, 2), cv::Point(100, 20),            cv::Scalar(255, 255, 255), -1);        putText(frame, frameNumberString.c_str(), cv::Point(15, 15),            FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));        imshow("Frame", frame);        imshow("FG Mask MOG 2", fgMaskMOG2);        keyboard = (char)waitKey(30);        ostringstream oss;        oss << (frameNumber + 1);        string nextFrameNumberString = oss.str();        string nextFrameFilename = prefix + nextFrameNumberString + suffix;        frame = imread(nextFrameFilename);        if (frame.empty())             exit(EXIT_FAILURE);        fn.assign(nextFrameFilename);                       // 更新图片路径    }}

运行结果

原创粉丝点击