运动目标检测是计算机视觉中的重要应用,广泛应用于安防监控、自动驾驶、人机交互等领域。本文将介绍如何使用OpenCV实现一个简单的视频运动目标检测系统,包括背景建模、形态学处理和轮廓检测等关键技术。
这段代码实现了以下功能:
import cv2
# 读取视频文件
cap = cv2.VideoCapture('test.avi')
# 创建形态学操作核
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))
VideoCapture
用于读取视频文件getStructuringElement
创建形态学操作核,这里使用3×3的十字形核# 创建混合高斯背景模型
fgbg = cv2.createBackgroundSubtractorMOG2()
createBackgroundSubtractorMOG2()
实现了基于高斯混合模型(GMM)的背景减除算法,能够有效分离前景和背景。
while True:
ret, frame = cap.read()
if not ret:
break
# 显示原始帧
cv2.imshow('frame', frame)
# 应用背景减除
fgmask = fgbg.apply(frame)
cv2.imshow('fgmask', fgmask)
# 形态学开运算去噪
fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
cv2.imshow('fgmask1', fgmask_new)
这段代码是视频运动检测系统的核心处理循环,主要完成视频帧的读取、背景减除和噪声处理等功能。下面我将详细解释每一部分:
代码结构解析
while True:
ret, frame = cap.read()
if not ret:
break
(1) 视频帧读取
cap.read()
从视频捕获对象读取下一帧ret
是布尔值,表示是否成功读取帧frame
是读取到的视频帧图像not ret
),退出循环(2) 显示原始帧
# 显示原始帧
cv2.imshow('frame', frame)
cv2.imshow()
显示当前帧(3) 背景减除处理
# 应用背景减除
fgmask = fgbg.apply(frame)
cv2.imshow('fgmask', fgmask)
fgbg.apply(frame)
应用之前创建的背景减除器fgmask
是二值图像(前景为白色,背景为黑色)(4) 形态学开运算去噪
# 形态学开运算去噪
fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
cv2.imshow('fgmask1', fgmask_new)
cv2.morphologyEx()
执行形态学操作cv2.MORPH_OPEN
表示开运算(先腐蚀后膨胀)kernel
是之前定义的3×3十字形结构元素 # 寻找轮廓
contours, h = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
# 计算轮廓周长
perimeter = cv2.arcLength(c, True)
# 过滤小轮廓
if perimeter > 100:
# 获取边界矩形
x, y, w, h = cv2.boundingRect(c)
# 绘制矩形框
fgmask_new_rect = cv2.rectangle(frame, (x,y), (x+w, y+h), (0,255,0), 2)
cv2.imshow('fgmask_new_rect', fgmask_new_rect)
# 退出条件
k = cv2.waitKey(50)
if k == 27:
break
这段代码完成了运动目标检测的最后关键步骤:轮廓查找、目标筛选和标记。下面我将详细解释每一部分:
(1)轮廓查找
contours, h = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.findContours()
在二值图像中查找轮廓fgmask_new
:经过去噪处理的前景掩码图像cv2.RETR_EXTERNAL
:只检测最外层轮廓cv2.CHAIN_APPROX_SIMPLE
:压缩水平、垂直和对角线段,只保留端点contours
:找到的轮廓列表,每个轮廓是点的数组h
:轮廓的层次信息(这里未使用)(2)轮廓处理循环
for c in contours:
# 计算轮廓周长
perimeter = cv2.arcLength(c, True)
cv2.arcLength(c, True)
计算轮廓周长
True
表示轮廓是闭合的(3)轮廓筛选
# 过滤小轮廓
if perimeter > 100:
(4)目标标记
# 获取边界矩形
x, y, w, h = cv2.boundingRect(c)
# 绘制矩形框
fgmask_new_rect = cv2.rectangle(frame, (x,y), (x+w, y+h), (0,255,0), 2)
cv2.boundingRect(c)
获取轮廓的最小外接矩形
cv2.rectangle()
在原图上绘制绿色矩形框
(0,255,0)
:绿色(BGR格式)2
:线宽(5)结果显示与退出控制
cv2.imshow('fgmask_new_rect', fgmask_new_rect)
# 退出条件
k = cv2.waitKey(50)
if k == 27:
break
waitKey(50)
等待50ms,并检查按键
混合高斯模型(MOG2)能够:
开运算(MORPH_OPEN)过程:
findContours
查找前景中的连通区域arcLength
计算轮廓周长用于过滤小噪声boundingRect
获取物体最小外接矩形运行程序后会显示四个窗口:
本文介绍了基于OpenCV的视频运动目标检测实现方法。通过背景建模、形态学处理和轮廓分析等技术,我们能够有效地检测和标记视频中的运动物体。这种方法计算效率高,适合实时应用场景。
完整代码已在上文给出,读者可以自行尝试并调整参数观察不同效果。OpenCV提供了丰富的计算机视觉功能,值得深入学习和探索。