帧差分算法
‘壹’ 视频监控中,三帧差分法的运动目标检测的原理是什么
对于帧差法的”双影”现象,有人提出来了三帧差法。其原理如下所示:
1. 由i(t)-i(t-1)得到前景图 F1
2. 由i(t+1)-i(t)得到前景图 F2
3. F1 ∩ F2得到前景图 F3
4. 形态学处理
‘贰’ 帧间差分法的结束语
实验表明.利用背景差分和帧间差分让改进后的视频运动目标检测算法,对视频图像像序列中的运动物体检有更好的效果,并且运算速度快。应该看到,改进后的算法要求背景与运动物体的对比度大于5%以上,才能检测出移动的物体。同时,差分法中存在的些缺点仍然没有得到解决,这些问题还有待进步研究。
‘叁’ OpenCV三帧差法
你的程序片段太少了啊。能不能多贴一点,包括变量的完整定义初始化等等。这么一段不好看懂啊
如果嫌麻烦,推荐看一下<<learning opencv>>。书里面比较详细。
检测常用的帧间差分法,书中都有介绍。买一本或者下个电子版看看吧。
电子版下载地址:
http://ishare.iask.sina.com.cn/f/6667035.html
‘肆’ 什么叫三帧差分法
3帧图像做两次差,再相与,求同存异,得到前景,最后向台下处理,得了。
‘伍’ 帧间差分法能进行火灾图像识别吗
三帧差分算法是相邻两帧差分算法的一种改进方法,它选取连续三帧视频图像进行差分运算,消除由于运动而显露背景影响,从而提取精确的运动目标轮廓信息。该算法的基本原理是是先选取视频图像序列中连续三帧图像并分别计算相邻两帧的差分图像,然后将差分图像通过选取适当的阈值进行二值化处理,得到二值化图像,最后在每一个像素点得到的二值图像进行逻辑与运算,获取共同部分,从而获得运动目标的轮廓信息。 三帧差法的具体算法如下。 提取连续的三帧图像,I(k-1),I(k),I(k+1) 。 (1) d(k,k-1) [x,y] = I(k)[x,y] - I(k-1)[x,y] ; d(k,k+1)[x,y] = I(k+1)[x,y] - I(k)[x,y] ; (2) b(k,k-1)[x,y] = 1; if d(k,k-1) [x,y] >= T; b(k,k-1)[x,y] = 0; if d(k,k-1) [x,y] < T; b(k+1,k)[x,y] = 1 if d(k+1,k) [x,y] >= T; b(k+1,k)[x,y] = 0 if d(k+1,k) [x,y] < T; (3) B(k)[x,y] = 1 ; if b(k,k-1)[x,y] && b(k+1,k)[x,y] == 1 ; B(k)[x,y] = 0 ; if b(k,k-1)[x,y] && b(k+1,k)[x,y] ==0 ; 比较关键的就是第2步的阈值T的选取问题,单纯用otsu算法分割貌似效果不太好,如果手动设置一个较小的值(如10)效果还行。 用otsu取阈值实现的一个三分差法代码。效果不是很好。 运行环境 VS2008+OpenCV2.0+windows XP . [cpp] view plainprint?#include “highgui.h” #include “cv.h” #include “cxcore.h” #include “cvaux.h” #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <vector> #include <windows.h> using namespace std; #pragma comment(lib, “highgui200.lib”) #pragma comment(lib, “cv200.lib”) #pragma comment(lib, “cxcore200.lib”) #pragma comment(lib, “cvaux200.lib”) #define GET_IMAGE_DATA(img, x, y) ((uchar*)(img->imageData + img->widthStep * (y)))[x] int T = 10; int Num[300]; int Sum[300]; void InitPixel(IplImage * img, int &_low, int &_top) { memset(Num,0,sizeof(Num)); memset(Sum,0,sizeof(Sum)); _low = 255; _top = 0; for(int i = 0;i < img->height;i++) { for(int j = 0;j < img->width;j++) { int temp = ((uchar*)(img->imageData + img->widthStep*i))[j]; if(temp < _low) _low = temp; if(temp > _top) _top = temp; Num[temp] += 1; } } for(int i = 1 ; i < 256 ; i++) { Sum[i] = Sum[i-1]+ i*Num[i]; Num[i] += Num[i-1]; } } int otsu (IplImage *img) { int _low,_top,mbest=0; float mn = img->height*img->width; InitPixel(img,_low,_top); float max_otsu = 0; mbest = 0; if( _low == _top) mbest = _low; else { for(int i = _low; i< _top ; i++) { float w0 = (float)((Num[_top]-Num[i]) / mn); float w1 = 1 - w0; float u0 = (float)((Sum[_top]-Sum[i])/(Num[_top]-Num[i])); float u1 = (float)(Sum[i]/Num[i]); float u = w0*u0 + w1*u1; float g = w0*(u0 - u)*(u0 - u) + w1*(u1 - u)*(u1 - u); if( g > max_otsu) { mbest = i; max_otsu = g; } } } return mbest; } int main() { int ncount=0; IplImage *image1=NULL; IplImage *image2=NULL; IplImage *image3=NULL; IplImage *Imask =NULL; IplImage *Imask1=NULL; IplImage *Imask2=NULL; IplImage *Imask3=NULL; IplImage *mframe=NULL; CvCapture *capture = cvCreateFileCapture(“E:\\Motion\\IndoorGTTest2.avi”); //CvCapture *capture = cvCreateCameraCapture(0); cvNamedWindow(“src”); cvNamedWindow(“dst”); cvNamedWindow(“Imask1”); cvNamedWindow(“Imask2”); cvNamedWindow(“Imask3”); //cvCreateTrackbar(“T”,“dst”,&T,255,0); while(mframe=cvQueryFrame(capture)) { DWORD start=GetTickCount(); if(ncount>1000000000) ncount=100; ncount+=1; if(ncount==1) { image1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1); image2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1); image3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1); Imask =cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1); Imask1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1); Imask2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1); Imask3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1); cvCvtColor(mframe,image1,CV_BGR2GRAY); } if(ncount==2) cvCvtColor(mframe,image2,CV_BGR2GRAY); if(ncount>=3) { if(ncount==3) cvCvtColor(mframe,image3,CV_BGR2GRAY); else { cvCopy(image2,image1); cvCopy(image3,image2); cvCvtColor(mframe,image3,CV_BGR2GRAY); } cvAbsDiff(image2,image1,Imask1); cvAbsDiff(image3,image2,Imask2); //cvShowImage(“Imask1”,Imask1); //cvShowImage(“Imask2”,Imask2); int mbest1 = otsu(Imask1); cvSmooth(Imask1, Imask1, CV_MEDIAN); cvThreshold(Imask1,Imask1,mbest1, 255, CV_THRESH_BINARY); int mbest2 = otsu(Imask2); cvSmooth(Imask2,Imask2, CV_MEDIAN); cvThreshold(Imask2,Imask2,mbest2, 255, CV_THRESH_BINARY); cout《mbest1《“ ”《mbest2《endl; cvAnd(Imask1,Imask2,Imask); /*cvErode(Imask, Imask); cvDilate(Imask,Imask);*/ DWORD finish=GetTickCount(); // cout《finish-start《“ms”《endl; cvShowImage(“src”,image2); cvShowImage(“dst”,Imask); } char c = cvWaitKey(30); if(c==27) break; } return 0; }
‘陆’ 帧间差分法的分法介绍
帧间差分法的优点是:算法实现简单,程序设计复杂度低;对光线等场景变化不太敏感,能够适应各种动态环境,稳定性较好。其缺点是:
不能提取出对象的完整区域,只能提取出边界;同时依赖于选择的帧间时间间隔。对快速运动的物体,需要选择较小的时间间隔,如果选择不合适,当物体在前后两帧中没有重叠时,会被检测为两个分开的物体:而对慢速运动的物体,应该选择较大的时间差,如果时间选择不适当,当物体在前后两帧中几乎完全重叠时,则检测不到物体。 鉴于背景差分法和帧间差分法的优缺点,我们将这两种方法结合起来,使它们优势互补,从而克服相互的弱点,提高运动检测的效果。但是在实际的场景中,即便是室内环境,也存在光线等各种变化造成的干扰,或者人为造成的开灯等光线的强烈变化。所以在背景差分法的实现中,它的固定背景不能一成不变。如果不进行重新初始化,错误的检测结果将随时间不断累计,造成恶性循环,从而造成监控失效。因此,我们在提出检测算法的同时,要建立背景更新模型。保证背景图像能随着光线的变化而变化,确保检测的准确性。
提出新算法的思想
在视频图像序列中,利用已有的背景差分法和帧间差分法作为启示,将动态图像中连续两帧差图像和背景差图像直接进行与操作,再将结果进行二值化处理得到运动结果。这样就达到了加大目标信息的权重,同时抑制了静态背景的效果,得到的运动检测图像包含了更多目标的信息,不仅包含目标轮廓而且还有目标轮廓内的目标相关点,从而将运动目标从背景图像中分离出来,最终得到视频序列图像中运动存在与否的二值化图像。
‘柒’ 帧间差分法的详细原理及讲解
帧间差分法是一种通过对视频图像序列中相邻两帧作差分运算来获得运动目标轮廓的方法,它可以很好地适用于存在多个运动目标和摄像机移动的情况。
‘捌’ 帧间差分法的简介
当监控场景中出现异常物体运动时,帧与帧之间会出现较为明显的差别,两帧相减,得到两帧图像亮度差的绝对值,判断它是否大于阈值来分析视频或图像序列的运动特性,确定图像序列中有无物体运动。图像序列逐帧的差分,相当于对图像序列进行了时域下的高通滤波。
‘玖’ 帧间差分法的算法描述
(l)、对序列图像进行3×3中值滤波预处理,去掉图像随机噪声。减少以后运算的复杂度,克服噪声对图像处理结果的干扰。
(2)、从视频图像序列中选取出背景图像所阢砂,使其只包含固定的背景图像:
(3)、在视频图像序列中选取连续的两帧图像,其中前一帧图像pk-1(x,y),当前帧图像pk(x,y);
(4)、计算当前帧与背景帧的差得FD(x,y),从 图像中提取出完整的目标;
(5)、计掉当前1帧的差得FG(x,y),得到目标的变化量;
(6)、求帧差FD(x,y)与,FG(x,y)的交集得到运动目标粗糙的运动区域幽像,
(7)、数学形态学运算使得运动区域封毕、连续、完整,并去掉背持中的噪声。
其中:(略)