// 基于混合高斯模型的运动目标检测
// Author: www.icvpr.com
// Blog: http://blog.csdn.net/icvpr
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
void find_contour(IplImage* pFrame,IplImage* pFrImg);
const int CONTOUR_MAX_AERA = 100000;//最大截取前景的面积
const int CONTOUR_MIN_AERA = 9000;//最小截取前景的面积
const double SLOPE_MAX=3;//前景框的最大斜率
const double SLOPE_MIN=1.5;//前景框的最小斜率
int main(int argc, char** argv)
{
std::string videoFile = "E:/1.mp4";
cv::VideoCapture capture;
capture.open(videoFile);
//cv::waitKey(33);
if (!capture.isOpened())
{
std::cout<<"read video failure"<<std::endl;
return -1;
}
cv::BackgroundSubtractorMOG2 mog;
cv::Mat foreground;
cv::Mat background;
cv::Mat frame;
long frameNo = 0;
while (capture.read(frame))
{
++frameNo;
std::cout<<frameNo<<std::endl;
// 运动前景检测,并更新背景
mog(frame, foreground, 0.001);
// 腐蚀
cv::erode(foreground, foreground, cv::Mat());
// 膨胀
cv::dilate(foreground, foreground, cv::Mat());
mog.getBackgroundImage(background); // 返回当前背景图像
cv::imshow("video", foreground);
cv::imshow("background", background);
cv::Mat pFrame=frame;
IplImage pFrame2=pFrame;
//IplImage* pFrImg_temp = cvCloneImage(&pFrame2);
//IplImage* pFrImg_temp2 = cvCreateImage(cvGetSize(pFrImg_temp),8,1);
IplImage pFrImg_temp2 = foreground;//改!!
//cvCvtColor(pFrImg_temp, pFrImg_temp2, CV_BGR2GRAY);
find_contour(&pFrame2,&pFrImg_temp2);
cv::imshow("input",frame);
if (cv::waitKey(25) > 0)
{
break;
}
}
return 0;
}
void find_contour(IplImage* pFrame,IplImage* pFrImg)
{
CvMemStorage *stor;
CvSeq *cont;
int area;
double slope;
//
// 下面的程序段用来找到轮廓
//
// Create dynamic structure and sequence.
stor = cvCreateMemStorage(0);
cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
// 找到所有轮廓
// cvFindContours( pFrImg, stor, &cont, sizeof(CvContour),
// CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
cvFindContours( pFrImg, stor, &cont, sizeof(CvContour),
CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
// 直接使用CONTOUR中的矩形来画轮廓
for(;cont;cont = cont->h_next)
{
CvRect r = ((CvContour*)cont)->rect;
area=r.height*r.width;
slope= r.height*1.0/r.width;
if((area < CONTOUR_MAX_AERA)&&(area > CONTOUR_MIN_AERA)&&(slope>SLOPE_MIN)&&(slope<SLOPE_MAX)) // 面积和形状不合适的去掉
{
cvRectangle( pFrame, cvPoint(r.x,r.y),
cvPoint(r.x + r.width, r.y + r.height),
CV_RGB(255,0,0), 1, CV_AA,0);
}
}
}