OpenCV之帧差法检测运动目标

今天的目标是用OpenCV实现对运动目标的检测,这里选用三帧帧差法。代码如下:

#include <opencv2/opencv.hpp>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <ctype.h>

double Threshold_index=0;
const int CONTOUR_MAX_AERA = 200;

void trackbar(int pos)
{
	Threshold_index=(double)pos;
}

int main(int argc, char* argv[])
{	
	CvCapture *capture=cvCaptureFromCAM(0);
	int n_cnt=0;
	IplImage *img=NULL,
		*img_gray1=NULL,
		*img_gray2=NULL,
		*img_gray3=NULL,
		*img_diff1=NULL,
		*img_diff2=NULL,
		*img_diff_and=NULL,
		*img_binary=NULL,
		*img_dilate=NULL;
	CvMemStorage *stor;
	CvSeq *cont;

	stor=cvCreateMemStorage(0);
	cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);

	cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
	cvNamedWindow("dilate",CV_WINDOW_AUTOSIZE);
	img=cvQueryFrame(capture);
	img_gray1=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	img_gray2=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	img_gray3=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	img_diff1=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	img_diff2=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	img_diff_and=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	img_binary=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	img_dilate=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);

	int index=1;
	cvCreateTrackbar("Threshold","test",&index,255,trackbar);

	while(img=cvQueryFrame(capture))
	{
		if(n_cnt%3==0)
			cvCvtColor(img,img_gray1,CV_BGR2GRAY);
		else if(n_cnt%3==1)
			cvCvtColor(img,img_gray2,CV_BGR2GRAY);
		else if(n_cnt%3==2)
			cvCvtColor(img,img_gray3,CV_BGR2GRAY);
		char c=(char)cvWaitKey(25);
		if(c==27)
			break;
		if(n_cnt>3)
		{
			cvAbsDiff(img_gray1,img_gray2,img_diff1);
			cvAbsDiff(img_gray2,img_gray3,img_diff2);
			cvAnd(img_diff1,img_diff2,img_diff_and);
			cvThreshold(img_diff_and,img_binary,Threshold_index,255,CV_THRESH_BINARY);
			cvShowImage("test",img_binary);

			cvDilate(img_binary,img_dilate);
			//cvShowImage("dilate",img_dilate);

			cvFindContours(img_dilate,stor,&cont,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
			for(;cont;cont = cont->h_next)
			{
						CvRect r = ((CvContour*)cont)->rect;//子类转换为父类例子
						if(r.height * r.width > CONTOUR_MAX_AERA) // 面积小的方形抛弃掉
						{
							cvRectangle(img, cvPoint(r.x,r.y), 
									cvPoint(r.x + r.width, r.y + r.height),
									CV_RGB(255,0,0), 1, CV_AA,0);
						}
			}
			cvShowImage("dilate",img);
		}
		if(c=='s')
		{
			cvSaveImage("d:/img.bmp",img);
			cvSaveImage("d:/img_binary.bmp",img_dilate);
		}
		n_cnt++;
	}

	cvDestroyAllWindows();
	cvReleaseCapture(&capture);
	cvReleaseImage(&img_gray1);
	cvReleaseImage(&img_gray2);
	cvReleaseImage(&img_gray3);
	cvReleaseImage(&img_diff1);
	cvReleaseImage(&img_diff2);
	cvReleaseImage(&img_diff_and);
	cvReleaseImage(&img_binary);
	cvReleaseImage(&img_dilate);
	cvReleaseMemStorage(&stor);
	return 0;
}

下图是检测的运动目标二值化图像以及在实际图像中叠加的矩形框效果图。




猜你喜欢

转载自blog.csdn.net/DY580C/article/details/35859551