opencv程序十九:基于帧间差分法的区域目标入侵检测

运行程序在原图像上画个入侵检测的方框,有运动目标进入方框产生报警,并将入侵时的帧保存为视频

程序如下:

// 26RuQinDetection_BaseTwoDiff.cpp : 定义控制台应用程序的入口点。
// 区域入侵检测,基于两帧差分法

#include "stdafx.h"
#include <cv.h>  
#include <cxcore.h>  
#include <highgui.h>  
//CAM定义用摄像头获得视频else文件
//#define CAM 

int apos=30;
CvRect box;
bool Drawing=false;
bool out=false;
int xx1,xx2,yy1,yy2;
int n=0;
CvVideoWriter* writer;//保存视频
CvFont font;  //字体

void DrawRect(IplImage*img,CvRect rect)
{
	xx1=box.x;
	xx2=box.x +box.width ;
	yy1=box.y ;
	yy2=box.y +box.height ;
    cvRectangle(img,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),cvScalar(0x00,0xff,0x00),2);

}  
//实现对窗口Window_Name上的对象param添加鼠标响应操作
void my_mouse_callback(int event,int x,int y,int flags,void* param)
{
	IplImage*img=(IplImage*)param;
	switch(event)
	{
		case CV_EVENT_MOUSEMOVE:
		{
			if(Drawing)
			{
			box.width=x-box.x;
			box.height=y-box.y;
			}
		}
		break;
		
		case CV_EVENT_LBUTTONDOWN:
		{
			Drawing=true;
			box=cvRect(x,y,0,0);
		}
		break;

		case CV_EVENT_LBUTTONUP:
		{
			Drawing=false;
			if (box.width<0)
			{
				box.x+=box.width;
				box.width*=-1;
			}
			if (box.height<0)
			{
				box.y+=box.height;
				box.height*=-1;
			}
			out=true;
			DrawRect(img,box);

		}
		break;
		
	}
}


void on_trackbar(int pos)  
{  
        apos=pos;   
}    
  
int main( int argc, char** argv )  
{  
    //声明IplImage指针  
    IplImage* pFrame = NULL; //原始视频帧  
    IplImage* pFrImg = NULL; //提取的前景图像,即运动目标  
    IplImage* pBkImg = NULL; //背景图像 
  
    CvMat* pFrameMat = NULL; //原始视频矩阵 
    CvMat* pFrMat = NULL;    //前景矩阵
    CvMat* pBkMat = NULL;    //背景矩阵
  
    CvCapture* pCapture = NULL;  
    //帧数
    int nFrmNum = 0;  
	box=cvRect(0,0,-1,-1);
	CvScalar s;
	int i, j;
	cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 1.0, 1.0, 0, 2, 8);
    //创建窗口  
    cvNamedWindow("video", 1);  
    //cvNamedWindow("background",1);  
    cvNamedWindow("foreground",1);  
    //使窗口有序排列  
    cvMoveWindow("video", 30, 0);  
    //cvMoveWindow("background", 360, 0);  
    cvMoveWindow("foreground", 690, 0);  
    // 滑动条          
    //int nThreshold = 30;        
    cvCreateTrackbar("阀值", "foreground", &apos, 100, on_trackbar);
	
#ifdef CAM
    if( !(pCapture = cvCaptureFromCAM(0)))  
    {  
        //pCapture = cvCaptureFromCAM(-1))  
        fprintf(stderr, "Can not open CAM .\n");  
        return -2;  
    }  
#else
	char *filename="../../0VideoSource/zjk_out.avi";
	if( !(pCapture = cvCaptureFromAVI(filename)))  
    {  
        //pCapture = cvCaptureFromCAM(-1))  
        fprintf(stderr, "Can not open file %s.\n",filename);  
        return -2;  
    }    
