精华内容
下载资源
问答
  • 三个不同场景下的遗留物视频,一个室内视频,(不同种类颜色物品的遗留物测试视频),一个半露天视频,一个火车站的遗留物检测视频。是专门用于遗留物检测用的视频
  • 本项目是利用opencv249在vs2010中的控制台程序,运行会弹出文件选择框选择需要检测的视频,主要功能是实现遗留物检测(静止目标检测)。
  • 基于帧间差分和边缘差分的遗留物检测算法基于帧间差分和边缘差分的遗留物检测算法基于帧间差分和边缘差分的遗留物检测算法基于帧间差分和边缘差分的遗留物检测算法
  • 遗留物检测

    2017-10-30 10:12:55
    一个可用的遗留物检测程序,主要是使用了混合高斯法GMM
  • 针对一般遗留物检测算法复杂度高和跟踪效果不理想的问题,提出了一种基于码本模型和压缩跟踪算法相结合的遗留物检测方法。首先通过码本模型建模和适时匹配背景更新算法来获取静止目标区域信息;然后利用稀疏测量矩阵对...
  • 针对目前在遗留物检测方面所存在的检测范围小、误检率过高和无法捕捉到遗留物放置者等问题,设计了一种基于全方位计算机视觉的遗留物检测系统;
  • 遗留物检测算法及实现

    万次阅读 2014-04-07 18:31:20
    从最终实现的角度来看,说不上是遗留物检测,至多是静止目标检测【运动物体长时间滞留检测】。实验室同学搞毕业设计,帮忙弄弄,也没弄成。  本文将分别给出老外论文+对应的代码【在老外论文基础上改进的】和国内...

            从最终实现的角度来看,说不上是遗留物检测,至多是静止目标检测【运动物体长时间滞留检测】。实验室同学搞毕业设计,帮忙弄弄,也没弄成。

             本文将分别给出老外论文+对应的代码【在老外论文基础上改进的】和国内的论文+代码【失败,能力不行】。总体思路都是帧间差分法,没有用sift特征匹配或者在线学习。

    算法一:

    《An abandoned object detection system based on dual backgroundsegmentation》 IEEE 2009

    搞了两个背景缓冲区:

    Current_background:初始为第一帧,其后对每个像素,若下一帧像素大于该背景像素,则该出背景像素加1,否则该处背景像素减1。【挺神奇的,好处是This way, even if the foreground ischanging at a fast pace, it will not affect the background but if theforeground is stationary, it gradually merges into the background.但是效果还是不及混合高斯,因为适应期太长太频繁了】

     Buffer_background:论文上说每隔20秒更新一次,直接拷贝Current_background,遗留物检测直接通过Current_background和Buffer_background相减即可。【他这边认为一个遗留物丢弃满20秒,如果还在,则认为该遗留物为背景了】。随后,搞了一堆跟踪该区域的东西,我不太感兴趣。

     本文对上述的改进的目标是物体如果被遗弃了,那么它就应该一直被检测到。我额外搞了一个遗弃背景模版abandon_background,用于记录遗弃物之前的背景图像。

    A.若物体离开,则abandon相应区域恢复到当前current的值,buffer更新为当前整个current。B.若物体未离开,则用abandon对buffer局部更新


    整体算法:

    1.      第一帧,用来初始化Current_background和Buffer_background

    2.      通过两个背景区域计算遗留物

    3.      每一帧更新Current_background

    4.      若时间间隔满足,更新Buffer_background和遗弃物背景abandon_background,更新计数器

       a.      若遗弃物背景首次更新,根据current和buffer之差,在相应的地方赋current的值,其余为0

       b.      进行物体离开判断,即:若abandon与current对应区域背景像素不同,则物体还未离开,否则离开

       c.      若物体离开,将current更新abandon的相应区域,buffer复制完整的current

       d.      若物体未离开,将abandon更新buffer的相应区域,abandon保持不变。

    5.      读取下一帧,返回2


    代码:

    调用的函数:

    #include "Model.h"
    #define Th 50
    #define Ta 90
    
    int first_update = 0;//首次更新标志
    
    void calc_fore(IplImage *current,IplImage *back,IplImage *fore)
    {
    	int i,j;
    
    	for (i=0;i<current->height;i++)
    	{
    		for (j=0;j<current->width;j++)
    		{
    			if (abs((u_char)current->imageData[i*current->widthStep+j] - (u_char)back->imageData[i*current->widthStep+j]) <=Ta )
    			{
    				fore->imageData[i*current->widthStep+j] = 0;//background
    			}else
    			{
    				fore->imageData[i*current->widthStep+j] = 255;//foreground
    			}
    		}
    	}
    }
    
    void update_currentback(IplImage *current,IplImage *curr_back)
    {
    	int i,j;
    	int p,q;
    
    	for (i=0;i<current->height;i++)
    	{
    		for (j=0;j<current->width;j++)
    		{
    			p = (u_char)current->imageData[i * current->widthStep + j];
    			q = (u_char)curr_back->imageData[i * current->widthStep + j];
    			//printf("%d,%d\n",p,q);
    
    			if (p >= q)
    			{
    				if (q == 255)
    				{
    					q = 254;
    				}
    				curr_back->imageData[i * current->widthStep + j] = q + 1;
    			}else
    			{
    				if (q == 0)
    				{
    					q = 1;
    				}
    				curr_back->imageData[i * current->widthStep + j] = q - 1;
    			}
    		}
    	}
    }
    
    void update_bufferedback(IplImage *curr_back,IplImage *buf_back,IplImage *abandon)
    {
    	int i,j,height,width;
    	int leave_flag = 0;
    	
    	height = curr_back->height;
    	width = curr_back->widthStep;
    
    	if (first_update == 0)
    	{
    		for ( i = 0;i < height; i++)
    		{
    			for (j = 0;j < width; j++)
    			{
    				if (abs((u_char)curr_back->imageData[i*width+j] - (u_char)buf_back->imageData[i*width+j]) <=Th )
    				{
    					abandon->imageData[i*width+j] = 0;//background
    				}else
    				{
    					abandon->imageData[i*width+j] = curr_back->imageData[i*width+j];//foreground
    					first_update = 1;
    				}
    			}
    		}
    		return;
    	}
    
    	//物体离开判断
    	for ( i = 0;i < height; i++)
    	{
    		for (j = 0;j < width; j++)
    		{
    			if (abandon->imageData[i*width+j] != 0)
    			{
    				if (abandon->imageData[i*width+j] != curr_back->imageData[i*width+j])
    				{
    					leave_flag = 1;					//物体掩膜处之前背景与当前的不一致,1:物体未离开,0:物体离开
    				}
    			}
    		}
    	}
    	
    	if(leave_flag == 0)		//物体离开
    	{
    		cvCopy(curr_back,buf_back);
    		for ( i = 0;i < height; i++)
    		{
    			for (j = 0;j < width; j++)
    			{
    				if (abandon->imageData[i*width+j] != 0)
    				{
    					abandon->imageData[i*width+j] = curr_back->imageData[i*width+j];
    				}
    			}
    		}
    	}else
    	{
    		for ( i = 0;i < height; i++)
    		{
    			for (j = 0;j < width; j++)
    			{
    				if (abandon->imageData[i*width+j] != 0)
    				{
    					buf_back->imageData[i*width+j] = abandon->imageData[i*width+j];
    				}
    			}
    		}
    	}
    	
    
    }

    主函数:

    // abandon_left.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "Model.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	CvCapture *capture=cvCreateFileCapture("test.avi");
    	IplImage *current_back,*buff_back,*abandon,*frame,*current_img,*fore;
    	int count,intern;
    
    	frame = cvQueryFrame(capture);
    	fore = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	current_back = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	current_img = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	buff_back = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	abandon = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    
    	count=0;
    	intern = count + 20;
    	
    	while (1)
    	{
    		cvCvtColor(frame,current_img,CV_RGB2GRAY);
    
    		if (count == 0)
    		{
    			//初始化背景模版
    			cvCopy(current_img,current_back);
    			cvCopy(current_img,buff_back);
    		}
    
    		if (count > 0)
    		{
    			//计算前景掩膜
    			calc_fore(current_back,buff_back,fore);
    
    			//更新跟踪背景
    			update_currentback(current_img,current_back);
    
    			if (count == intern)
    			{
    				update_bufferedback(current_back,buff_back,abandon);
    				intern = count + 20;
    			}
    			cvShowImage("current",current_img);
    			cvShowImage("current_back",current_back);
    			cvShowImage("buff_back",buff_back);
    			cvShowImage("abandon detection",fore);
    		}
    
    		count++;
    		frame =cvQueryFrame(capture);
    
    		if (cvWaitKey(23)>=0)
    		{
    			break;
    		}
    	}
    	cvNamedWindow("current",0);
    	cvNamedWindow("buff_back",0);
    	cvNamedWindow("current_back",0);
    	cvNamedWindow("abandon detection",0);
    	cvReleaseCapture(&capture);
    	return 0;
    }
    

    效果图:




    说明:左下角有个女的运动规律也符合静止目标检测规律,所以也被检测出来了。后期可以通过外接矩形长宽比等其他手段过滤掉。

    视频+代码工程的下载连接:http://download.csdn.net/detail/jinshengtao/7157943


    算法二:

    《一种基于双背景模型的遗留物检测方法》

    搞了个脏背景和纯背景,定义:

    当视频场景中不出现运动目标,或者背景不受场景中所出现的运动目标影响时,这样的背景称为纯背景。否则,称为脏背景

    它们的更新规则:

    一般背景的更新按照帧间差分法:


    脏背景使用全局更新,直接赋值一般背景:


    纯背景根据前景掩膜,进行局部更新,即若前景掩膜被标记为运动的部分,则相应的纯背景区域用上一帧的纯背景更新;若前景掩膜被标记为非运动的部分,则相应的纯背景区域用当前帧的一般背景更新。


    静止目标前景检测算法可以通过以下公式看明白:


    具体算法流程不给咯,论文没提,自己摸索的,反正试验效果失败了。

    代码:

    // left_bag.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "cv.h"
    #include "highgui.h"
    #define u_char unsigned char
    #define alfa 0.03
    #define Th 60
    #define Ta 60
    #define Tb 40
    
    void calc_fore(IplImage *current,IplImage *back,IplImage *fore)
    {
    	int i,j;
    
    	for (i=0;i<current->height;i++)
    	{
    		for (j=0;j<current->width;j++)
    		{
    			if (abs((u_char)current->imageData[i*current->widthStep+j] - (u_char)back->imageData[i*current->widthStep+j]) <=Th )
    			{
    				fore->imageData[i*current->widthStep+j] = 0;//background
    			}else
    			{
    				fore->imageData[i*current->widthStep+j] = 255;//foreground
    			}
    		}
    	}
    }
    
    void update_back(IplImage *current,IplImage *back,IplImage *B_p,IplImage *B_d,IplImage *fore,IplImage *B_p_pre)
    {
    	int i,j;
    
    	//更新B_n
    	for (i=0;i<current->height;i++)
    	{
    		for (j=0;j<current->width;j++)
    		{
    			back->imageData[i*current->widthStep+j] = (1-alfa)*current->imageData[i*current->widthStep+j] + alfa * back->imageData[i*current->widthStep+j];		
    		}
    	}
    
    	//更新B_d
    	cvCopy(back,B_d);
    	
    	//更新B_p
    	for (i = 0;i < fore->height;i++)
    	{
    		for (j = 0;j < fore->width;j++)
    		{
    			if ((unsigned char)fore->imageData[i*fore->widthStep + j ] == 255)
    			{
    				B_p->imageData[i*fore->widthStep + j] = B_p_pre->imageData[i*fore->widthStep + j];
    			}else
    			{
    				B_p->imageData[i*fore->widthStep + j] = back->imageData[i*fore->widthStep + j];
    			}
    		}
    	}
    }
    
    void calc_StaticTarget(IplImage *current,IplImage *B_d,IplImage *B_p,IplImage *M_s,IplImage *M_m,IplImage *M_f)
    {
    	int i,j;
    
    	for (i = 0;i < current->height;i++)
    	{
    		for (j = 0;j < current->width;j++)
    		{
    			if (abs((u_char)current->imageData[i*current->widthStep+j] - (u_char)B_d->imageData[i*current->widthStep+j]) <= Th )
    			{
    				M_s->imageData[i*current->widthStep+j] = 255;
    			}else
    			{
    				M_s->imageData[i*current->widthStep+j] = 0;
    			}
    
    			if (abs((u_char)B_p->imageData[i*current->widthStep+j] - (u_char)B_d->imageData[i*current->widthStep+j]) > Tb)
    			{
    				M_m->imageData[i*current->widthStep+j] = 255;
    			}else
    			{
    				M_m->imageData[i*current->widthStep+j] = 0;
    			}
    
    			if (((unsigned char)M_m->imageData[i*current->widthStep+j] == 255) &&((unsigned char)M_s->imageData[i*current->widthStep+j] == 255))
    			{
    				M_f->imageData[i*current->widthStep+j] = 255;
    			}else
    			{
    				M_f->imageData[i*current->widthStep+j] = 0;
    			}
    		}
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	CvCapture *capture=cvCreateFileCapture("test.avi");
    	IplImage *frame,*current_img,*B_n,*B_p,*B_d,*B_p_pre;
    	IplImage *M,*M1,*M_s,*M_m,*M_f;
    	int count,i,j;
    
    	frame = cvQueryFrame(capture);
    	current_img = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	B_n = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	B_p = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	B_d = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	B_p_pre = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    
    	M = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	M1 = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	M_s = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	M_m = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    	M_f = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
    
    	count=0;
    	while (1)
    	{
    		cvCvtColor(frame,current_img,CV_RGB2GRAY);
    
    		if (count == 0)
    		{
    			//初始化各种背景模版
    			cvCopy(current_img,B_n);
    			cvCopy(current_img,B_p);
    			cvCopy(current_img,B_d);
    			cvCopy(current_img,B_p_pre);
    		}
    
    		if (count > 1)
    		{
    			//计算前景掩膜
    			calc_fore(current_img,B_n,M1);
    
    			//膨胀腐蚀操作
    			cvDilate(M1, M, 0, 1);
    			cvErode(M, M1, 0, 2);
    			cvDilate(M1, M, 0,1);	
    
    			//静止目标检测
    			calc_StaticTarget(current_img,B_d,B_p,M_s,M_m,M_f);
    
    			//更新跟踪背景
    			update_back(current_img,B_n,B_p,B_d,M,B_p_pre);
    
    			cvShowImage("pure ground",B_p);
    			cvShowImage("dirty ground",B_d);
    			cvShowImage("static target",M_f);
    			cvShowImage("fore ground",M);
    			cvCopy(B_p,B_p_pre);
    		}
    
    		count++;
    		frame =cvQueryFrame(capture);
    		
    
    		if (cvWaitKey(23)>=0)
    		{
    			break;
    		}
    	}
    	cvNamedWindow("pure ground",0);
    	cvNamedWindow("dirty ground",0);
    	cvNamedWindow("static target",0);
    	cvNamedWindow("fore ground",0);
    	cvReleaseCapture(&capture);
    	return 0;
    }
    

    算法三【MATLAB toolbox中的一个demo】

    理论部分没看,在控制台直接输入:edit videoabandonedobj 会有相应的代码跳出来。

    在help中搜索Abandoned Object Detection,会有理论部分介绍

    视频素材下载地址:http://www.mathworks.cn/products/viprocessing/vipdemos.html

    代码:【2010b 版本可跑】

    clc;
    clear;
    
    status = videogetdemodata('viptrain.avi');
    if ~status
        displayEndOfDemoMessage(mfilename);
        return;
    end
    
    roi = [80 100 240 360];
    % Maximum number of objects to track
    maxNumObj = 200;
    % Number of frames that an object must remain stationary before an alarm is
    % raised
    alarmCount = 45;
    % Maximum number of frames that an abandoned object can be hidden before it
    % is no longer tracked
    maxConsecutiveMiss = 4;
    % Maximum allowable change in object area in percent
    areaChangeFraction = 15;
    % Maximum allowable change in object centroid in percent
    centroidChangeFraction = 20;
    % Minimum ratio between the number of frames in which an object is detected
    % and the total number of frames, for that object to be tracked.
    minPersistenceRatio = 0.7;
    % Offsets for drawing bounding boxes in original input video
    PtsOffset = int32(repmat([roi(1); roi(2); 0 ; 0],[1 maxNumObj]));
    
    hVideoSrc = video.MultimediaFileReader;
    hVideoSrc.Filename = 'viptrain.avi';
    hVideoSrc.VideoOutputDataType = 'single';
    
    hColorConv = video.ColorSpaceConverter;
    hColorConv.Conversion = 'RGB to YCbCr';
    
    hAutothreshold = video.Autothresholder;
    hAutothreshold.ThresholdScaleFactor = 1.3;
    
    hClosing = video.MorphologicalClose;
    hClosing.Neighborhood = strel('square',5);
    
    hBlob = video.BlobAnalysis;
    hBlob.MaximumCount = maxNumObj;
    hBlob.NumBlobsOutputPort = true;
    hBlob.MinimumBlobAreaSource = 'Property';
    hBlob.MinimumBlobArea = 100;
    hBlob.MaximumBlobAreaSource = 'Property';
    hBlob.MaximumBlobArea = 2500;
    hBlob.ExcludeBorderBlobs = true;
    
    hDrawRectangles1 = video.ShapeInserter;
    hDrawRectangles1.Fill = true;
    hDrawRectangles1.FillColor = 'Custom';
    hDrawRectangles1.CustomFillColor = [1 0 0];
    hDrawRectangles1.Opacity = 0.5;
    
    hDisplayCount = video.TextInserter;
    hDisplayCount.Text = '%4d';
    hDisplayCount.Color = [1 1 1];
    
    hAbandonedObjects = video.VideoPlayer;
    hAbandonedObjects.Name = 'Abandoned Objects';
    hAbandonedObjects.Position = [10 300 roi(4)+25 roi(3)+25];
    
    hDrawRectangles2 = video.ShapeInserter;
    hDrawRectangles2.BorderColor = 'Custom';
    hDrawRectangles2.CustomBorderColor = [0 1 0];
    
    hDrawBBox = video.ShapeInserter;
    hDrawBBox.BorderColor = 'Custom';
    hDrawBBox.CustomBorderColor = [1 1 0];
    
    hAllObjects = video.VideoPlayer;
    hAllObjects.Position = [45+roi(4) 300 roi(4)+25 roi(3)+25];
    hAllObjects.Name = 'All Objects';
    
    hDrawRectangles3 = video.ShapeInserter;
    hDrawRectangles3.BorderColor = 'Custom';
    hDrawRectangles3.CustomBorderColor = [0 1 0];
    
    hThresholdDisplay = video.VideoPlayer;
    hThresholdDisplay.Position = ...
                [80+2*roi(4) 300 roi(4)-roi(2)+25 roi(3)-roi(1)+25];
    hThresholdDisplay.Name = 'Threshold';
    
    firsttime = true;
    while ~isDone(hVideoSrc)
        Im = step(hVideoSrc);
    
        % Select the region of interest from the original video
        OutIm = Im(roi(1):end, roi(2):end, :);
    
        YCbCr = step(hColorConv, OutIm);
        CbCr  = complex(YCbCr(:,:,2), YCbCr(:,:,3));
    
        % Store the first video frame as the background
        if firsttime
            firsttime = false;
            BkgY      = YCbCr(:,:,1);
            BkgCbCr   = CbCr;
        end
        SegY    = step(hAutothreshold, abs(YCbCr(:,:,1)-BkgY));
        SegCbCr = abs(CbCr-BkgCbCr) > 0.05;
    
        % Fill in small gaps in the detected objects
        Segmented = step(hClosing, SegY | SegCbCr);
    
        % Perform blob analysis
        [Area, Centroid, BBox, Count] = step(hBlob, Segmented);
    
        % Call the helper function that tracks the identified objects and
        % returns the bounding boxes and the number of the abandoned objects.
        [OutCount, OutBBox] = videoobjtracker(Area, Centroid, BBox, Count,...
           areaChangeFraction, centroidChangeFraction, maxConsecutiveMiss, ...
           minPersistenceRatio, alarmCount);
    
        % Display the abandoned object detection results
        Imr = step(hDrawRectangles1, Im, OutBBox+PtsOffset);
        Imr(1:15,1:30,:) = 0;
        Imr = step(hDisplayCount, Imr, OutCount);
        step(hAbandonedObjects, Imr);
    
        % Display all the detected objects
        Imr = step(hDrawRectangles2, Im, BBox+PtsOffset);
        Imr(1:15,1:30,:) = 0;
        Imr = step(hDisplayCount, Imr, OutCount);
        Imr = step(hDrawBBox, Imr, roi);
        step(hAllObjects, Imr);
    
        % Display the segmented video
        SegIm = step(hDrawRectangles3, repmat(Segmented,[1 1 3]), BBox);
        step(hThresholdDisplay, SegIm);
    end
    
    release(hVideoSrc);

    虽然不是自己的研究方向,但也算尝试了吧。马上快答辩咯,攒个人品先~

    展开全文
  • 遗留物或搬移物检测是智能视频监控中的一项基本功能,基本上是智能视频监控领域的必备功能。然而,在实际应用中漏报或误判率依然很高。常见的遗留物或搬移物检测算法主要分为两类,一类是先检测,再根据检测前景在...

       

    智能视频监控中的遗留物或搬移物检测

    kezunhai@gmail.com

    http://blog.csdn.net/kezunhai

          

           遗留物或搬移物检测是智能视频监控中的一项基本功能,基本上是智能视频监控领域的必备功能。然而,在实际应用中漏报或误判率依然很高。常见的遗留物或搬移物检测算法主要分为两类,一类是先检测,再根据检测前景在场景中的停留时间来判定是否为遗留物或搬移物;另一类,则是先检测,然后采用跟踪方法来判断是否为遗留物或搬移物,该类方法由于目标跟踪本身存在的难点,在实际应用的场景受到了很大的限制。因此本文主要介绍第一类方法。

           在第一类方法中,常用的是双背景模型,有些文献又称为短时背景和长时背景(short term background and long term background),国内找到的文献基本是延续这一思想,没什么新意,建议研究或做这块的朋友留意国外的资料。下图是来自文献3:


            在遗留物检测这块,经常遇到的问题有:

             1)突然光照的变化

             突然光照的变化对遗留物的检测其实影响不到,主要影响的是检测到的前景。根据双背景模型建立的背景模型来进行遗留物检测,可以在一定程度上减少光照的影响。

            2)遗留物和搬移物的判断

            对遗留物和搬移物的区分是智能视频分析中的基本功能,因此对于检测到的静态目标块,怎么区分是遗留物还是搬移物呢?常用的做法是采用边缘自相关、和颜色直方图相关,以及文献3提出的向外围通胀。个人观点,边缘自相关和颜色直方图相关是比较不错的,边缘自相关对外背景比较杂乱的效果不如颜色直方图相关。当然,为了增强直方图的可分辨性,可以采用直方图的变体。在实践中,中心加权的直方图在区分遗留物和搬移物方面的效果不错,基本上可以达到90%以上的正确区分。

           3)遗留物和搬移物的跳跃

            在监控过程中,检测到的静态库可能会出现遗留和搬移的跳变(即同一物体时而是遗留物、时而是搬移物)。解决这个问题的方法其实很简单:通过对状态进行记录,采用投票法来决定到底是遗留物还是搬移物,也即,同一静态块,以标记状态次数为多的为最终目标快(比如,同一静止块,标记为遗留的次数为4,标记为搬移的次数为2,则最终状态为2)。

          4)静态块的闪烁处理

           对于由于风吹和树叶、摇头的风扇等,由于在场景中也会长时间的被检测为前景,当做静止块来处理。对于该种情况,可以通过统计该块的均值和方差以及长宽比来进一步确认。通常可以假设,对于遗留物或搬移物,其多为刚体结构,均值、方差和长宽比不会发生很大的变化。采用这种处理,可以去掉很大一部分的误判和干扰。 

          另外,如果采用跟踪的方法,可以进一步减少遗留物或搬移物的误判率(这些遗留物或搬移物不会自己到这里来,一般会伴随着运动目标,将静止块与附近的运动目标进行关联,可以提高检测精度)。



    推荐资料:
    1、Abandoned Objects Detection in Video Surveillance System A Survey
    2、left-object deteection through background modelling(ColorModel 和Texture Model(均值与周围像素比得Bitmap)
    3、Real time detection of abandoned and removed objects in complex environment
    4、robust detection of abandoned and removed objects in complex surveillance videos
    5、An abandoned object detection system based on dual background segmentation --Singh

    6、基于改进混合高斯建模和短时稳定度的遗留物检测算法
    7、视频监控场景中的遗留物检测研究与实现_周金旺


    可以猛戳下载: 遗留物或搬移物检测相关资料

    作者: kezunhai  出处: http://blog.csdn.net/kezunhai  欢迎转载或分享,但请务必声明文章出处。
        
    展开全文
  • 基于全方位计算机视觉的遗留物检测系统.pdf
  • Abandoned Object Detection via Temporal Consistency Modeling and Back-Tracing Verification for Visual Surveillance 摘要 本文提出了在监控视频下的遗留物检测算法,作者把long-term 和 short-term的背景模型...

    Abandoned Object Detection via Temporal Consistency Modeling and Back-Tracing Verification for Visual Surveillance

    摘要

           本文提出了在监控视频下的遗留物检测算法,作者把long-term 和 short-term的背景模型结合在监控视频视频中提取前景目标。最后对提取的前景目标进行有限状态机(Pixel-Based Finite State Machine )和遗留物主人的轨迹回溯法(Back-Tracing)联合判断前景目标是否为遗留物。

    一、双学习率的背景消除算法( Temporal Dual-rates foreground Integration Method)

    1、双高斯模型的背景消除算法

           背景消除算法用来得出图片的前景物体(foreground), 有限状态机用于判断前景物体是否为遗留物。

    A. 背景建模和模型更新策略

    在这里插入图片描述

    图1:GMM背景建模输出的检测结果

           首先, 需要对监控的视频环境进行建模,使用混合高斯模型GMM对监控的背景进行建模学习监控下的背景信息.混合高斯模型:
    单个多维高斯模型

           一般的高斯模型通过极大似然法来求解最优值(通常根据定义的表示特征需要混合3-5个高斯模型,根据EM算法(极大化Jensen不等式的lower bound)对高斯模型的参数进行学习)。
           但是本文的背景建模的GMM模型的策略采用了Improved Adaptive Gaussian Mixture Model for Background Subtraction文中的GMM学习方式,自适应更新混合高斯模型的个数和高斯模型的参数。其更新方式如下:

    •     1. 初始化一个背景模型 B ( x , y ) B(x,y) B(x,y);其中 ( x , y ) (x,y) (x,y)代表图像的每个像素点, 0 ≤ x ≤ m − 1 , 0 ≤ y ≤ n − 1 0\leq x \leq m-1,0\leq y \leq n-1 0xm1,0yn1
    •     2. 对于一张图像 I t I_{t} It的每个像素点 ( x , y ) (x,y) (x,y),如果 I t ( x , y ) ⊆ B ( x , y ) I_{t}(x,y) \subseteq B(x,y) It(x,y)B(x,y) 就表示图像 I t I_{t} It的像素点 ( x , y ) (x,y) (x,y)属于背景(BG),否则像素点 ( x , y ) (x,y) (x,y)就是图片的前景(FG)。
    •     3. 如果独立的像素点 ( x , y ) (x,y) (x,y)是图片的背景,那么需要把点 I t ( x , y ) I_{t}(x,y) It(x,y)作为训练样本更新我们的背景模型 B ( x , y ) B(x,y) B(x,y)
    •     4. 更新下一张图片 t = t + 1 t = t + 1 t=t+1, 重复步骤2。

           其中通过对步骤3中学习率 λ ∈ [ 0 , 1 ] \lambda\in[0,1] λ[0,1]的调整来控制 λ B \lambda B λB ( 1 − λ ) I t (1-\lambda)I_{t} (1λ)It的偏好。如果 λ \lambda λ的值较小,模型 B B B对新的训练样本 I t I_{t} It的学习速度就很快,高斯模型对新的样本适应很快(当FG物体静止较短时间后GMM就会快速适应,并在接下来识别成背景),反之若 λ \lambda λ的值较大,那么高斯模型对新的样本适应较慢(只有当FG停留很长的时间,模型才能判定其为背景)。

    B. 静止物体检测-----长(Long-Term)短(Short-Term)时双背景建模

    在这里插入图片描述

    图2:长短时背景建模的静止FG物体检测流程

           长短时背景建模的核心就是对GMM模型使用不同的学习率 λ \lambda λ。从之前的对 λ \lambda λ讨论中可以发现GMM模型的学习率越大,模型更新速度越慢,从而对静止的FG物体越不敏感。所以我们把使用小的学习率 λ S \lambda_{S} λS背景模型称为Short-term短时背景模型 B S B_{S} BS,同时其模型输出的二值背景图片记作 F S F_{S} FS。相似的把较大的学习率 λ L \lambda_{L} λL的背景模型称为Long-term长时背景模型 B L B_{L} BL,同时其模型输出的二值背景图片记作 F L F_{L} FL。长短时背景检测模型的结果如图3所示:
    在这里插入图片描述

    图3:Long-term和Short-term背景模型检测结果

           Short-term模型对新的图片的适应性很强会把静止的FG很快分类成BG背景,而Long-term模型对新的图片的适应性很较弱不会立刻把静止FG物体分类成BG信息。而静止的FG物体检测的核心是利用两个模型的输出的差来实现静止FG检测。具体流程如图2所示。对于FG的检测来说long-term长时模型会检测更多的FG信息(最直观的理解:long背景模型物体待的时间越long才是BG背景,short背景模型物体带的时间较短就可以是BG背景)。
           对于一个图片的像素点 i i i,我们定义了 S i S_{i} Si表示当前像素点长短时双背景模型的输出值:

    S i S_{i} Si = F L ( i ) ∗ F S ( i ) = F_{L}(i)*F_{S}(i) =FL(i)FS(i)

    其中, F S ( i ) F_{S}(i) FS(i) F L ( i ) F_{L}(i) FL(i) 都属于[0,1],都表示一个二值的像素点。 对于双背景消除法的输出值 S i S_{i} Si 有四种情况如下表所示:

    S i S_{i} Si像素点 i i i的意义
    00长时模型检测为BG,短时模型检测模型为BG-> 背景像素BG
    01长时模型检测为BG,短时模型检测模型为FG-> 突然暴露的背景像素BG ∗ ^{*}
    10长时模型检测为FG,短时模型检测模型为BG-> 候选的静止FG
    11长时模型检测为FG,短时模型检测模型为FG-> 移动中的FG

    *注(原论文的注释为这个像素点在图像中之前被物体遮挡然后才在接下来的图片中暴露出来, 个人理解:一个FG物体在这个像素点静止了一小会long模型没适应而short适应了即S=1,0,但是时间很短然后就离开了导致S=0, 1)

    2、有限状态机(Pixel-Based FSM)

    在这里插入图片描述

    图4:静止FG物体判断的FSM有限状态机

           对于已经建模好了的双背景模型,其 S i S_{i} Si初始状态主要包含有两个(11,00)。对于静止FG的定义中首先是移动的状态下停下并静止下来一段时间,所以FSM的触发条件为物体都是运动的FG前景 S i = 11 S_{i} = 11 Si=11, 然后物体静止下来状态就需要进入 S i = 10 S_{i} = 10 Si=10。如果物体静止的时间大于 T s T_{s} Ts,则判定其为静止的FG物体。注(如果物体静止的时间较短long没适应:11-10-01-00, 时间满足条件:11-10-00(这个状态下可能包含有遗留物的丢弃和背景捡走过程?);在验证的时候刚丢掉的物体突然被移动的物体遮挡了会不满足FSM)。具体过程见图4。

           综上FSM规则是:如果连续子序列 S i S_{i} Si需要以11为触发状态,然后有足够长的时间序列 S i = 1 , 0 S_{i}=1,0 Si=1,0,我们才能判定这个像素点为静止FG像素点。同时考虑到遗留物的特征,对于检测到的静止FG像素点blobs设置一个阈值,既不能太小,同时不能太小。到此为止才能把检测出来的静止FG作为候选的遗留物信息。

    二、回溯跟踪验证(Back-Tracing Verification)

    在这里插入图片描述

    图5:遗留物主人的跟踪验证

           为了验证静止的FG是否是被遗留的物体还是仅仅放在这边一段时间(之后拿走!)。如果静止的FG物体的丢弃者不再返回到物体附近,那么这个物体就被判断成遗留物。具体的回溯验证流程如下:
           当一个物体或者一个blob在FSM中在 t t t时刻被判定为静止的FG物体后而且在这个FG的周围 D D D的范围内没有移动的物体后(注意这个条件),我们回溯到视频的第 t 0 t_{0} t0帧数( t 0 = t − T s t_{0}=t-T_{s} t0=tTs)并假设在这一帧物体被人遗留。在 t 0 t_{0} t0帧的图片上我们创建一个时空范围 W 0 W_{0} W0(spatial-temporal window), W 0 W_{0} W0 t 0 t_{0} t0帧图片的遗留物物体的中心点 p p p为圆心大小为 ( r 2 , δ ) (r^2,\delta ) (r2,δ),其中 r r r为当前图片上的半径 , δ \delta δ为时间范围 [ t 0 , t 0 + δ ] [t_{0},t_{0}+\delta ] [t0,t0+δ]
           对于时空范围 W 0 W_{0} W0我们重新审视在这个范围内的全部FG物体(blob)。我们使用合适的人形状的高宽估计和检测人的算法(Deformable Part Model)在blobs中检测人来判定遗留物的主人。如果在 W 0 W_{0} W0的空间中我们检测到了多个人直接使用离遗留物中心点 p p p最近的人判定其为遗留物的主人并把 W 0 W_{0} W0空间中的这个blob记录为 p 1 p1 p1
           下一步我们利用 p 1 p1 p1为中心再创建一个时空范围 W 1 W_{1} W1其范围也为 ( r 2 , δ ) (r^2,\delta ) (r2,δ)。然后利用我们在 W 0 W_{0} W0中找到的遗留物主人的颜色特征(颜色直方图)在 W 1 W_{1} W1时空范围中blobs寻找最相似的blob(e Bhattacharyya coefficient巴氏系数作为判断依据)。最后找到另一个 p 2 p2 p2创建时空范围 W 2 W_{2} W2。重复上述步骤直到我们找到的时间超过 t t t。完成这些后我们就实现了在 δ \delta δ范围内对遗留物主人的跟踪。优点:更有效的解决人被短暂的遮挡的问题而且由于时间范围的有效性所以该方法也的效率也很高。图5展示了本算法对遗留物主人的跟踪效果。

    之前的文章中验证了双背景消除法检测的遗留物会带来很多的误报,所以本文了提出一种回溯验证的方法,主要是去寻找遗留物的owner的信息来辅助判断。

    三、遗留物事件分析( Abandoned Object Event Analysis)

    在这里插入图片描述

    图5:遗留物时间分析的全部流程

           图5展示了遗留物检测事件的全部流程,一旦遗留物的主人的轨迹被侦测到,然后我们会根据以下连两个规则进行判断然后进行是否报警行为。

           1.时序规则(Temporal rule):一个遗留物被人遗弃时间上要超过 T = 30 s T=30s T=30s以上。否则不算遗留物。通常 T = 30 s T=30s T=30s可以使用 T = 30 f p s T=30fps T=30fps来计算
           2.空间规则(Spatial rule):遗留物的定义是被人给遗留的物体而且遗留物不会被立马捡起来。所以在空间上遗留物和其主人的距离需要达到 D = 3 m D=3m D=3m以上报警事件才会触发。

    展开全文
  • 在智能视频监控系统中,遗留物检测是一个很重要的应用,对遗留物的检测基本上都是采取对前景掩膜对应的背景区域不进行更新,这往往又会导致其他的问题,如背景模型的鲁棒性和对环境的适应性等。而且在对遗留物检测中...

             在智能视频监控系统中,遗留物检测是一个很重要的应用,对遗留物的检测基本上都是采取对前景掩膜对应的背景区域不进行更新,这往往又会导致其他的问题,如背景模型的鲁棒性和对环境的适应性等。而且在对遗留物检测中,如果背景中的物体移除,有时又需要对该移除物体对应的背景区域进行更新。这里介绍一种判断物体是遗留还是移除的检测算法,也可以参考论文“moving object detection,tracking and classification for smart video survleillance”。

           对于标注为遗留或移除的前景区域,取其外接矩形对应的对应的背景区域,记为R,然后将该区域向外围扩展,在背景中取一个包含R区域的区域S,计算这两个区域的颜色均值Ar和As,然后求这两个均值的比值,从而进一步判断物体是遗留还是移除。判断准则如下:

                                                                                  

             如果这两个区域的均值的比值满足上式,则认为该区域是物体移除,需要进一步对该区域对应的背景模型进行更新;否则,就是物体遗留,对该区域对应的背景模型不进行更新。为什么该中判断准则有效呢? 在实际中,场景中的背景趋向于同一化,即同一场景的邻近区域比较相似(在室内的情况更是如此),如果是物体遗留,则会引起场景中背景的较大变化,导致均值的变化,进一步直接影响均值比值的较大变化;而物体的移除,则使得移除物体位置变成场景的本来模样,则其均值与其邻域附近的区域的均值很接近;如此,就可以进一步对场景中的物体遗留和移除进行判断。

          实现代码如下:

    // 返回2表示遗留,1表示移除
    int detectLeftRemove(Mat& background, Rect& rect)
    {	
    	int returnVal = -1;
    	Rect surroundRect;
    	surroundRect.x = std::max(0,rect.x-15); // 外移10个像素
    	surroundRect.y = std::max(0,rect.y-15);
    
    	if ( (surroundRect.y+rect.height+30) > background.rows )	
    		surroundRect.height = background.rows- surroundRect.y;	
    	else
    		surroundRect.height = rect.height+30;
    
    	if ( (surroundRect.x+rect.width+30) > background.cols )	
    		surroundRect.width = background.cols- surroundRect.x;	
    	else
    		surroundRect.width = rect.width+30;	
    	Scalar S1 = mean(background(rect));
    	Scalar S2 = mean(background(surroundRect));
    	double dist1 = norm(S1);
    	double dist2 = norm(S2);
    	double ratio = 0.0;
    	if ( dist1>= dist2 )
    		ratio = dist2/dist1;
    	else
    		ratio = dist1/dist2;
    
    	if (ratio>=0.85 && ratio<=1.0)	// 相近表示离开( Remove )	
    		returnVal = 1;		
    	else	  // 否则表示遗留(Left)	
    		returnVal = 2;	
    	
    	return returnVal;	
    }


       另外,介绍一个实用的矩阵缩放函数:

    Rect scale_rect(const Rect& r, float scale)
    {
       Point2f m=centerRect(r);
       float width  = r.width  * scale;
       float height = r.height * scale;
       int x=cvRound(m.x - width/2);
       int y=cvRound(m.y - height/2);
       return Rect(x, y, cvRound(width), cvRound(height));
    }


     

     

     

    展开全文
  • 在智能视频监控系统中,遗留物检测是一个很重要的应用,对遗留物的检测基本上都是采取对前景掩膜对应的背景区域不进行更新,这往往又会导致其他的问题,如背景模型的鲁棒性和对环境的适应性等。而且在对遗留物检测中...
  • 根据《An abandoned object detection system based on dual background segmentation》,自己写的代码
  • 遗留物检测思路

    千次阅读 2012-04-19 21:39:02
    对于遗留物检测,需要勾勒出其轮廓。 因为在我需要的场景中,背景通常是比较稳定的,只包含一些较小的扰动和一块内容会随时间变化的屏幕。由于是遗留物检测,物体会静止的放置较长时间,所以不希望实时更新背景以免...
  • 这是一些关于遗留物或搬移物检测的经典资料,望对大家有所帮助。
  • 高斯背景检测遗留物 可执行代码 需要自己录入视频
  • 标识出摄像头视频中的移动的物体,光影效果好的时候效果较好,摄像头不能乱动。
  • dsp版遗留物检测基本完工

    千次阅读 2008-05-06 12:54:00
    检测到的目标保存在一个动态序列中,保存了目标的位置、大小、时间信息。在ccs环境下编译通过,又在windows下结合directshow测试了一下,发现几个小bug,其余运转正常。还需要一个智能背景重新学习的模块。以后再说...
  • 智能视频监控中的遗留物或搬移物检测 kezunhai@gmail.com http://blog.csdn.net/kezunhai 遗留物或搬移物检测是智能视频监控中的一项基本功能,基本上是智能视频监控领域的必备功能。然而,在实际应用中漏报...
  • #资源达人分享计划#
  • dsp下的遗留物检测

    千次阅读 2008-04-28 11:01:00
    最近一直在做,本来算法挺复杂,背景学习剔除了运动物体的影响,对遗留目标还用了vector,后来发现内存不够了,只有5M可以用。又一顿改。使用了下采样图像,简化了算法。可是还没有找到一个简单好用的动态数据结构,...
  • 首先利用sift对目标提取特征点,作为之后的判断依据 demo的目的是再一段视频中检测到目标物体。 我们利用了opencv去读取一段视频 利用sift去提取每一帧的特征点,之后进行匹配 起初想去除错检测点,但发现确实...
  • 这一份遗留物品月统计表(参考)适合大家用于学习、参考、借鉴,希望遗留物品月统计表(参考)就是你所需要的...该文档为遗留物品月统计表(参考),是一份很不错的参考资料,具有较高参考价值,感兴趣的可以下载看看
  • 物品遗留与丢失

    2021-02-22 17:33:24
    一是基于背景建模的被盗遗留检测:通过各种不同的方法对监控场景进行背景建模,比如混合高斯模型建模、双学习率的双背景建模等,经过背景建模,再与实时监控比较,找到可疑,通过后续的形态学操作确定准确的目标...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,858
精华内容 743
关键字:

遗留物检测