对这个运动目标检测方法实现的结果A Hybrid Algorithm for Moving Object Detection

最近在做烟火检测,需要用到运动检测,看到论文A System for Video Surveillance and Monitoring中的A Hybrid Algorithm for Moving Object Detection这个方法,我用opencv将其实现,代码下面会贴出,但是其的到的结果很差,不知道代码哪里出了问题,请高手给予指点,谢谢!

左图为原图,有图为用上面论文中的方法得到前景图像,【自己的代码可能写错了,请大神们给予指点谢谢】

代码如下:

#include <stdio.h>

#include <cv.h>

#include <cxcore.h>

#include <highgui.h>

int main(int argc,char** argv)

{

CvCapture* pCapture=NULL;

cvNamedWindow("source",1);

cvNamedWindow("move_detection",1);

cvMoveWindow("source",30,0);

cvMoveWindow("move_detection",690,0);

char *szFileName = "E:\\技术总结\\视频中的火花和烟雾的检测\\烟的测试视频\\Basketball_yard.avi";

if(!(pCapture=cvCaptureFromFile(szFileName)))

{

fprintf(stderr,"Can not open video file %s\n",szFileName);

return -2;

}

IplImage* pFrame = NULL;

IplImage* pFrImg = NULL;

IplImage* pBkImg = NULL;

CvMat* pFrameMat = NULL;

CvMat* pFrMat = NULL;

CvMat* pBkMat = NULL;

CvMat* pMatChannels[4] = {NULL,NULL,NULL,NULL};

CvMat* pFrameMatPre1 = NULL;

CvMat* pFrameMatPre2 = NULL;

CvMat* pFrameMatCur = NULL;

CvMat* framediff1 = NULL;

CvMat* framediff2 = NULL;

CvMat* threshold = NULL;

int nFrmNum=0;

int frame_height;

int frame_width;

int frame_channel;

int k;

while(pFrame=cvQueryFrame(pCapture))

{

nFrmNum++;

frame_height = pFrame->height;

frame_width = pFrame->width;

frame_channel = pFrame->nChannels;

if(nFrmNum==1)

{

pBkImg = cvCreateImage(cvSize(frame_width, frame_height),  IPL_DEPTH_8U,1);

pFrImg = cvCreateImage(cvSize(frame_width, frame_height),  IPL_DEPTH_8U,1);

pBkMat = cvCreateMat(frame_height, frame_width, CV_32FC1);

pFrMat = cvCreateMat(frame_height, frame_width, CV_32FC1);

pFrameMat = cvCreateMat(frame_height, frame_width, CV_32FC3);

pFrameMatPre1 = cvCreateMat(frame_height, frame_width, CV_32FC1);

pFrameMatPre2 = cvCreateMat(frame_height, frame_width, CV_32FC1);

pFrameMatCur = cvCreateMat(frame_height, frame_width, CV_32FC1);

framediff1 = cvCreateMat(frame_height, frame_width, CV_32FC1);

framediff2 = cvCreateMat(frame_height, frame_width, CV_32FC1);

threshold = cvCreateMat(frame_height, frame_width, CV_32FC1);

for(k=0;k<frame_channel;k++)

{

pMatChannels[k] = cvCreateMat(frame_height, frame_width, CV_32FC1);

}

//转化成单通道图像再处理

cvConvertScale(pFrame,pFrameMat,1,0);

cvSplit(pFrameMat, pMatChannels[0], pMatChannels[1], pMatChannels[2], pMatChannels[3]);

cvAddWeighted(pMatChannels[0],0.114,pMatChannels[1],0.587,0,pFrameMatPre1);

cvAddWeighted(pMatChannels[2],0.299,pFrameMatPre1,1,0,pFrameMatPre1); //转换为灰度图像

cvConvert(pFrameMatPre1, pBkMat);

cvConvert(pFrameMatPre1, pFrameMatPre2);

cvZero(pFrameMatCur);

cvZero(pFrameMatPre2);

cvSet(threshold,cvScalar(5),NULL); //阈值设为5

}

else

{

double t = (double)cvGetTickCount(); //计算每帧时间

const double alpha = 0.02;

const int threshold_wavelet = 5;

const int threshold_color = 7;

int i,j;

cvConvertScale(pFrame,pFrameMat,1,0);

cvSplit(pFrameMat, pMatChannels[0], pMatChannels[1], pMatChannels[2], pMatChannels[3]);

cvAddWeighted(pMatChannels[0],0.114,pMatChannels[1],0.587,0,pFrameMatCur);

cvAddWeighted(pMatChannels[2],0.299,pFrameMatCur,1,0,pFrameMatCur); //转换为灰度图像

//当前帧跟背景图相减

cvAbsDiff(pFrameMatCur, pFrameMatPre1, framediff1);

cvAbsDiff(pFrameMatCur, pFrameMatPre2, framediff2); //帧差法

//cvAbsDiff(pFrameMatCur, pBkMat, pFrMat);

//二值化前景图

for(i=0;i<frame_height;i++)

for(j=0;j<frame_width;j++)

{

if((cvmGet(framediff1,i,j) > cvmGet(threshold,i,j)) && (cvmGet(framediff2,i,j) > cvmGet(threshold,i,j)))

cvmSet(pFrMat,i,j,255.0);

else

cvmSet(pFrMat,i,j,0.0);

if(cvmGet(pFrMat,i,j))

{

double differ = abs(cvmGet(pFrameMatCur,i,j) - cvmGet(pBkMat,i,j)); //背景差分法

if(differ > cvmGet(threshold,i,j))

cvmSet(pFrMat,i,j,255); //前景像素用255表示

else

cvmSet(pFrMat,i,j,0);

}

}

//进行形态学滤波 ,连通域分析

// cvErode(pFrMat, pFrMat, 0, 1);

// cvDilate(pFrMat, pFrMat, 0, 1);

// cvMorphologyEx( pFrMat, pFrMat, 0, 0, CV_MOP_OPEN, 1 );

// cvMorphologyEx( pFrMat, pFrMat, 0, 0, CV_MOP_CLOSE, 2 );

//

// cvConvert(pFrMat, pFrImg);

// find_connected_components(pFrImg, 1, 4,NULL,NULL,NULL);

// cvConvert(pFrImg,pFrMat);

//当前帧图像更新

cvConvert(pFrameMatPre1,pFrameMatPre2);

cvConvert(pFrameMatCur,pFrameMatPre1);

//背景更新

for(i=0;i<frame_height;i++)

for(j=0;j<frame_width;j++)

{

if(cvGetReal2D(pFrMat,i,j) == 0)

{

double temp = alpha*cvmGet(pBkMat,i,j)+(1-alpha)*cvmGet(pFrameMatCur,i,j);

cvmSet(pBkMat,i,j,temp);

double differ = alpha*cvmGet(threshold,i,j)+(1-alpha)*5*abs(cvmGet(pFrameMatCur,i,j) - cvmGet(pBkMat,i,j));

cvmSet(threshold,i,j,differ);

}

}

//转化为图像格式,用以显示

cvConvert(pBkMat, pBkImg);

cvConvert(pFrMat, pFrImg);

//把图像正过来

//pBkImg->origin = pFrame->origin;

pFrImg->origin = pFrame->origin;

// 计算运算时间

t = (double)cvGetTickCount() - t;

printf( "calculation time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );

//显示图像

//cvWriteFrame(writerin,pFrame);

//cvWriteFrame(writerout,pResult);

cvShowImage("source", pFrame);

cvShowImage("move_detection", pFrImg);

cvSaveImage("src.bmp",pFrame);

cvSaveImage("fg.bmp",pFrImg);

//如果有按键事件,则跳出循环

//此等待也为cvShowImage函数提供时间完成显示

//等待时间可以根据CPU速度调整

if( cvWaitKey(10) >= 0 )

break;

}

}

//销毁窗口

cvDestroyWindow("source");

cvDestroyWindow("move_detection");

//cvDestroyWindow("spatial_wavelet_detection");

cvDestroyWindow("color_detection");

cvDestroyWindow("result");

//释放图像和矩阵

cvReleaseImage(&pFrImg);

cvReleaseImage(&pBkImg);

cvReleaseMat(&pFrMat);

cvReleaseMat(&pBkMat);

cvReleaseMat(&pFrameMat);

cvReleaseMat(&pFrameMatCur);

cvReleaseMat(&pFrameMatPre1);

cvReleaseMat(&pFrameMatPre2);

cvReleaseMat(&framediff1);

cvReleaseMat(&framediff2);

for(k=0;k<frame_channel;k++)

{

cvReleaseMat(&pMatChannels[k]);

}

//cvReleaseVideoWriter(&writerin);

//cvReleaseVideoWriter(&writerout);

cvReleaseCapture(&pCapture);

return 0;

}

请大家给予指点,谢谢!

对应的工程可以免费下载:http://download.csdn.net/detail/lwjaiyjk3/7452145

对这个运动目标检测方法实现的结果A Hybrid Algorithm for Moving Object Detection

时间: 2024-10-14 14:31:02

对这个运动目标检测方法实现的结果A Hybrid Algorithm for Moving Object Detection的相关文章

OpenCV运动目标检测——帧间差,混合高斯模型方法

一.简单的帧间差方法 帧差法是在连续的图像序列中两个或三个相邻帧间采用基于像素的时间差分并且闽值化来提取图像中的运动区域. 代码: int _tmain(int argc, _TCHAR* argv[]) { VideoCapture capture("bike.avi"); if(!capture.isOpened()) return -1; double rate = capture.get(CV_CAP_PROP_FPS); int delay = 1000/rate; Mat

【转】 运动目标检测跟踪主流算法

不全,需要慢慢补充 一.运动目标检测 (一)背景差 1.帧差 2.GMM 等 背景减算法可以对背景的光照变化.噪声干扰以及周期性运动等进行建模,在各种不同情况下它都可以准确地检测出运动目标.因此对于固定摄像头的情形,目前大多数的跟踪算法中都采用背景减算法来进行目标检测.背景减算法的局限性在于它需要一个静态的固定摄像头. (二)运动场 光流法 光流估计的方法都是基于以下假设:图像灰度分布的变化完全是目标或者场景的运动引起的,也就是说,目标与场景的灰度不随时间变化.这使得光流方法抗噪声能力较差,其应

运动目标检测ViBe算法

一.运动目标检测简介   视频中的运动目标检测这一块现在的方法实在是太多了.运动目标检测的算法依照目标与摄像机之间的关系可以分为静态背景下运动检测和动态背景下运动检测.先简单从视频中的背景类型来讨论.        静态背景下的目标检测,就是从序列图像中将实际的变化区域和背景区分开了.在背景静止的大前提下进行运动目标检测的方法有很多,这些方法比较侧重于背景扰动小噪声的消除,如:1.背景差分法2.帧间差分法3.光流法4.混合高斯模型(GMM)5.码本(codebook)还有这些方法的变种,例如三帧

静态背景下运动目标检测

前言:运动对象常用在视频监控领域,目的是从序列图像中将变化区域从背景图像中提取出来,运动区域的有效检测对目标分类.跟踪.行为理解等后期处理非常重要.根据摄像机与运动目标之间的关系可分为静态背景下的运动目标检(摄像机静止)和动态背景下的运动目标检测(摄像机也同时运动).项目中我用到的是静态背景下的运动目标检测,需通过固定摄像机检测运动物体,并完成抓取动作. 内容: 运动目标检测常用的方法一般分为两大类,一种是基于特征的方法,另一种是基于灰度的方法.基于特征的方法是依据图像的特征来检测运动目标,多用

运动目标检测--改进的背景减法

一.概述 本文提出了一种改进的基于背景减法的运动目标检测算法,该算法能自适应地对背景进行初始化和实时更新,并能有效克服光照等外界条件变化对运动目标检测的影响. 二.算法介绍 基于背景减法的视频运动目标检测主要包括预处理.背景建模.目标检测和后处理四个步骤.本文的算法流程如图 1 所示,算法中的预处理是对每一帧图像都进行去噪和亮度归一化处理,以抑制光照突变和噪声的影响:背景建模则采用改进的均值滤波法自动初始化背景,并不断实时更新背景,以克服环境光照变化所产生的影响:目标检测是在背景减法的基础上采用

运动目标检测跟踪各过程算法综述

运动目标检测跟踪各过程算法综述 图像预处理数字图像中的几种典型噪声有:高斯噪声来源于电子电路噪声和低照明度或高温带来的传感器噪声:椒盐噪声类似于随机分布在图像上的胡椒和盐粉微粒,主要由图像切割引起或变换域引起的误差:加性噪声是图像在传输中引进的信道噪声.一般来说,引入的都是加性随机噪声,可以采用均值滤波.中值滤波.高斯滤波等方法去除噪声,提高信噪比.均值滤波在噪声分布较平均,且峰值不是很高的情况下能够得到较好的应用:中值滤波对尖脉冲噪声的滤除有较好的效果,并且能突出图像的边缘和细节:高斯滤波对滤

GDI 泄漏检测方法

方法一 1.打开电脑的[任务管理器],选择[进程]页,点击菜单项的[查看]项,选择[选择列]: 2.勾选[GDI对象(J)]即可. 3.此时,用户就可以在进程中看到每个进程对应的GDI对象,每个进程的GDI对象(网页浏览器除外,每打开一个网页GDI对象都会增加)基本上是一定的,如果不断上涨,则说明程序存在GDI泄漏问题. 方法二 使用检测工具GDIndicator,支持win7+xp 1.启动待检测的程序和GDIndicator,启动顺序没有要求,之后F5刷新,就能看到系统中所有进程,和使用的资

通讯链路的检测方法

问题背景: TCP不能及时通知连接中断,如果使用keep-live机制默认时间是2小时11分钟15秒没有通讯才会发送探测消息,如依靠TCP超时机制可能要等待9分钟才能检测出网络中断,因此必须用户自己检测连接是否正常. 连接中断可能的原因: 1)一方主机崩溃 发不出FIN,对等方依靠重发检测链路中断,如果崩溃方在对等方准备撤销连接之前又重新启动了,若此时收到了消息则会回复RST消息给对等方,这将导致对等方撤销连接,对等方会收到ECONNECREST错误,或者下一次读导致SIGPIPE信号或EPIP

百度云离线下载含有违规内容检测方法分析

最近国家开始一轮净网行动,清除网上的淫秽***信息.各大互联网厂家纷纷开始行动,比如当年很好用的百度云离线下载就一度关闭.后来再次开启后,就出现了这句经典词,因含有违规内容被屏蔽无法下载. 其实被屏蔽的不一定都是不健康视频,有些仅仅是因为文件名含有一些字眼而已,比如一些美国大片的枪版就几乎都不能通过百度云的离线下载检测.据说这种方法还在迅雷等地方都有检测,因此我们来分析一下,这个检测到底是如何进行的. 首先上传了一个BT文件,BT文件里面的内容为大闹天宫的电影,但是我把文件名改成了含有敏感词汇的