这篇文章将为大家详细讲解有关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;
}
下图是检测的运动目标二值化图像以及在实际图像中叠加的矩形框效果图。
关于“OpenCV如何实现帧差法检测运动目标”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。