EmguCV学习笔记 C# 9.3 移动检测类
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。
教程VB.net版本请访问:EmguCV学习笔记 VB.Net 目录-CSDN博客
教程C#版本请访问:EmguCV学习笔记 C# 目录-CSDN博客
笔者的博客网址:https://blog.csdn.net/uruseibest
教程配套文件及相关说明以及如何获得pdf教程和代码,请移步:EmguCV学习笔记
学习VB.Net知识,请移步: vb.net 教程 目录_vb中如何用datagridview-CSDN博客
学习C#知识,请移步:C# 教程 目录_c#教程目录-CSDN博客
9.3 移动检测类
EmguCV主要提供的移动检测类,可以根据不同的算法实现背景建模,帮助我们从动态视频中提取静态前景。在早期版本中,移动检测类主要是BackgroundSubtractor类的继承类,新的版本中,它们主要集中在Emgu.CV.BgSegm命名空间下。这些类都对处理的图像有一定的要求,必须是8位灰度图像或者8位彩色图像。
9.3.1 Emgu.CV.BgSegm命名空间
BgSegm命名空间提供了5个基于背景分割的算法实现,常用于视频中的前景提取:
1、BackgroundSubtractorCNT类(Emgu.CV.BgSegm)
BackgroundSubtractorCNT是EmguCV中实现基于连通性的背景建模和前景提取的类。它通过对像素进行连通分析,将相邻的前景像素合并为一个前景区域,从而提高了前景检测的精度和鲁棒性。
由于BackgroundSubtractorCNT类需要维护一个像素的稳定状态,因此对于大尺寸的图像,可能会占用较大的内存空间。
2、BackgroundSubtractorGMG类(Emgu.CV.BgSegm)
BackgroundSubtractorGMG是EmguCV中实现基于自适应背景模型的背景建模和前景提取的类。它可以自适应地更新背景模型,以适应背景变化和光照变化等情况。
BackgroundSubtractorGMG类需要较长的初始化时间,因此在使用之前需要先对一定数量的帧进行背景建模
3、BackgroundSubtractorGSOC类(Emgu.CV.BgSegm)
BackgroundSubtractorGSOC是EmguCV中实现基于自适应背景模型的背景建模和前景提取的类。它可以自适应地更新背景模型,以适应背景变化和光照变化等情况。
BackgroundSubtractorGSOC类的计算复杂度较高,因此在处理大尺寸的图像时可能需要较长的处理时间。
4、BackgroundSubtractorLSBP类(Emgu.CV.BgSegm)
BackgroundSubtractorLSBP是EmguCV中实现基于局部二进制模式(Local Binary Patterns,LBP)的背景建模和前景提取的类。它可以自适应地更新背景模型,以适应背景变化和光照变化等情况。
BackgroundSubtractorLSBP类的计算速度较快,在处理大尺寸的图像时也具有一定的优势。
5、BackgroundSubtractorMOG类(Emgu.CV.BgSegm)
BackgroundSubtractorMOG是EmguCV中实现基于高斯混合模型(Gaussian Mixture Model,GMM)的背景建模和前景提取的类。它可以自适应地更新背景模型,以适应背景变化和光照变化等情况。
BackgroundSubtractorMOG类的计算速度较快,在处理大尺寸的图像时也具有一定的优势。
BgSegm命名空间中的类有一个重要的方法:Apply方法。该方法用于将当前帧与背景模型进行比较,提取出前景部分。其声明如下:
public static void Apply(
this IBackgroundSubtractor subtractor,
IInputArray image,
IOutputArray fgMask,
double learningRate = -1
)
参数说明:
- image:输入图像,要求为8位灰度图像或彩色图像。
- fgmask:输出前景掩码图像,为8位灰度图像。
- learningRate:背景模型的学习速率,取值范围为0到1。当学习速率为0时,算法不会对背景模型进行更新;当学习速率为1时,算法完全采用当前帧作为背景模型。当为-1时,则实际的学习速率是根据当前帧与背景模型的相似度来动态调整的。具体来说,如果当前帧与背景模型的相似度较高(即前景变化较小),则算法的学习速率会相应降低,背景模型会更加稳定;如果当前帧与背景模型的相似度较低(即前景变化较大),则算法的学习速率会相应提高,背景模型会更加适应场景变化。这种自适应学习速率的机制可以使算法更加鲁棒,能够适应不同的场景变化。但是,由于学习速率的实际值取决于当前帧与背景模型的相似度,因此无法确定学习速率的具体数值。如果需要精确控制学习速率,建议使用具有固定学习速率的Apply方法并手动调整学习速率参数。
在调用Apply方法时,算法会将输入图像与背景模型进行比较,并将前景像素标记为1,背景像素标记为0,最终生成前景掩码图像。学习速率参数用于控制背景模型的更新速度,当学习速率较大时,背景模型可以更快地适应场景变化,但也容易受到噪声和干扰的影响;当学习速率较小时,背景模型变化相对较慢,但也更加稳定。
关于Apply方法的示例代码,请参看9.3.1.1节【BackgroundSubtractorMOG】。
9.3.1.1 BackgroundSubtractorMOG
BackgroundSubtractorMOG是EmguCV中实现基于高斯混合模型(Gaussian Mixture Model,GMM)的背景建模和前景提取的类。它的构造函数如下:
public BackgroundSubtractorMOG(
int history = 200,
int nMixtures = 5,
double backgroundRatio = 0.7,
double noiseSigma = 0
)
参数说明:
- history:表示用于背景建模的历史帧数,即建模时考虑的前几帧的像素值。
- nMixtures:表示使用的高斯分布数量,即背景颜色的数量,NMixtures越大,模型越复杂,可以更好地适应复杂的背景场景。但NMixtures过大会导致计算时间和内存消耗增加。
- backgroundRatio:表示背景像素的阈值,即像素值与背景模型中各个高斯分布的距离阈值。
- noiseSigma:表示噪声标准差,即高斯分布的方差。
开发时,根据实际情况需根据需要设置不同的参数值,以达到更好的背景建模和前景提取效果。
【代码位置:frmChapter9_2】Button1_Click、vcMog_ImageGrabbed
VideoCapture vcMog;
Emgu.CV.BgSegm.BackgroundSubtractorMOG bsMog;
Mat moutMog;
//使用BackgroundSubtractorMOG进行移动检测
private void Button1_Click(object sender, EventArgs e)
{
//使用BackgroundSubtractorMOG默认的参数
bsMog = new Emgu.CV.BgSegm.BackgroundSubtractorMOG();
moutMog = new Mat();
vcMog = new VideoCapture("C:\\learnEmgucv\\movie1.mp4");
if (vcMog.IsOpened == false)
{
MessageBox.Show("打开文件失败");
return;
}
//添加ImageGrabbed事件
vcMog.ImageGrabbed += vcMog_ImageGrabbed;
vcMog.Start();
}
//在ImageGrabbed事件内使用BackgroundSubtractorMOG进行检测
private void vcMog_ImageGrabbed(object sender, EventArgs e)
{
Mat nextframe = new Mat();
//如果使用Retrieve,那么需要检查视频当前播放的位置
vcMog.Retrieve(nextframe);
//判断是否到达视频结束帧
if (vcMog.Get(CapProp.PosFrames) >= vcMog.Get(CapProp.FrameCount))
{
//停止
vcMog.Stop();
//释放资源
vcMog.Dispose();
//取消事件
vcMog.ImageGrabbed -= vcMog_ImageGrabbed;
return;
}
//BackgroundSubtractorMOG类的Apply方法
bsMog.Apply(nextframe, moutMog);
//检测得到的图像噪声较多,进行滤波
CvInvoke.MedianBlur(moutMog, moutMog, 15);
//二值化
CvInvoke.Threshold(moutMog, moutMog, 220, 255, ThresholdType.Binary);
ImageBox1.Image = moutMog;
System.Threading.Thread.Sleep(40);
}
输出结果如下图所示:
图9-5 使用BackgroundSubtractorMOG进行移动目标检测
以下代码在上述代码的基础上,将移动目标标识出来:
【代码位置:frmChapter9_2】Button1_Click、vcMog1_ImageGrabbed
private void Button1_Click(object sender, EventArgs e)
{
……
//添加ImageGrabbed事件
vcMog.ImageGrabbed += vcMog1_ImageGrabbed;
……
}
//将移动目标标识出来
private void vcMog1_ImageGrabbed(object sender, EventArgs e)
{
Mat nextframe = new Mat();
//如果使用Retrieve,那么需要检查视频当前播放的位置
vcMog.Retrieve(nextframe);
//判断是否到达视频结束帧
if (vcMog.Get(CapProp.PosFrames) >= vcMog.Get(CapProp.FrameCount))
{
//停止
vcMog.Stop();
//释放资源
vcMog.Dispose();
//取消事件
vcMog.ImageGrabbed -= vcMog1_ImageGrabbed;
return;
}
//BackgroundSubtractorMOG类的Apply方法
bsMog.Apply(nextframe, moutMog);
//检测得到的图像噪声较多,进行滤波
CvInvoke.MedianBlur(moutMog, moutMog, 15);
//二值化
CvInvoke.Threshold(moutMog, moutMog, 220, 255, ThresholdType.Binary);
//查找形状
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
CvInvoke.FindContours(moutMog, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
Mat mshow = new Mat();
mshow = nextframe.Clone();
Double contourArea = 0;
for (int i = 0; i < contours.Size; i++)
{
contourArea = CvInvoke.ContourArea(contours[i]);
//必须大于一定面积才认为是有效的目标
if (contourArea > 10000)
{
//获得最大外接矩形
Rectangle rectmax = CvInvoke.BoundingRectangle(contours[i]);
//绘制最大外接矩形
CvInvoke.Rectangle(mshow, rectmax, new MCvScalar(0, 0, 255), 3);
}
}
ImageBox1.Image = mshow;
System.Threading.Thread.Sleep(40);
}
输出结果如下图所示:
图9-6 检测并标识移动目标
附注:GMM模型是一种常用的背景建模算法,它将背景模型表示为多个高斯分布的混合,每个高斯分布对应一种背景颜色。在每次处理新的视频帧时,使用当前帧像素值与背景模型中各个高斯分布的均值和方差进行比较,如果像素值与某个高斯分布的均值和方差差异较小,则将其归为该背景颜色,否则将其视为前景。
9.3.1.2 BackgroundSubtractorCNT
BackgroundSubtractorCNT是EmguCV中实现基于连通性的背景建模和前景提取的类。它的构造函数如下:
public BackgroundSubtractorCNT(
int minPixelStability = 15,
bool useHistory = true,
int maxPixelStability = 900,
bool isParallel = true
)
参数说明:
- minPixelStability:表示前景像素在背景建模时的最小稳定帧数。当一个像素在连续的minPixelStability帧中被检测为前景时,它才会被认为是真正的前景像素。
- useHistory:表示是否使用历史帧数进行计数。
- maxPixelStability:表示前景像素在背景建模时的最大稳定帧数。当一个像素在超过maxPixelStability帧中没有被检测为前景时,它会被认为是背景像素。
- isParallel:用于控制计算前景掩码的算法是否并行执行。当isParallel为True时,算法会使用多线程并行计算前景掩码,以提高算法的处理速度。当isParallel为False时,算法会使用单线程顺序计算前景掩码,以保证算法的准确性和稳定性。需要注意的是,使用多线程并行计算前景掩码可以显著提高算法的处理速度,但也会带来一些性能和内存开销。如果计算机的处理器性能较弱或内存较少,建议将isParallel参数设置为False,以避免出现性能瓶颈或内存不足的问题。
关于使用BackgroundSubtractorCNT进行移动目标检测的代码,请参看9.3.1.1节【BackgroundSubtractorMOG】的示例代码,可以根据实际需要修改相应参数。
9.3.1.3 BackgroundSubtractorGMG
BackgroundSubtractorGMG是EmguCV中实现基于自适应背景模型的背景建模和前景提取的类。它的构造函数如下:
public BackgroundSubtractorCNT(
int minPixelStability = 15,
bool useHistory = true,
int maxPixelStability = 900,
bool isParallel = true
)
参数说明:
- initializationFrames:表示背景建模时的初始帧数。在这些帧中,BackgroundSubtractorGMG会学习场景的背景信息,并初始化背景模型。
- decisionThreshold:表示前景像素的阈值。当一个像素的概率值大于DecisionThreshold时,它被认为是前景像素,否则为背景像素。
关于使用BackgroundSubtractorGMG进行移动目标检测的代码,请参看9.3.1.1节【BackgroundSubtractorMOG】的示例代码,可以根据实际需要修改相应参数。
9.3.1.4 BackgroundSubtractorGSOC
BackgroundSubtractorGSOC是EmguCV中实现基于自适应背景模型的背景建模和前景提取的类。它的构造函数如下:
public BackgroundSubtractorGSOC(
BackgroundSubtractorLSBP. CameraMotionCompensation mc = BackgroundSubtractorLSBP.CameraMotionCompensation.None,
int nSamples = 20,
float replaceRate = 0.003f,
float propagationRate = 0.01f,
int hitsThreshold = 32,
float alpha = 0.01f,
float beta = 0.0022f,
float blinkingSupressionDecay = 0.1f,
float blinkingSupressionMultiplier = 0.1f,
float noiseRemovalThresholdFacBG = 0.0004f,
float noiseRemovalThresholdFacFG = 0.0008f
)
参数说明:
- mc:是否使用相机运动补偿。
- n示例:指定帧的每个点保留的采样数。
- replaceRate:替换旧样本的概率-模型自行更新的速度。
- propagationRate:传播到相邻点的概率。
- hitsThreshold:样本必须具备多少优势,才能被视为可能的替代品。
- alpha:阈值的比例系数。
- beta:阈值的偏移系数。
- blinkingUppressionDecay:闪烁抑制衰减因子。
- blinkingUppressionMultiplier:闪烁的抑制倍数。
- noiseRemovalThresholdFacBG:背景点噪声消除强度。
- noiseRemovalThresholdFacFG:前景点噪声消除强度。
关于使用BackgroundSubtractorGSOC进行移动目标检测的代码,请参看9.3.1.1节【BackgroundSubtractorMOG】的示例代码,可以根据实际需要修改相应参数。
9.3.1.5 BackgroundSubtractorLSBP
BackgroundSubtractorLSBP是EmguCV中实现基于局部二进制模式(Local Binary Patterns,LBP)的背景建模和前景提取的类。它的构造函数如下:
public BackgroundSubtractorLSBP(
BackgroundSubtractorLSBP. CameraMotionCompensation mc = BackgroundSubtractorLSBP.CameraMotionCompensation.None,
int nSamples = 20,
int LSBPRadius = 16,
float tlower = 2f,
float tupper = 32f,
float tinc = 1f,
float tdec = 0.05f,
float rscale = 10f,
float rincdec = 0.005f,
float noiseRemovalThresholdFacBG = 0.0004f,
float noiseRemovalThresholdFacFG = 0.0008f,
int LSBPthreshold = 8,
int minCount = 2
)
参数说明:
- mc:是否使用相机运动补偿。
- nSamples:要在帧的每个点保持的采样数。
- LSBPRadius:LSBP描述符半径。
- tlower:T值的下限。
- tupper:T值的上限。
- tinc:增加T值的步长。
- tdec:减小T值的步长。
- rscale:阈值的比例系数。
- rincdec:阈值的增加/减少步骤。
- noiseRemovalThresholdFacBG:背景点的噪声去除强度。
- noiseRemovalThresholdFacFG:前景点的噪声去除强度。
- LSBPthreshold:LSBP二进制字符串的阈值。
- minCount:将样本视为前景的最小匹配数。
关于使用BackgroundSubtractorLSBP进行移动目标检测的代码,请参看9.3.1.1节【BackgroundSubtractorMOG】的示例代码,可以根据实际需要修改相应参数。
9.3.2 BackgroundSubtractorMOG2类
BackgroundSubtractorMOG2是EmguCV中实现基于高斯混合模型(Gaussian Mixture Model,GMM)的背景建模和前景提取的类。
BackgroundSubtractorMOG2类的构造函数如下:
public BackgroundSubtractorMOG2(
int history = 500,
float varThreshold = 16f,
bool shadowDetection = true
)
参数说明:
- history:表示背景建模时使用的历史帧数。history值越大,背景模型越稳定,但也会增加计算量。
- varThreshold:像素和样本之间的方差阈值。当一个像素的方差值超过VarThreshold时,它被认为是前景像素。
- shadowDetection:表示是否检测阴影。如果设置为True,则会检测图像中的阴影,并将其标记为前景像素。
BackgroundSubtractorMOG2类的常用属性如下:
- History:历史帧数,表示用于建模的最近的几帧图像。
- VarThreshold:阈值,用于控制前景和背景之间的差异,当差异超过该阈值时,像素被认为是前景像素,通常设置为16。
- BackgroundRatio:背景比例,表示用于建模的背景像素占总像素数的比例,通常设置为0.9。
- DetectShadows:是否检测阴影,通常设置为True。如果检测阴影,则前景掩码图像中会包含阴影区域,在后续处理中需要进行额外的处理。
- VarThresholdGen:阈值生成率,用于控制阈值的自适应学习率,通常设置为1.0。
- VarInit:初始化方差,表示用于初始化高斯混合模型的初始方差,通常设置为15。
- VarMin:最小方差,表示每个高斯混合模型允许的最小方差,通常设置为4。
- VarMax:最大方差,表示每个高斯混合模型允许的最大方差,通常设置为75。
- ShadowValue:阴影值,表示阴影像素的像素值,通常设置为127。
- ShadowThreshold:阴影阈值,用于判断像素是否为阴影像素,通常设置为0.5。
在使用BackgroundSubtractorMOG类时,可以通过调整这些属性的值,来控制背景建模的精度和速度。例如,可以增加历史帧数来提高背景模型的稳定性,也可以降低阈值来增加前景像素的数量。需要根据实际情况进行调整。
【代码位置:frmChapter9_2】Button2_Click、vcMog2_ImageGrabbed
VideoCapture vcMog2;
Emgu.CV.BackgroundSubtractorMOG2 bsMog2;
Mat moutMog2;
//使用BackgroundSubtractorMOG2进行移动检测
private void Button2_Click(object sender, EventArgs e)
{
//使用BackgroundSubtractorMOG2默认的参数
bsMog2 = new BackgroundSubtractorMOG2();
moutMog2 = new Mat();
vcMog2 = new VideoCapture("C:\\learnEmgucv\\movie1.mp4");
if (vcMog2.IsOpened == false)
{
MessageBox.Show("打开文件失败");
return;
}
//添加ImageGrabbed事件
vcMog2.ImageGrabbed += vcMog2_ImageGrabbed;
vcMog2.Start();
}
//在ImageGrabbed事件内使用BackgroundSubtractorMOG2进行检测
private void vcMog2_ImageGrabbed(object sender, EventArgs e)
{
Mat nextframe = new Mat();
//如果使用Retrieve,那么需要检查视频当前播放的位置
vcMog2.Retrieve(nextframe);
//判断是否到达视频结束帧
if (vcMog2.Get(CapProp.PosFrames) >= vcMog2.Get(CapProp.FrameCount))
{
//停止
vcMog2.Stop();
//释放资源
vcMog2.Dispose();
//取消事件
vcMog2.ImageGrabbed -= vcMog2_ImageGrabbed;
return;
}
//BackgroundSubtractorMOG2类的Apply方法
bsMog2.Apply(nextframe, moutMog2);
//检测得到的图像噪声较多,进行滤波
CvInvoke.MedianBlur(moutMog2, moutMog2, 15);
//二值化,如果设置了检测阴影,可以注释掉下面代码看看
CvInvoke.Threshold(moutMog2, moutMog2, 220, 255, ThresholdType.Binary);
ImageBox1.Image = moutMog2;
System.Threading.Thread.Sleep(40);
}
输出结果如下图所示:
图9-7 使用BackgroundSubtractorMOG2进行移动目标检测
BackgroundSubtractorMOG和BackgroundSubtractorMOG2都是EmguCV中用于背景建模和前景提取的类,它们的主要区别在于使用的GMM模型不同。
BackgroundSubtractorMOG使用的是简单的GMM模型,可以适应一定程度的背景变化和光照变化,但在处理复杂场景时可能会产生较多的误检和漏检。
BackgroundSubtractorMOG2使用的是更加复杂的GMM模型,可以自适应地调整模型参数,以适应复杂的背景场景和光照变化等情况。同时,BackgroundSubtractorMOG2还可以检测图像中的阴影,并将其标记为前景像素。
相比之下,BackgroundSubtractorMOG2的前景提取效果更加准确,但计算量和内存消耗也会更大。因此,BackgroundSubtractorMOG适用于对计算资源要求较低的背景建模和前景提取场景,适合处理较为简单的背景场景;而BackgroundSubtractorMOG2适用于对前景提取精度要求较高的场景,可以处理复杂的背景和光照变化等情况。
总的来说,选择使用哪个类要根据实际需求进行判断,如果对前景提取精度要求不高,可以选择BackgroundSubtractorMOG;如果需要更高的前景提取精度,可以选择BackgroundSubtractorMOG2。
9.3.3 BackgroundSubtractorKNN
BackgroundSubtractorKNN是EmguCV中用于背景建模和前景提取的类,它使用KNN算法来进行背景建模和前景提取,相比于传统的GMM模型,它具有更好的自适应性和实时性。
public BackgroundSubtractorKNN(
int history,
double dist2Threshold,
bool detectShadows
)
参数说明:
- history:表示背景建模时使用的历史帧数。history值越大,背景模型越稳定,但也会增加计算量。
- dist2Threshold:像素和样本之间距离平方的阈值。当一个像素的方差值超过dist2Threshold时,它被认为是前景像素。
- detectShadows:表示是否检测阴影。如果设置为True,则会检测图像中的阴影,并将其标记为前景像素。
BackgroundSubtractorKNN类的常用属性如下:
- History:用于模型训练的历史帧数,通常设置为500。History属性值越大,背景模型越稳定,但也会增加计算量。
- Dist2Threshold:像素与背景模型之间的距离阈值,通常设置为400.0。如果像素与背景模型之间的距离超过了该阈值,则该像素被视为前景像素。
- DetectShadows:是否检测阴影,通常设置为True。如果检测阴影,则前景掩码图像中会包含阴影区域,在后续处理中需要进行额外的处理。
- ShadowValue:阴影像素值,通常设置为127。在前景掩码图像中,阴影像素的像素值会被设置为该值。
- ShadowThreshold:阴影阈值,通常设置为0.5。如果像素与背景模型之间的距离小于该阈值,则该像素被视为阴影像素。
- KNNSample:邻域样本的数量,它指定了每个像素的邻域中应该包含多少个样本,通常设置为7。该属性越大,算法检测前景的准确性越高,但计算量也会相应增加。当该属性为1时,每个像素只考虑其本身作为样本,不考虑邻域样本,因此算法运行速度最快,但检测前景的准确性也最低。KNNSample属性需要根据实际需求进行调整,以平衡算法的性能和准确性。
【代码位置:frmChapter9_2】Button3_Click、vcKNN_ImageGrabbed
VideoCapture vcKNN;
Emgu.CV.BackgroundSubtractorKNN bsKNN;
Mat moutKNN;
//使用BackgroundSubtractorKNN进行移动检测
private void Button3_Click(object sender, EventArgs e)
{
//使用BackgroundSubtractorKNN
bsKNN = new BackgroundSubtractorKNN(50, 200.0F, true);
moutKNN = new Mat();
vcKNN = new VideoCapture("C:\\learnEmgucv\\movie1.mp4");
if (vcKNN.IsOpened == false)
{
MessageBox.Show("打开文件失败");
return;
}
//添加ImageGrabbed事件
vcKNN.ImageGrabbed += vcKNN_ImageGrabbed;
vcKNN.Start();
}
//在ImageGrabbed事件内使用BackgroundSubtractorKNN进行检测
private void vcKNN_ImageGrabbed(object sender, EventArgs e)
{
Mat nextframe = new Mat();
//如果使用Retrieve,那么需要检查视频当前播放的位置
vcKNN.Retrieve(nextframe);
//判断是否到达视频结束帧
if (vcKNN.Get(CapProp.PosFrames) >= vcKNN.Get(CapProp.FrameCount))
{
//停止
vcKNN.Stop();
//释放资源
vcKNN.Dispose();
//取消事件
vcKNN.ImageGrabbed -= vcKNN_ImageGrabbed;
return;
}
//BackgroundSubtractorKNN类的Apply方法
bsKNN.Apply(nextframe, moutKNN);
//检测得到的图像噪声较多,进行滤波
CvInvoke.MedianBlur(moutKNN, moutKNN, 15);
//二值化,如果设置了检测阴影,可以注释掉下面代码看看
CvInvoke.Threshold(moutKNN, moutKNN, 220, 255, ThresholdType.Binary);
ImageBox1.Image = moutKNN;
System.Threading.Thread.Sleep(40);
}
输出结果如下图所示:
图9-8 使用BackgroundSubtractorKNN进行移动目标检测