OpenCV实现简单摄像头视频监控程序
如何在冗长的监控录像中找到关键点?我们知道,监控录像中大部分信息都是没用的,那些信息就等同于一幅静态图像。我们要等待监控的范围内出现异常情况时再跟踪。
这其实是一个最简单的计算机图像处理程序。简单的思路是这样的:首先给摄像头取景采样,当背景稳定时,以该图片作为基准图片。然后在监控过程中,若出现了和基准图片反差较大的视频帧,那么启动捕捉程序,并标出异常区域。
程序如下:
#include#include #include #include #include #defineESC0x1b #defineTRUE1 #defineFALSE0 //检测图像异常,仅在采样时调用。 //返回真表示已检测到异常,需要重新采样。 //返回假表示未检测到异常,在一定时间后即可获取基准图像。 intdetect(CvCapture*capture,IplImage*std,IplImage*frm,CvRect*rect); //图像采样,确定基准图像,以便监测场景变化 //返回真表示采样成功,返回假表示采样失败 intgather(CvCapture*capture,IplImage*std,CvRect*rect); //摄像机监视,用矩形框标示出和基准图像反差较大的图像范围。 voidmonitor(CvCapture*capture,IplImage*std,CvRect*rect); //求x的平方 intsquare(intx); intmain(intargc,char*argv[]) { CvCapture*capture;//摄像机源 IplImage*std;//基准图像 CvRectrect;//异常位置矩形标识 capture=cvCreateCameraCapture(0); if(!capture)return-1; std=cvQueryFrame(capture); rect=cvRect(-1,-1,0,0); std=cvCloneImage(std); cvNamedWindow("MonitorScreen"); if(gather(capture,std,&rect)) { monitor(capture,std,&rect); } cvDestroyWindow("MonitorScreen"); cvReleaseImage(&std); cvReleaseCapture(&capture); return0; } intdetect(CvCapture*capture,IplImage*std,IplImage*frm,CvRect*rect) { intx,y;//循环变量 intf=FALSE;//检测到异常的标识 intx1=-1,x2=0;//异常区域矩形横坐标范围 inty1=-1,y2=0;//异常区域矩形纵坐标范围 uchar*ptr1b,*ptr1g,*ptr1r;//基准图像的每个像素的三个颜色通道的值 uchar*ptr2b,*ptr2g,*ptr2r;//实时图像的每个像素的三个颜色通道的值 intsquaresum;//计算RGB差值平方和 //遍历图像中的每一个点,将实时采样图与基准图做比较,检测两者的每一个 //像素点的RGB差值平方和。当该值大于8192时(换算成灰度值则意味着 //两者的灰度差大于90)则立即报告出现异常,只有遍历完毕后仍未找到异 //常才报告没有异常。 for(y=0;y height;y++) { for(x=0;x width;x++) { ptr1b=cvPtr2D(std,y,x)+0;ptr2b=cvPtr2D(frm,y,x)+0; ptr1g=cvPtr2D(std,y,x)+1;ptr2g=cvPtr2D(frm,y,x)+1; ptr1r=cvPtr2D(std,y,x)+2;ptr2r=cvPtr2D(frm,y,x)+2; squaresum= square(*ptr1b-*ptr2b)+ square(*ptr1g-*ptr2g)+ square(*ptr1r-*ptr2r); if(squaresum>8192) { if(f) { if(x x2)x2=x; if(y y2)y2=y; } else { f=TRUE; x1=x;y1=y; x2=x;y2=y; } } } } if(x2-x1>frm->width/4||y2-y1>frm->height/4) { f=TRUE; } else { f=FALSE; } *rect=cvRect(x1,y1,x2-x1,y2-y1); returnf; } intgather(CvCapture*capture,IplImage*std,CvRect*rect) { IplImage*frm; intexcept=FALSE;//检测到异常的标识 intfinish=FALSE;//采样已完成的标识 clock_tstart_time,real_time;//时间段监测 start_time=clock(); while(!finish) { frm=cvQueryFrame(capture); cvShowImage("MonitorScreen",frm); except=detect(capture,std,frm,rect); if(except) { start_time=clock(); cvCopyImage(frm,std); } if(cvWaitKey(15)==ESC)break; real_time=clock(); if(real_time-start_time>=3000) { finish=TRUE; } } returnfinish; } voidmonitor(CvCapture*capture,IplImage*std,CvRect*rect) { IplImage*frm; intexcept=FALSE; intfinish=FALSE; while(!finish) { frm=cvQueryFrame(capture); except=detect(capture,std,frm,rect); if(except) { cvRectangle( frm, cvPoint(rect->x,rect->y), cvPoint(rect->x+rect->width,rect->y+rect->height), cvScalar(0,0,255), 4); } cvShowImage("MonitorScreen",frm); if(cvWaitKey(15)==ESC) { finish=TRUE; } } } intsquare(intx) { returnx*x; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。