OpenCVSharp:使用MOG进行运动物体识别

B站影视 欧美电影 2025-11-18 14:39 1

摘要:运动物体检测是计算机视觉中的一个重要应用,广泛应用于安防监控、交通分析、人机交互等领域。本文将详细介绍如何使用OpenCVSharp中的MOG(Mixture of Gaussians)算法实现运动物体检测,并通过一个完整的WPF应用程序示例展示实际应用。

动态效果:

运动物体检测是计算机视觉中的一个重要应用,广泛应用于安防监控、交通分析、人机交互等领域。本文将详细介绍如何使用OpenCVSharp中的MOG(Mixture of Gaussians)算法实现运动物体检测,并通过一个完整的WPF应用程序示例展示实际应用。

什么是MOG算法?

MOG(Mixture 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.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绘制矩形

就这样处理每一帧就可以得到上面的效果了。

来源:opendotnet

相关推荐