混合高斯模型+背景抑制+形态学

15 篇文章 0 订阅
15 篇文章 0 订阅

source.cpp

#include<iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <stdio.h>
#include <opencv/cvaux.h>
#include <vector>
#include <cv.h>
#include <math.h>
#include <iostream>
#include "deleteerrorobject.h"
#pragma warning(disable:4996)
using namespace std; 
using namespace cv;
int main()
{

    DeleteErrorObject delecterrorobject;
    VideoCapture video("C:\\Users\\ThinkCentre\\Desktop\\数学建模\\附件3-检测前景视频\\campus\\Campus\\input.avi");
    string filenames1 = "C:\\Users\\ThinkCentre\\Desktop\\数学建模\\附件2-典型视频\\campus.avi";
    string filenames2 = "C:\\Users\\ThinkCentre\\Desktop\\数学建模\\附件2-典型视频\\campus.avi";
    VideoWriter outputVideo1(filenames1, CV_FOURCC('M', 'J', 'P', 'G'), 25.0, Size(160, 128), false);
    VideoWriter outputVideo2(filenames2, CV_FOURCC('M', 'J', 'P', 'G'), 25.0, Size(160, 128), false);
    int frame_number,total_frame_number;
    Mat frame, mask, thresholdImage, output, saliencymap, bg;
    Mat pre_img;
    Mat flow_img;
    Mat motion2color;
    Mat detect_bgSubtractor;
    BackgroundSubtractorMOG bgSubtractor(10, 20, 0.8, false);
    //腐蚀膨胀算子
    Mat element_erode = getStructuringElement(MORPH_RECT, Size(3, 3));
    Mat element_dilate = getStructuringElement(MORPH_RECT, Size(5, 5));
    Mat new_mask_img;
    //
    if (!video.isOpened())
    {
        cout << "please try again!" << endl;
        return (-1);
    }
    else
    {
        total_frame_number = int(video.get(CV_CAP_PROP_FRAME_COUNT));
        for (frame_number = 0; frame_number < total_frame_number; frame_number++)
        {
            video >> frame;
            namedWindow("frame");
            imshow("frame", frame);
            bgSubtractor(frame, mask, 0.001);
            bgSubtractor.getBackgroundImage(bg);
            outputVideo1 << mask;
            //******************************************************
            // delete bad object
            //******************************************************
            new_mask_img = delecterrorobject.GetRectOfAllObject(mask, frame);
            //******************************************************
            //腐蚀膨胀
            erode(new_mask_img, new_mask_img, element_erode);
            dilate(new_mask_img, new_mask_img, element_dilate);
            //******************************************************
            outputVideo2 << new_mask_img;
            namedWindow("new_mask_img");
            imshow("mask", new_mask_img);
            namedWindow("mask");
            imshow("mask", mask);
            waitKey(60);
//          }
        }
    }
    return 0;
}

deleteerrorobject.h

#include<iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <stdio.h>
#include <opencv/cvaux.h>
#include <vector>
#include <cv.h>
#include <math.h>
#include <iostream>

using namespace cv;
using namespace std;
class DeleteErrorObject
{
public:
    Mat GetRectOfAllObject(Mat input_img, Mat original_img);
    Mat DeleteSmallRect(Rect rect,Mat input_img);
    double CompareBackgroundAndObject(Rect rect, Mat input_img);
private:

    vector<vector<Point>> object_contours;
    vector<Rect> rectbounding;
};

deleteerrorobject.cpp

# include "deleteerrorobject.h"

Mat DeleteErrorObject::GetRectOfAllObject(Mat input_binary_img,Mat original_img )
{
    Mat input_img_copy = input_binary_img.clone();
    Mat original_img_copy = original_img.clone();
    Rect every_bounding;
    double compare_background_ROI;



    //************************************************************************************
    //获得混合高斯模型得到的二值化的图像的连通域
    findContours(input_img_copy, object_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    //************************************************************************************
    if (object_contours.size() != 0)
    {
        for (unsigned int num_bounding = 0; num_bounding < object_contours.size(); num_bounding++)
        {
            //************************************************************************************
            //获得混合高斯模型得到的二值化的图像的连通域矩形包络 
            every_bounding = boundingRect(object_contours[num_bounding]);
            //************************************************************************************
            //比较在原图中矩形包络所表示的区域与其背景之间的相关性,相关性越高,代表与背景越接近,此区域就越不可能是行人
            compare_background_ROI = CompareBackgroundAndObject(every_bounding, original_img_copy);
            //************************************************************************************
            if ((every_bounding.width* every_bounding.height <= 50 || compare_background_ROI<0.05))
            {
                //************************************************************************************
                //删除不符合条件的区域
                DeleteSmallRect(every_bounding, input_binary_img);
                //************************************************************************************
            }
            else
            {
                rectbounding.push_back(every_bounding);
            }
        }
    }

    return input_binary_img;
}
Mat DeleteErrorObject::DeleteSmallRect(Rect rect, Mat input_img)
{
    for (int j = rect.y; j < rect.y + rect.height; j++)
    {
        uchar* data = input_img.ptr<uchar>(j);
        for (int i = rect.x; i < rect.x + rect.width; i++)
        {            
            data[i] = 0;
        }
    }
    return input_img;
}

double DeleteErrorObject::CompareBackgroundAndObject(Rect rect, Mat original_img_copy)
{
    Mat img_roi;
    Mat img_background;
    Rect backgrount_rect;

    const int img_roi_channels[1] = { 0 };
    const int img_roi_histSize[1] = { 256 };
    float img_roi_hranges[2] = { 0, 255 };
    const float* img_roi_ranges[1] = { img_roi_hranges };

    const int img_background_channels[1] = { 0 };
    const int img_background_histSize[1] = { 256 };
    float img_background_hranges[2] = { 0, 255 };
    const float* img_background_ranges[1] = { img_background_hranges };

    int width = original_img_copy.cols;
    int height = original_img_copy.rows;

    Rect img_background_rect;

    MatND img_roi_hist;
    MatND img_background_hist;

    int center_x = original_img_copy.cols / 2;
    int center_y = original_img_copy.rows / 2;



    //************************************************************************************************
    //取背景像素(取出目标所在的位置的原图的背景)

    if ((rect.x + rect.width) < center_x && (rect.y + rect.height) < center_y)
    {
        img_background = original_img_copy(Rect(1, 1, center_x, center_y));
    }
    else if ((rect.x + rect.width) > center_x && (rect.y + rect.height) > center_y)
    {
        img_background = original_img_copy(Rect(center_x, center_y, center_x, center_y));
    }
    else if ((rect.x + rect.width) < center_x && (rect.y + rect.height) > center_y)
    {
        img_background = original_img_copy(Rect(1, center_y, center_x, center_y));
    }
    else
    {
        img_background = original_img_copy(Rect(center_x, 1, center_x, center_y));
    }

    //************************************************************************************************

    img_roi = original_img_copy(rect);

    //计算直方图
    calcHist(&img_roi, 1, img_roi_channels, Mat(), img_roi_hist, 1, img_roi_histSize, img_roi_ranges);
    calcHist(&img_background, 1, img_background_channels, Mat(), img_background_hist, 1, img_background_histSize, img_background_ranges);
    //直方图比较
    double compare_background_ROI = compareHist(img_roi_hist, img_background_hist, CV_COMP_CORREL);
    return compare_background_ROI;
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值