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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/t247555529/article/details/53054101

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 modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along 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 实战

猜你喜欢

转载自blog.csdn.net/t247555529/article/details/53054101
今日推荐