OpenCVSharp:使用MOG进行运动物体识别 📅 2026/6/28 2:26:54 目录效果实现效果动态效果实现运动物体检测是计算机视觉中的一个重要应用广泛应用于安防监控、交通分析、人机交互等领域。本文将详细介绍如何使用OpenCVSharp中的MOGMixture of Gaussians算法实现运动物体检测并通过一个完整的WPF应用程序示例展示实际应用。什么是MOG算法MOGMixture of Gaussians高斯混合模型是一种基于背景建模的运动检测算法。它通过对每个像素建立多个高斯分布模型来表示背景能够有效处理光照变化、树叶摇曳等动态背景干扰。MOG算法原理背景建模为每个像素建立K个高斯分布模型模型匹配将当前像素值与已有模型进行匹配模型更新根据匹配结果更新模型参数前景检测不匹配任何背景模型的像素被标记为前景ViewModel设计我们使用MVVM模式设计应用程序主要包含以下属性和命令public classMovingObjectDetectionViewModel : BindableBase { // 视频路径 publicstring VideoPath { get; set; } // 图像显示 public BitmapImage OriginalImage { get; set; } public BitmapImage ProcessedImage { get; set; } // 处理状态 publicbool IsProcessing { get; set; } publicstring StatusMessage { get; set; } // 检测参数 publicdouble DetectionThreshold { get; set; } // 统计信息 publicint FrameCount { get; set; } publicint DetectedObjectsCount { get; set; } // 命令 public ICommand SelectVideoCommand { get; privateset; } public ICommand RunCommand { get; privateset; } public ICommand StopCommand { get; privateset; } }主要实现在RunAsync中我们来学习一下用到了OpenCVSharp的哪些方法。using var capture new VideoCapture(VideoPath); // 获取视频信息 int frameWidth (int)capture.Get(VideoCaptureProperties.FrameWidth); int frameHeight (int)capture.Get(VideoCaptureProperties.FrameHeight); double fps capture.Get(VideoCaptureProperties.Fps); int totalFrames (int)capture.Get(VideoCaptureProperties.FrameCount);首先可以这样获取视频的一些信息using var mog BackgroundSubtractorMOG.Create(); using var frame new Mat(); using var fg new Mat(); using var kernel Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(5, 5));遇到了一个新东西Cv2.GetStructuringElement。这行代码是创建一个形态学操作的结构元素也称为核或卷积核用于图像处理中的形态学变换。Cv2.MorphologyEx(fg, fg, MorphTypes.Open, kernel);这是OpenCVSharp中执行高级形态学操作的函数支持多种形态学变换类型。参数说明第一个参数 fg输入图像即经过MOG背景减除后的前景掩码第二个参数 fg输出图像处理后的结果会覆盖原图像第三个参数 MorphTypes.Open指定形态学操作类型为开运算第四个参数 kernel之前创建的5×5椭圆形结构元素开运算Opening Operation是形态学处理中的一种基本操作它由腐蚀Erosion后跟膨胀Dilation两个步骤组成开运算 腐蚀 膨胀。开运算的效果去除小噪声消除图像中的孤立白点小噪声区域平滑轮廓使物体轮廓更加平滑断开细小连接轻微分离可能连接在一起的不同物体保持主要形状不显著改变物体的大小和基本形状我们需要大概了解一下腐蚀与膨胀是什么意思。腐蚀膨胀// 查找轮廓 OpenCvSharp.Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(fg, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);又接触到了一个新东西Cv2.FindContours()这是OpenCV中查找轮廓的核心函数用于在二值图像中检测物体边界。参数详解第一个参数 fg输入的二值图像经过形态学处理的前景掩码第二个参数 out contours输出的轮廓数组第三个参数 out hierarchy输出的轮廓层次结构第四个参数 RetrievalModes.External轮廓检索模式第五个参数 ContourApproximationModes.ApproxSimple轮廓近似方法轮廓检索模式RetrievalModes.External含义只检测最外层轮廓适用场景运动物体检测因为我们只关心物体的外部边界效果忽略物体内部的孔洞其他可选模式RetrievalModes.External // 只检测外轮廓 RetrievalModes.List // 检测所有轮廓不建立层次关系 RetrievalModes.CComp // 检测所有轮廓建立两层层次关系 RetrievalModes.Tree // 检测所有轮廓建立完整的层次树轮廓近似方法ContourApproximationModes.ApproxSimple含义压缩水平、垂直、对角方向的元素只保留端点效果减少轮廓点数提高处理速度适用场景矩形或近似矩形的物体其他可选方法ContourApproximationModes.ApproxNone // 保存所有轮廓点 ContrieApproximationModes.ApproxSimple // 压缩轮廓保留端点 ContourApproximationModes.ApproxTC89L1 // Teh-Chin链逼近算法L1 ContourApproximationModes.ApproxTC89KCOS // Teh-Chin链逼近算法KCOS// 绘制检测到的运动物体 foreach (var contour in contours) { double area Cv2.ContourArea(contour); if (area 300) // 过滤掉太小的区域 { currentFrameObjects; var rect Cv2.BoundingRect(contour); Cv2.Rectangle(frame, rect, Scalar.Red, 2); } }Cv2.ContourArea()计算轮廓包围的面积Cv2.BoundingRect()计算轮廓的最小外接矩形Cv2.Rectangle()绘制矩形就这样处理每一帧就可以得到上面的效果了。引入地址