OpenCV之BackgroundSubtractorMOG2动态目标检测


// OpenCV3 与 OpenCV2 一些区别 ...
Ptr<BackgroundSubtractor> bg_model = createBackgroundSubtractorMOG2();
bg_model->apply(img, fgmask);

// ------------------------------------ //
//  params.minThreshold = 20;//二值化的起始阈值
//  params.maxThreshold = 180;//二值化的终止阈值
//  params.thresholdStep = 10;//二值化的阈值步长
//  params.minConvexity = 0.5f;//斑点的最小凸度 默认0.95f
//  params.minInertiaRatio = 0.03f;//斑点的最小惯性率 默认0.1f
//  params.minArea = 120;//斑点的最小面积
//  params.maxArea = 5000;//斑点的最大面积
//  params.blobColor = 255;//检测白色
//  重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点
//  params.minRepeatability = 2;
//  最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点
//  params.minDistBetweenBlobs = 10;
// ------------------------------------ //

// OpenCV2使用BackgroundSubtractorMOG2动态目标检测
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
    // --------------------------------------------------
    namedWindow("image", WINDOW_AUTOSIZE);
    namedWindow("foreground", WINDOW_AUTOSIZE);
    namedWindow("background", WINDOW_AUTOSIZE);
    // --------------------------------------------------
    VideoCapture m_cap("/home/danoo/xxx.avi");
    // --------------------------------------------------
    BackgroundSubtractorMOG2 m_mog;
    SimpleBlobDetector::Params m_params;
    m_params.filterByArea = true;
    m_params.minArea = 1;
    m_params.blobColor = 255;
    SimpleBlobDetector m_detector(m_params);
    Ptr<SimpleBlobDetector> m_blob = m_detector.create("SimpleBlob");
    // --------------------------------------------------
    Mat frame;
    Mat foreground;
    // Mat background;
    while(m_cap.read(frame))
    {
    // 运动前景检测
    m_mog(frame, foreground, 0.001);
    // 腐蚀
    cv::erode(foreground, foreground, cv::Mat());
    // 膨胀
    cv::dilate(foreground, foreground, cv::Mat());
    // 返回当前背景图像
    // m_mog.getBackgroundImage(background);
    // -------------------------------------------------------------- //
    // 特征点检测
    vector<KeyPoint> key_points;
    m_blob->detect(foreground, key_points);
    // -------------------------------------------------------------- //
    // 检测到特征点 ...
    // key_points.size()
    // -------------------------------------------------------------- //
    imshow("image", frame);
    imshow("foreground", foreground);
    // -------------------------------------------------------------- //
    cv::waitKey(20);
    }
}

整合foreground到frame图像

// 初始化 Mat - 识别区域尺寸
Mat channel = Mat::zeros(foreground.rows, foreground.cols, CV_8UC3);
// 通道数组 ...
vector<cv::Mat> channels;
channels.push_back(foreground);
channels.push_back(foreground);
channels.push_back(foreground);
// 将多个数组组合合并成一个多通道的数组
cv::merge(channels, channel);
// 重定义尺寸 ...
// cv::resize(channel, channel, Size(frame.cols, frame.rows), 0, 0, cv::INTER_LINEAR);
Mat roi = frame(rect);
// 实现图片的线性融合 - 数组有相同的尺寸和相同的信道数
addWeighted(channel, 0.5, roi, 0.5, 0, roi);

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
    // --------------------------------------------------
    namedWindow("foreground", WINDOW_AUTOSIZE);
    // --------------------------------------------------
    VideoCapture m_cap("/home/danoo/xxx.avi");
    // --------------------------------------------------
    BackgroundSubtractorMOG2 m_mog;
    SimpleBlobDetector::Params m_params;
    m_params.filterByArea = true;
    m_params.minArea = 1;
    m_params.blobColor = 255;
    SimpleBlobDetector m_detector(m_params);
    Ptr<SimpleBlobDetector> m_blob = m_detector.create("SimpleBlob");
    // --------------------------------------------------
    Mat frame;
    Mat foreground;
    // Mat background;
    while(m_cap.read(frame))
    {
    // 运动前景检测
    m_mog(frame, foreground, 0.001);
    // 腐蚀
    cv::erode(foreground, foreground, cv::Mat());
    // 膨胀
    cv::dilate(foreground, foreground, cv::Mat());
    // 返回当前背景图像
    // m_mog.getBackgroundImage(background);
    // -------------------------------------------------------------- //
    // 特征点检测
    vector<KeyPoint> key_points;
    m_blob->detect(foreground, key_points);
    // -------------------------------------------------------------- //
    // 检测到特征点 ...
    // key_points.size()
    // -------------------------------------------------------------- //
    // 初始化 Mat - 识别区域尺寸
    Mat channel = Mat::zeros(foreground.rows, foreground.cols, CV_8UC3);
    // 通道数组 ...
    vector<cv::Mat> channels;
    channels.push_back(foreground);
    channels.push_back(foreground);
    channels.push_back(foreground);
    // 将多个数组组合合并成一个多通道的数组
    cv::merge(channels, channel);
    // 重定义尺寸 ...
    // cv::resize(channel, channel, Size(frame.cols, frame.rows), 0, 0, cv::INTER_LINEAR);
    Mat roi = frame;
    // 实现图片的线性融合 - 数组有相同的尺寸和相同的信道数
    addWeighted(channel, 0.5, roi, 0.5, 0, roi);
    // -------------------------------------------------------------- //
    imshow("foreground", frame);
    // -------------------------------------------------------------- //
    cv::waitKey(20);
    }
}