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;
}