bgslibrary视频前景提取算法之帧差法

来源:互联网 发布:淘宝装修素材刚 编辑:程序博客网 时间:2024/04/30 06:52

BGSLibrary:A Background Subtraction Library
The BGSLibrary was developed by Andrews Sobral and provides an easy-to-use C++ framework based on OpenCV to perform background subtraction (BGS) in videos.
github介绍及下载地址 : https://github.com/andrewssobral/bgslibrary
现有30+种视频前景提取算法,不一定最优,但可以比较效果,准备研究其中部分。

第一次写,给出完整的头文件和main函数,以后仅给出要实现的算法
这次先实现 帧差法 (FrameDifferenceBGS) FrameDifference,总共4个文件
IBGS.h //IBGS是所有不同的视频前景提取算法的抽象类 ,我去掉其中saveConfig()和loadConfig()
FrameDifferenceBGS.h 帧差法
FrameDifferenceBGS.cpp
main.cpp //自己写的调用

文件名: IBGS.h

/*This file is part of BGSLibrary.BGSLibrary is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.BGSLibrary is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.*/#pragma once#include <opencv2/opencv.hpp>#include <opencv2/imgproc/imgproc_c.h>#include <opencv2/imgproc/types_c.h>#include <opencv2/highgui/highgui_c.h>class IBGS{public:    virtual void process(const cv::Mat &img_input, cv::Mat &img_foreground, cv::Mat &img_background) = 0;    /*virtual void process(const cv::Mat &img_input, cv::Mat &img_foreground){    process(img_input, img_foreground, cv::Mat());    }*/    virtual ~IBGS(){}private:    /*virtual void saveConfig() = 0;    virtual void loadConfig() = 0;*/};

参考demo后自己写的main函数
main.cpp

#include <iostream>#include "FrameDifferenceBGS.h"#include "IBGS.h"using namespace cv;using namespace std;#define resizedHeight       480     #define resizedWidth        600     #define VIDEOFILE    "1.mp4"#define frameTostart 20      //设置开始帧string inputPath = "E:\\2paperCode\\testVideo\\Crossroad\\229\\";int main(int argc, char* argv[]){    VideoCapture capture(inputPath + VIDEOFILE);    if (!capture.isOpened())    {        cerr << "No video input\n" << endl;        return -1;    }       IBGS *bgsFDiff;    bgsFDiff = new FrameDifferenceBGS();//使用帧差法    int pause = 0;    Mat img_input;    Mat img_input_resized(resizedHeight, resizedWidth, CV_8UC3);    capture.set(CAP_PROP_POS_FRAMES, frameTostart);     FrameDifferenceBGS fdiff;    while (!pause)    {        capture >> img_input;        if (img_input.empty())            break;        resize(img_input, img_input_resized, img_input_resized.size());        namedWindow("input", WINDOW_NORMAL);        imshow("input", img_input_resized);        Mat img_mask;        Mat img_bkgmodel;        bgsFDiff->process(img_input, img_mask, img_bkgmodel);         // by default, it shows automatically the foreground mask image        if (cvWaitKey(10) == 'q')            pause = !pause;    }    delete bgsFDiff;        cvDestroyAllWindows();        capture.release();    return 0;}

帧差法头文件,从 IBGS继承而来
FrameDifferenceBGS.h

#pragma once#include <iostream>#include <opencv2/opencv.hpp>#include "IBGS.h"class FrameDifferenceBGS : public IBGS{private:    bool firstTime;    cv::Mat img_input_prev;    cv::Mat img_foreground;    bool enableThreshold;    int threshold;    bool showOutput;public:    FrameDifferenceBGS();    ~FrameDifferenceBGS();    void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);//private://  void saveConfig();//  void loadConfig();};

FrameDifferenceBGS.cpp

#include "FrameDifferenceBGS.h"FrameDifferenceBGS::FrameDifferenceBGS() : firstTime(true), enableThreshold(true), threshold(15), showOutput(true){    std::cout << "FrameDifferenceBGS()" << std::endl;}FrameDifferenceBGS::~FrameDifferenceBGS(){    std::cout << "~FrameDifferenceBGS()" << std::endl;}void FrameDifferenceBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel){    if (img_input.empty())        return;    enableThreshold = true;    threshold = 15;    showOutput = true;    if (img_input_prev.empty())    {        img_input.copyTo(img_input_prev);//前一帧为空时,将当前帧复制给前一帧        return;    }    cv::absdiff(img_input_prev, img_input, img_foreground);    if (img_foreground.channels() == 3)        cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);    if (enableThreshold)        cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);    if (showOutput)    {        namedWindow("Frame Difference", cv::WINDOW_NORMAL);        cv::imshow("Frame Difference", img_foreground);    }    img_foreground.copyTo(img_output);    img_input.copyTo(img_input_prev);    firstTime = false;}

PS:尽量使用 OpenCV 内置函数. 调用LUT 函数可以获得最快的速度. 这是因为OpenCV库可以通过英特尔线程架构启用多线程,下面的opencv矩阵操作均是优化的多线程并行处理,较高效
具体参考:快速对图像的像素进行操作 opencv 实战

0 0
原创粉丝点击