opencv中BackgroundSubtractorMOG问题及解决方法

以前写了一片博文,最近有人给我反应,在opencv中出现BackgroundSubtractorMOG未定义问题,我这里简单说明一下这个问题。

通过对opencv文档查询可以发现如下:
opencv中BackgroundSubtractorMOG问题及解决方法_第1张图片
这里我们可以清楚看到BackgroundSubtractorMOG所在的命名空间中,由于我这篇博文使用的是BackgroundSubtractorMOG2,而BackgroundSubtractorMOG2就在cv命名空间中,所以可以正常使用。对于使用BackgroundSubtractorMOG,这个函数在cv::bgsegm中,如果你没有正确导入头文件,就会出现未定义问题。

如果你想正确使用BackgroundSubtractorMOG这个函数,你应该在头文件中引入

#include "bgsegm.hpp"

这个头文件。但是如果你导入上面的头文件时,你还会发现仍然不能使用,原因在于以下
opencv中BackgroundSubtractorMOG问题及解决方法_第2张图片
opencv_contrib这是opencv一个额外的部分,这部分是收费或者不稳定的算法,如果你想使用可以自己单独编译opencv,编译过程网上有很多教程,这里就不在赘述。我相信大家参考教程是可以编译成功的。
如果你变异opencv成功,下面的具体使用和BackgroundSubtractorMOG2基本相同,如下:

Ptr<cv::bgsegm::BackgroundSubtractorMOG> fgbg =  cv::bgsegm::createBackgroundSubtractorMOG();

完整代码
VideoDetect.h

#pragma once
#include 
#include 
#include "bgsegm.hpp"

using namespace std;
using namespace cv;
enum VIDEOTYPE
{
    CAMERAVIDEO/*摄像头*/,FILEVIDEO/*视频*/
};

class MOG2Detector
{
public:
    MOG2Detector();
    ~MOG2Detector();
    /*
    VIDEOTYPE 指定摄像头或者文件
    path 文件路径
    WindowName opencv可视化窗口名称
    */
    MOG2Detector(VIDEOTYPE type,char * path = "E:/image/s.avi",char * WindowName = "Video");
    //开始
    void startDecect();

private:
    char * WinName;
    VIDEOTYPE VideoType;
    cv::VideoCapture capture;
    cv::Ptr fgbg;
};

VideoDetect.cpp:

#include "stdafx.h"
#include "MOG2Detector.h"


MOG2Detector::MOG2Detector()
{
}
MOG2Detector::~MOG2Detector()
{

}

MOG2Detector::MOG2Detector(VIDEOTYPE type, char * path, char * WindowName)
{
    if (type == CAMERAVIDEO) 
    {
        capture.open(0);
    }
    else if (type == FILEVIDEO)
    {
        capture.open("E:/image/s.avi");
    }
    else 
    {
        cout << "Type is error, you can input CAMERAVIDEO or FILEVIDEO" << endl;
        return;
    }

    if (!capture.isOpened())
    {
        std::cout << "video camera capture open fail! \n" << std::endl;
        exit(1);
    }

    fgbg = cv::createBackgroundSubtractorMOG();
    WinName = WindowName;
}

void MOG2Detector::startDecect()
{
    cv::Mat frame, fgmask;
    //cnts存储边缘信息
    std::vector<std::vector > cnts;
    cv::namedWindow("video", 1);

    while (1)
    {
        capture.read(frame);
        fgbg->apply(frame, fgmask);
        //检测每一帧边缘
        findContours(fgmask, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
        float Area;
        Rect rect;
        vector m;
        for (int i = cnts.size() - 1; i >= 0; i--)
        {
            vector c = cnts[i];
            //获取面积
            Area = contourArea(c);
            if (Area < 50)//50这个值根据需求设定,这里指的是目标的大小
            {
                continue;
            }
            else
            {
                m = c;
            }
            rect = boundingRect(m);
            rectangle(frame, rect, Scalar(0, 255, 0), 2);
        }
        resize(frame, frame, Size(480, 320));
        imshow("video", frame);
        char c = waitKey(33);
        if (c == 27)
            break;
    }
    //释放资源
    capture.release();
    cv::destroyWindow("video");
}

原创博文,转载请标明出处,谢谢!!

你可能感兴趣的:(计算机视觉)