运动目标检测是指在序列图像中检测出变化区域并将运动目标从背景图像中提取出来。通常情况下,目标分类、跟踪和行为理解等后处理过程仅仅考虑图像中对应于运动目标的像素区域,因此运动目标的正确检测与分割对于后期处理非常重要然而,由于场景的动态变化,如天气、光照、阴影及杂乱背景干扰等的影响,使得运动目标的检测与分割变得相当困难。根据摄像头是否保持静止,运动检测分为静态背景和运运动目标检测是指在序列图像中检测出变化区域并将运动目标从背景图像中提取出来。通常情况下,目标分类、跟踪和行为理解等后处理过程仅仅考虑图像中对应于运动目标的像素区域,因此运动目标的正确检测与分割对于后期处理非常重要然而,由于场景的动态变化,如天气、光照、阴影及杂乱背景干扰等的影响,使得运动目标的检测与分割变得相当困难。根据摄像头是否保持静止,运动检测分为静态背景和运动背景两类。大多数视频监控系统是摄像头固定的,因此静态背景下运动目标检测算法受到广泛关注,常用的方法有帧差法、光流法、背景减除法、 ViBe算法、ViBe+算法等。本文将对算法做概论介绍和优缺点比较。
帧间差分法是将视频流中相邻两帧或相隔几帧图像的两幅图像像素值相减,并对相减后的图像进行阈值化来提取图像中的运动区域。 若相减两帧图像的帧数分别为第k帧, 第(k+1)帧,其帧图像分别为fk(x,y),fk+1(x,y),差分图像二值化阈值为T,差分图像用D(x, y)表示,则帧间差分法的公式如下:
D(x,y)={1,|fk+1(x,y)−fk(x,y)|>T0,others
帧间差分法的优缺点如下:
笔者已经将把源码上传到GitHub网站上,地址如下:
https://github.com/upcAutoLang/BackgroundSplit-OpenCV/tree/master/src/FramesDifference
二帧差值(相邻帧间差分法直接对相邻的两帧图像做差分运算,并取差分运算的绝对值构成移动物体,优点是运算快速,实时性高,缺点是无法应对光照的突变,物体间一般具有空洞)
opencv、c++实现:
#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
using namespace cv;
int main(int argc,char *argv[])
{
VideoCapture videoCap(argv[1]);
if(!videoCap.isOpened())
{
return -1;
}
double videoFPS=videoCap.get(CV_CAP_PROP_FPS); //获取帧率
double videoPause=1000/videoFPS;
Mat framePre; //上一帧
Mat frameNow; //当前帧
Mat frameDet; //运动物体
videoCap>>framePre;
cvtColor(framePre,framePre,CV_RGB2GRAY);
while(true)
{
videoCap>>frameNow;
if(frameNow.empty()||waitKey(2500)==27)
{
break;
}
cvtColor(frameNow,frameNow,CV_RGB2GRAY);
absdiff(frameNow,framePre,frameDet);
framePre=frameNow;
imshow("Video",frameNow);
imshow("Detection",frameDet);
}
return 0;
}
调用了Opencv自带的视频文件“768x576.avi”,视频文件位置:“opencv\sources\samples\gpu”,下图是视频第100帧时图像:
右图是相邻两帧差法检测到的物体,检测效果没有经过膨胀或腐蚀等处理。可以看到物体的轮廓是“双边”的,并且物体的移动速度越快,双边轮廓现象越粗越明显(这是不是给监控中速度检测提供了一个思路~~),另一个就是物体具有较大的空洞。
三帧差法是在相邻帧差法基础上改进的算法,在一定程度上优化了运动物体双边,粗轮廓的现象,相比之下,三帧差法比相邻帧差法更适用于物体移动速度较快的情况,比如道路上车辆的智能监控。
三帧差法基本实现步骤:1. 前两帧图像做灰度差;2. 当前帧图像与前一帧图像做灰度差;3. 1和2的结果图像按位做“与”操作。
opencv、C++实现:
#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
using namespace cv;
int main(int argc,char *argv[])
{
VideoCapture videoCap(argv[1]);
if(!videoCap.isOpened())
{
return -1;
}
double videoFPS=videoCap.get(CV_CAP_PROP_FPS); //获取帧率
double videoPause=1000/videoFPS;
Mat framePrePre; //上上一帧
Mat framePre; //上一帧
Mat frameNow; //当前帧
Mat frameDet; //运动物体
videoCap>>framePrePre;
videoCap>>framePre;
cvtColor(framePrePre,framePrePre,CV_RGB2GRAY);
cvtColor(framePre,framePre,CV_RGB2GRAY);
int save=0;
while(true)
{
videoCap>>frameNow;
if(frameNow.empty()||waitKey(videoPause)==27)
{
break;
}
cvtColor(frameNow,frameNow,CV_RGB2GRAY);
Mat Det1;
Mat Det2;
absdiff(framePrePre,framePre,Det1); //帧差1
absdiff(framePre,frameNow,Det2); //帧差2
threshold(Det1,Det1,0,255,CV_THRESH_OTSU); //自适应阈值化
threshold(Det2,Det2,0,255,CV_THRESH_OTSU);
Mat element=getStructuringElement(0,Size(3,3)); //膨胀核
dilate(Det1,Det1,element); //膨胀
dilate(Det2,Det2,element);
bitwise_and(Det1,Det2,frameDet);
framePrePre=framePre;
framePre=frameNow;
imshow("Video",frameNow);
imshow("Detection",frameDet);
}
return 0;
}
同样是“768x576.avi”视频文件,并且也保存了第100帧的原始图像和运动物体检测图像:
原始帧图像;未经形态学处理的原始的三帧差法检测到的运动物体,未经任何形态学处理的原始的三帧差法检测到的物体的双边轮廓现象有所改善,但同时也有丢失轮廓的现象;最后两个帧差图像按位与操作之前做了一下膨胀处理的效果。
相比相邻两帧差法,原始的三帧差法对物体的双边粗轮廓和“鬼影”现象有所改善,比较适合对运动速度较快物体的检测,但是仍然会有空洞出现,并且物体移动速度较慢时容易丢失轮廓。当然三帧差法做了两次的差分运算,给了三帧差法更多可操作和优化的空间,为更优秀的检测效果提供了可能。
参考网址:
《背景差分法》
《帧间差分法和背景建模法》
背景差分法是一种对静止场景进行运动分割的通用方法,它将当前获取的图像帧与背景图像做差分运算,得到目标运动区域的灰度图,对灰度图进行阈值化提取运动区域,而且为避免环境光照变化影响,背景图像根据当前获取图像帧进行更新。
根据前景检测,背景维持和后处理方法,存在几种不同的背景差方法。若设It,BtIt,Bt分别为当前帧与背景帧图像,T为前景灰度阈值,则其中一种方法流程如下:
背景差分法的优缺点如下:
高斯背景模型 在运动检测中的应用
原理 : 高斯模型就是用高斯概率密度函数(正态分布曲线)精确地量化事物,将一个事物分解为若干的基于高斯概率密度函数(正态分布曲线)形成的模型。
对图像背景建立高斯模型的原理及过程:图像灰度直方图反映的是图像中某个灰度值出现的频次,也可以认为是图像灰度概率密度的估计。如果图像所包含的目标区域和背景区域相比,区域面积较大且区域在灰度上有一定的差异,那么该图像的灰度直方图呈现双峰-谷形状,其中一个峰对应于目标的重心灰度,另一个峰对应于背景的中心灰度。对于复杂的图像,尤其是医学图像,一般是多峰的。通过将直方图的多峰特性看作是多个高斯分布的叠加,可以解决图像的分割问题。
在智能监控系统中,对于运动目标的检测是中心内容,而在运动目标检测提取中,背景目标对于目标的识别和跟踪至关重要。而建模正是背景目标提取的一个重要环节。
我们首先要提起背景和前景的概念,前景是指在假设背景为静止的情况下,任何有意义的运动物体即为前景。建模的基本思想是从当前帧中提取前景,其目的是使背景更接近当前视频帧的背景。即利用当前帧和视频序列中的当前背景帧进行加权平均来更新背景,但是由于光照突变以及其他外界环境的影响,一般的建模后的背景并非十分干净清晰,而高斯混合模型是是建模最为成功的方法之一。
混合高斯模型使用K(基本为3到5个)个高斯模型来表征图像中各个像素点的特征,在新一帧图像获得后更新混合高斯模型, 用当前图像中的每个像素点与混合高斯模型匹配,如果成功则判定该点为背景点, 否则为前景点。 通观整个高斯模型,主要是有方差和均值两个参数决定,对均值和方差的学习,采取不同的学习机制,将直接影响到模型的稳定性、精确性和收敛性 。由于我们是对运动目标的背景提取建模,因此需要对高斯模型中方差和均值两个参数实时更新。为提高模型的学习能力,改进方法对均值和方差的更新采用不同的学习率;为提高在繁忙的场景下,大而慢的运动目标的检测效果,引入权值均值的概念,建立背景图像并实时更新,然后结合权值、权值均值和背景图像对像素点进行前景和背景的分类。
到这里为止,混合高斯模型的建模基本完成,我在归纳一下其中的流程,首先初始化预先定义的几个高斯模型,对高斯模型中的参数进行初始化,并求出之后将要用到的参数。其次,对于每一帧中的每一个像素进行处理,看其是否匹配某个模型,若匹配,则将其归入该模型中,并对该模型根据新的像素值进行更新,若不匹配,则以该像素建立一个高斯模型,初始化参数,代理原有模型中最不可能的模型。最后选择前面几个最有可能的模型作为背景模型,为背景目标提取做铺垫。
方法: 目前,运动物体检测的问题主要分为两类,摄像机固定和摄像机运动。对于摄像机运动的运动物体检测问题,比较著名的解决方案是光流法,通过求解偏微分方程求的图像序列的光流场,从而预测摄像机的运动状态。对于摄像机固定的情形,当然也可以用光流法,但是由于光流法的复杂性,往往难以实时的计算,所以我采用高斯背景模型。因为,在摄像机固定的情况下,背景的变化是缓慢的,而且大都是光照,风等等的影响,通过对背景建模,对一幅给定图像分离前景和背景,一般来说,前景就是运动物体,从而达到运动物体检测的目的。
单分布高斯背景模型
单分布高斯背景模型认为,对一个背景图像,特定像素亮度的分布满足高斯分布,即对背景图像B, (x,y)点的亮度满足:
IB (x,y) ~ N(u,d)
这样我们的背景模型的每个象素属性包括两个参数:平均值u 和 方差d。
对于一幅给定的图像G,如果 Exp(-(IG (x,y)-u(x,y))^2/(2*d^2)) > T,认为(x,y)是背景点,反之是前景点。
同时,随着时间的变化,背景图像也会发生缓慢的变化,这时我们要不断更新每个象素点的参数
u(t+1,x,y) = a*u(t,x,y) + (1-a)*I(x,y)
这里,a称为更新参数,表示背景变化的速度,一般情况下,我们不更新d(实验中发现更不更新 d,效果变化不大)。
opencv
int main( int argc, char** argv )
{
VideoCapture cam("bike.avi");// 0打开默认的摄像头
if(!cam.isOpened())
return -1;
namedWindow("mask",CV_WINDOW_AUTOSIZE);
namedWindow("frame",CV_WINDOW_AUTOSIZE);
Mat frame,mask,threImage,output;
int delay = 1000/cam.get(CV_CAP_PROP_FPS);
BackgroundSubtractorMOG bgSubtractor(10,10,0.5,false);
//构造混合高斯模型 参数1:使用历史帧的数量 2:混合高斯个数,3:背景比例 4::噪声权重
while (true)
{
cam>>frame;
imshow("frame",frame);
bgSubtractor(frame,mask,0.001);
imshow("mask",mask);
waitKey(delay);
}
return 0;
}
累积权重构建背景模型
运动物体检测与跟踪中的帧差分法,除了相邻帧差分法和三帧差分法外,还有一种差分方法,可以通过建立不含前景的背景模型,用当前帧和背景模型做差,差值就可以体现运动物体大概的位置和大小信息。相比相邻帧差分法和三帧差分法,背景模型做差法可以较为完整的体现运动物体的整体轮廓,运动物体的双重轮廓、“鬼影”、空洞现象改善明显,下文的对比效果可以看到这一点。
但背景模型的选取和建立的要求条件也更为苛刻:
1. 背景模型中不能包含前景物体,如果包含前景物体,则在之后检测到的运动物体结果中,会一直保留有前景运动物体初始的轮廓。
例如下边这个例子,选取了第一帧作为背景模型,不幸的是,第一帧中含有运动物体,用红色框标示出:
正如前边所说的,在之后检测到的运动物体结果中,3个前景运动物体初始的轮廓一直存在,即使运动物体早已经不在初始的位置,用红色框标示出。
若使用完全不包含前景物体的背景图像作为背景模型,上述情况就不会出现了,检测效果也比较好。比如使用下边这个图像作为背景模型:
由于这个视频没有完全不包含前景物体的背景图像,我的方法是求所有视频帧序列和的平均值作为背景模型,在一定程度上可以代表不含前景的背景图,部分位置处移动物体停留的事件比较久,所以有一些黑影出现,如图像中部区域。检测效果中不再有之前的3个“伪影像”,并且可以看到,相比相邻帧差分法和三帧差分法,背景模型做差法可以较为完整的体现运动物体的整体轮廓,运动物体的双重轮廓、“鬼影”、空洞现象改善明显。
2. 背景模型对环境的变化非常敏感,比如光照的变化、背景模型建立之后监控中加入的静止的物体、或背景模型中原本的物体位置被挪动等等,这些因素都会造成静止的物体被当做运动物体检测出来。造成误检,
还以上一个视频为例,当背景模型中原本静止的物体位置被挪动:
建立背景模型时视频中彩带的位置在下图用蓝色线段标示出,之后由于一些原因彩带的位置发生了改变,用红色线段标示,位置改变后,即使彩带一直保持静止,在检测结果中仍然会错误的检测出静止的彩带。
现实情况中,想要消除以上两点影响,一次性建立一个理想的背景模型,几乎是不可能的。基于此,我们可以建立一个动态的背景模型,这个动态模型实现以下两个功能:
1. 如果初始建立的背景模型中包含有前景物体,动态模型应该能够快速将前景物体的影响降低或消除掉;
2. 对于背景模型中静止的物体位置改变或者新加入视频画面中静止的物体,动态模型应该能够快速觉察到这种变化, 并把这种改变纳入到下一轮的背景模型构建中。
基于这两个基本的要求,构建动态背景模型的步骤如下:
1. 以初始第一帧作为第一个背景模型
2. 检测第二帧中运动物体,得到前景图像
3. 把第二帧图像抠除检测到的前景物体后,以一定比例系数累加到上一轮构建的背景模型中
4. 更新背景模型,在随后帧上,重复1,2,3
Opencv中,accumulateWeighted方法可以实现以上构建动态模型的要求。
方法原型:
void accumulateWeighted( InputArray src, InputOutputArray dst,
double alpha, InputArray mask=noArray() );
第一个参数:src,新加入的构建背景模型的图像矩阵;
第二个参数:dst,累计新元素src后生成的新的背景模型;
第三个参数:alpha,新加入原型src的系数,公式表述为:
dst = dst*(1-alpha) + src*alpha;
即alpha越大,当前新元素对构建动态模型的影响越大如下,当alpha取值为0.9时,背景模型为,此时新加入背景模型的新元素占比较大,对新的背景模型的影响也大,从上图可以看到,除有少许拖影外 ,基本跟上一帧图像特征一致;当alpha取值为0.2时,背景模型为,此时,新加入背景模型的元素占比较小,意味着之前加入的元素比重相应较大,累计的背景模型有很 重的“鬼影”,每一个虚影代表了最近新加入背景模型的一个元素。
第四个参数:mask,英文释义“面具”,顾名思义,指在背景模型中需要减去的,不予考虑的部分,可以使用在当前背景模型下检出的前景物体作为mask,进一步减少对背景模型的干扰,可以为空。
累积权重构建背景模型代码实现:
#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include "iostream"
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
VideoCapture videoCap(argv[1]);
if(!videoCap.isOpened())
{
return -1;
}
Mat image;
Mat imageBackground; //动态背景模型
Mat imageFront; //前景
double videoFPS=videoCap.get(CV_CAP_PROP_FPS); //获取帧率
double videoPause=1000/videoFPS;
videoCap>>imageBackground; //第一帧作为初始背景模型
cvtColor(imageBackground,imageBackground,CV_RGB2GRAY);
Mat element=getStructuringElement(0,Size(3,3)); //腐蚀核
while(true)
{
videoCap>>image;
if(image.empty()||waitKey(videoPause)==27) //视频播放完成,或Esc键退出
{
break;
}
Mat image1;
cvtColor(image,image1,CV_RGB2GRAY);
absdiff(image1,imageBackground,imageFront);
imageBackground.convertTo(imageBackground,CV_32FC1); //扩展至32位做运算
accumulateWeighted(image1,imageBackground,0.6,imageFront);
imageBackground.convertTo(imageBackground,CV_8UC1); //转换回8位
threshold(imageFront,imageFront,0,255,CV_THRESH_OTSU); //阈值分割
morphologyEx(imageFront,imageFront,CV_MOP_OPEN,element); //消除孤立的点
//膨胀操作,消除孔洞
dilate(imageFront,imageFront,element);
dilate(imageFront,imageFront,element);
dilate(imageFront,imageFront,element);
dilate(imageFront,imageFront,element);
dilate(imageFront,imageFront,element);
vector> contours;
vector hierarchy;
findContours(imageFront,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point());
for(int i=0;i
测试效果:
笔者已经将把源码上传到GitHub网站上,地址如下:
https://github.com/upcAutoLang/BackgroundSplit-OpenCV/tree/master/src/GaussBGDifference
ViBe - a powerful technique for background detection and subtraction in video sequences
——摘自ViBe算法官网
ViBe是一种像素级视频背景建模或前景检测的算法,效果优于所熟知的几种算法,对硬件内存占用也少。该算法主要不同之处是背景模型的更新策略,随机选择需要替换的像素的样本,随机选择邻域像素进行更新。在无法确定像素变化的模型时,随机的更新策略,在一定程度上可以模拟像素变化的不确定性。
参考地址:
《ViBe算法原理和代码解析 》
《背景建模–Vibe 算法优缺点分析》
《第一次总结报告——Vibe 》
《运动检测(前景检测)之(一)ViBe 》
《VIBE改进算法》
参考论文:
《O. Barnich and M. Van Droogenbroeck. ViBe: a powerful random technique to estimate the background in video sequences.》
《O. Barnich and M. Van Droogenbroeck. ViBe: A universal background subtraction algorithm for video sequences.》
算法官网:
http://www.telecom.ulg.ac.be/research/vibe/
前文提到的帧间差分法、背景差分法中存在若干问题如下:
其中值得一提的是Ghost区域:Ghost区域常常出现于帧间差分法,当一个原本静止的物体开始运动时,帧间差分法检测时,可能会将原本该物体覆盖区域错误的检测为运动的,这块被错误检测到的区域被称为Ghost。同样的,原本正在运动的物体变成静止物体时,也会出现Ghost区域。
例如下图,原图像中只有三个正在运动的人,但由于帧间差分法取得的背景图中包含这三个运动的人的某一帧运动状态,后面的一系列帧序列与背景图相减,都会存在背景图中三个人所在的位置,这时候取得的前景会多出三个被检测区域,即Ghost区域。
Ghost区域在检测中,一定要尽快消除。
ViBe比较特殊的地方它的思想:它为所有像素点存储了一个样本集,样本集里面保存的采样值是该像素点过去的像素值与其邻居点的像素值。后面每一帧的新像素值和样本集里的样本历史值进行比较,判断是否属于背景点。
下面从几点讲解ViBe算法:
模型中,背景就是静止的,或者移动非常缓慢的物体;前景就是相对于背景的物体,即正在移动的物体。所以背景提取算法也可以看成是一个分类问题,遍历像素点的过程中,来确定一个像素点是属于前景点,还是属于背景点。
在ViBe模型中,背景模型为每个像素点存储了样本集,样本集大小一般为20个点。对于采入的新一帧图像,该帧的某个像素点与该像素点的样本集内采样值比较接近时,就可以判断其是一个背景点。
用公式表示,我们可以认为:
将v(x,y)与M(x,y)中所有样本值作差,所有差值中,在±R范围内的个数为Nb,若Nb大于一个给定的阈值min,就说明当前像素值与该点历史样本中的多个值相似,那么就认为(x,y)点属于背景点。
初始化是建立背景模型的过程,一般的检测算法需要一定长度的视频序列学习完成,影响了检测的实时性,而且当视频画面突然变化时,重新学习背景模型需要较长时间。
ViBe算法建立背景模型只需要一帧,即使用单帧视频序列初始化背景模型。将视频的第一帧作为背景模型的同时,算法也将该帧中每一个像素点周围随机取多个像素点,填充该像素点的样本集,这样样本集中就包含了像素点的时空分布信息。
用公式表示,我们可以认为:
于是有:
M0(x)={v0(y|y∈NG(x))},t=0
这种背景模型初始化的优缺点如下:
初始背景模型建立完毕后,就可以进行前景的检测和背景模型的更新了。
此时已经建立起了背景模型,便可以已经建立好的背景模型进行前景的检测。
遍历新一帧图像的所有像素点。用公式表示,则有:
检测前景的流程如下:
检测过程的主要三个参数是:样本集数目N,阈值R,与阈值T。一般设置N = 20, R = 20, T = 2;
即使已经建立起了背景模型,也应该对背景模型进行不断的更新,这样才能使得背景模型能够适应背景的不断变化(如光照变化,背景物体变更等)。
A. 普通更新策略
对于其他的背景提取算法,背景模型有两种不同的更新策略:
B. ViBe算法更新策略
ViBe算法中,使用的更新策略是:保守更新策略 + 前景点计数法 + 随机子采样。
这就决定了ViBe算法的更新策略的其他属性:
C. ViBe算法具体更新的方法:
更新邻居的样本值利用了像素值的空间传播特性,背景模型逐渐向外扩散,这也有利于Ghost区域的更快的识别。
在选择要替换的样本集中的样本值时,我们是随机选取一个样本值进行更新。这样就可以保证,样本值的平滑的生命周期的原因是由于是随机的更新,这种情况下一个样本值在时刻t不被更新的概率是(N - 1) / N。假设时间是连续的,那么在极小时间dt过去后,样本值仍然保留的概率是:
P(t,t+dt)=(N−1N)(t+dt)−t
也可以写作:
P(t,t+dt)=e−ln(NN−1)dt
上面的公式表明,样本值在模型中是否被替换,与时间t无关,即更新策略是合适的。
Vibe背景建模为运动目标检测研究领域开拓了新思路,是一种新颖、快速及有效的运动目标检测算法。优点主要有两点:
关于运算效率的比较,《背景建模–Vibe 算法优缺点分析》中做了实验:为了得到最佳样本数量N值,分别选取N为5、15、20、25进行了实验对比:结果如图所示:
实验结果表明,N取20、25时,检测结果理想;考虑计算负载,N取20最优。与混合高斯的3-5个高斯模型的计算匹配比较,基于20个样本的背景模型计算具有计算开销低、检测速度快等优点。
Vibe的背景模型相似度匹配函数只与判断像素点与历史样本值是否相近的阈值R,以及判断前景点的阈值T有关(具体见本文三.2.(3))。背景模型中的样本与待分类像素的欧式距离小于R的个数超过T时,更新背景模型;而找到T个匹配样本时,便立即判断该像素为背景像素点,并停止计算,这样提高了运算效率。
ViBe算法自身也存在着局限性。主要有静止目标、阴影前景和运动目标不完整等问题。
A. 静止目标
如下图所示:
图(a)红框中的人在等地铁,从图(a)到图(c)经过498帧,长时间驻留未运动,该人物运动目标逐渐被背景吸收。而在本视频中,将在450帧以上都没有明显位移的运动目标区域定义成为静止目标区域。
这样可以总结产生静止目标问题的原因有两个:
B. 阴影前景
如下图所示:
图(b)和图(d)分别是用Vibe算法对人体运动目标(a)和车体运动目标(c)的检测结果。由于光线被人体或车体运动目标所遮挡,投射阴影区的背景被误检为运动目标前景。阴影的存在导致检测出来的运动目标形状不准确,影响后续目标分类、跟踪、识别和分析等其他智能视频处理模块。
产生阴影前景问题的根源是:光线被运动目标前景遮挡,投射阴影区的颜色比背景的颜色暗,即阴影和背景颜色值的距离相差较大,背景差分后被误检为运动目标前景。
C. 运动目标不完整问题
如下图所示:
总结图中的结果,可以将运动目标不完整现象大致分为三类:
产生运动目标不完整问题的根源主要有两点:
笔者已经将把源码上传到GitHub网站上,地址如下:
https://github.com/upcAutoLang/BackgroundSplit-OpenCV/tree/master/src/ViBe
笔者对ViBe+进行了学习研究,博客地址如下:
《论文翻译:ViBe+算法(ViBe算法的改进版本)》
笔者已经将把源码上传到GitHub网站上,地址如下:
https://github.com/upcAutoLang/BackgroundSplit-OpenCV/tree/master/src/ViBe%2B
相关参考地址:
《ViBe算法原理和代码解析 》
《VIBE改进算法》
参考论文:
《M. Van Droogenbroeck and O. Paquot. Background Subtraction: Experiments and Improvements for ViBe.》