#endif
	pFrame = cvQueryFrame( pCapture );
	IplImage*temp1=cvCloneImage(pFrame);
	cvSetMouseCallback("video",my_mouse_callback,(void*)pFrame);
	while(out==false)
	{
		cvCopyImage(pFrame,temp1);
		if(Drawing)
			DrawRect(temp1,box);
		cvShowImage("video",temp1);
		if(cvWaitKey(100)==27)
			break;
	}
	printf("%d,%d,%d,%d,",xx1,xx2,yy1,yy2);
	//创建视频
	writer = cvCreateVideoWriter( "zjk_out.avi", CV_FOURCC('M','J','P','G'), 27, cvSize(pFrame->width, pFrame->height));
	//逐帧读取视频  
    while(pFrame = cvQueryFrame( pCapture ))  
    {  
        nFrmNum++;  
		
		n=0;
        //如果是第一帧,需要申请内存,并初始化  
        if(nFrmNum == 1)  
        {  
            pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);  
            pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);  
  
            pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);  
            pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);  
            pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);  
  
            //转化成单通道图像再处理  
            cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY); //第一帧作为背景了 
            //cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY); // 
			//转换成矩阵
            cvConvert(pBkImg, pFrameMat);  //虽然没用,相当于给矩阵赋了初值
            cvConvert(pBkImg, pFrMat);	   //虽然没用,相当于给矩阵赋了初值
            cvConvert(pBkImg, pBkMat);  
        }  
        else  
        {  
            cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);  
            cvConvert(pFrImg, pFrameMat);  
            //高斯滤波先,以平滑图像  
            //cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);  
  
            //当前帧跟背景图相减 计算两个数组差的绝对值 
            cvAbsDiff(pFrameMat, pBkMat, pFrMat);  
			
            //二值化前景图  
            cvThreshold(pFrMat, pFrImg, apos, 255.0, CV_THRESH_BINARY);  
			
            //进行形态学滤波,去掉噪音  只有摄像头时候会用
			#ifdef CAM
			cvErode(pFrImg, pFrImg, 0, 1);  
            cvDilate(pFrImg, pFrImg, 0, 1);  
			/* cvDilate(pFrImg, pFrImg, 0, 1);
			cvErode(pFrImg, pFrImg, 0, 1);*/  
			#endif
            //更新背景  
            //cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);  
            //将背景转化为图像格式,用以显示  
            //cvConvert(pBkMat, pBkImg);  
			cvCopy(pFrameMat,pBkMat,NULL);
			//pBkMat=pFrameMat;
            //显示图像  
			for(j = xx1; j < xx2; j++)	
				for(i = yy1; i < yy2; i++)
				{ 
					s = cvGet2D(pFrImg,i,j);
					if (s.val[0]==0xff)//0xff为白色的
					{
						n++;
					}
				}
			printf("n=%d\n",n);
			//没有目标入侵
			if(n<=50)
			{
				//在原图像上画框
				cvRectangle(pFrame,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),cvScalar(0x00,0xff,0x00),2);
				//在二值化前景图上画框
				cvRectangle(pFrImg,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),cvScalar(0xff,0xff,0xff),2);
				
			}
			else //有目标入侵
			{
				//在原图像上报警并保存视频
				cvRectangle(pFrame,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),cvScalar(0x00,0x00,0xff),2);
				cvPutText(pFrame, "warning!", cvPoint(0,20), &font, CV_RGB(255,0,0));
				cvWriteFrame(writer, pFrame);//将图像写入视频
				//在二值化前景图上报警
				cvRectangle(pFrImg,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),cvScalar(0xff,0xff,0xff),2);
				cvPutText(pFrImg, "warning!", cvPoint(0,20), &font, CV_RGB(255,255,255));
				
			}
			
            cvShowImage("video", pFrame);  
            //cvShowImage("background", pBkImg);  
            cvShowImage("foreground", pFrImg);  
			
            //如果有按键事件,则跳出循环  
            //此等待也为cvShowImage函数提供时间完成显示  
            //等待时间可以根据CPU速度调整  
            if( cvWaitKey(100) >= 0 )  
            {  
                printf("into wait if");
				//break;  
            }  
			
        }  
    }  
    cvWaitKey();  
  
    //销毁窗口  
    cvDestroyWindow("video");  
    //cvDestroyWindow("background");  
    cvDestroyWindow("foreground");  
  
    //释放图像和矩阵  
    cvReleaseImage(&pFrImg);  
    cvReleaseImage(&pBkImg);  
  
    cvReleaseMat(&pFrameMat);  
    cvReleaseMat(&pFrMat);  
    cvReleaseMat(&pBkMat);  
  
    cvReleaseCapture(&pCapture);  
	cvReleaseVideoWriter(&writer);
    return 0;  
}  




结果如下:



http://www.niftyadmin.cn/n/588215.html

相关文章

rodert教你学Maven-实战这一篇就够了

欢迎大家前来白嫖PDF。下图回复&#xff1a;666 本教程致力于最实用教程&#xff0c;个别图片粘贴有丢失&#xff0c;还有来领取原版。 文章目录前言1.什么是Maven&#xff1f;2.maven的作用2.1.Maven的功能2.2.为什么使用maven3.maven安装和配置3.1.安装3.2.配置4.maven项目规…

略谈如何从工作线程中弹出对话框

朱金灿 工作线程&#xff0c;在一些技术文章被称为辅助线程&#xff0c;是相对于主线程而言的。在工作线程中使用界面需要一些技巧。我就曾在工程线程中弹出对话框中遇到过莫名奇妙的错误。下面就我的经验谈谈如何从工作线程中弹出对话框&#xff08;暂时只讲方法&#xff0c;原…

几种常用的视频接口

视频接口 我们经常在家里的电视机、各种播放器上&#xff0c;视频会议产品和监控产品的编解码器的视频输入输出接口上看到很多视频接口&#xff0c;这些视频接口哪些是模拟接口、哪些是数字接口&#xff0c;哪些接口可以传输高清图像等&#xff0c;下面就做一个详细的介绍。 目…

VC使用CRT调试功能来检测内存泄漏

信息来源&#xff1a;csdnC/C 编程语言的最强大功能之一便是其动态分配和释放内存&#xff0c;但是中国有句古话&#xff1a;“最大的长处也可能成为最大的弱点”&#xff0c;那么 C/C 应用程序正好印证了这句话。在 C/C 应用程序开发过程中&#xff0c;动态分配的内存处理不当…

rodert单排学习redis入门【黑铁】

redis入门 欢迎大家前来白嫖PDF。下图回复&#xff1a;666 本教程致力于最实用教程&#xff0c;个别图片粘贴有丢失&#xff0c;还有来领取原版。 文章目录前言1.NoSql(not only sql)2.Redis入门3.Redis特性3.1.性能3.2.特性3.3.优势4.Redis使用场景5.安装5.1.单机安装5.1.1.wi…

OpenCv矩阵操作函数大全

OpenCv矩阵操作函数大全 .分类&#xff1a; C/C opencv 数字图像处理 2012-02-13 20:43 96人阅读 评论(0) 收藏 举报 OpenCv矩阵操作有很多函数有mask&#xff0c;代表掩码&#xff0c;如果某位mask是0,那么对应的src的那一位就不计算&#xff0c;mask要和矩阵/ROI/的大小相等大…