【深度学习】OpenCV 视频分析实战:背景建模 + 形态学处理实现运动目标检测 文章目录完整代码一览打开视频与定义内核定义结构内核创造背景减除器视频逐帧处理读取帧前景掩码去除噪声分离目标轮廓检测与过滤显示结果与退出控制释放资源调优建议完整代码一览import cv2 capcv2.VideoCapture(test.avi)kernelcv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))fgbgcv2.createBackgroundSubtractorMOG2()whileTrue:ret,freamcap.read()ifnot ret:breakcv2.imshow(fream,fream)fgmaskfgbg.apply(fream)cv2.imshow(famask,fgmask)fgmask_newcv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)cv2.imshow(famask1,fgmask_new)contourscv2.findContours(fgmask_new,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]forc in contours:perimetercv2.arcLength(c,True)ifperimeter188:x,y,w,hcv2.boundingRect(c)fgmask_new_rectcv2.rectangle(fream,(x,y),(xw,yh),(0,0,255),2)cv2.imshow(fgmask_new_rect,fgmask_new_rect)kcv2.waitKey(60)ifk27:# ESC 键退出breakcap.release()cv2.destroyAllWindows()打开视频与定义内核import cv2 capcv2.VideoCapture(test.avi)cv2.VideoCapture创建一个视频捕获对象参数可以是视频文件路径或摄像头设备号0 表示默认摄像头。这里指定了 ‘test.avi’表示读取本地视频文件。定义结构内核kernelcv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))定义了一个 十字形结构内核尺寸为 3×3。这个内核将用于形态学操作开运算。十字形结构适合处理细长的噪声或连接断裂的前景区域。创造背景减除器fgbgcv2.createBackgroundSubtractorMOG2()创建一个 MOG2 背景减除器。MOG2 是基于高斯混合模型的背景建模算法它能自动学习背景并且能区分阴影通过阴影检测参数。我们使用默认参数即可。视频逐帧处理读取帧whileTrue:ret,freamcap.read()ifnot ret:breakcv2.imshow(fream,fream)#无限循环不断读取视频的下一帧。cap.read() 返回两个值ret 表示是否成功读取布尔值fream 是当前帧图像注意变量名拼写错误但无影响。如果 ret 为 False说明视频已读完或读取失败则跳出循环,同时显示原始帧方便观察视频内容。前景掩码fgmaskfgbg.apply(fream)cv2.imshow(famask,fgmask)fgbg.apply(fream) 将当前帧输入到背景减除器中返回一个二值图像 fgmask白色255区域表示前景运动物体黑色0区域表示背景。显示这个前景掩码你会看到运动目标呈白色块状但往往会有很多噪点小白色斑点和内部空洞。运行结果去除噪声分离目标fgmask_newcv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)cv2.imshow(famask1,fgmask_new)cv2.morphologyEx 执行形态学操作这里用的是 开运算MORPH_OPEN即先腐蚀后膨胀。开运算的效果去除细小的白色噪点相当于“擦掉”孤立的小白点同时断开黏连在一起的大块目标如果两个物体靠得太近开运算能稍微分开它们。使用我们之前定义的 3×3 十字内核强度适中不会过度破坏目标轮廓。处理后前景掩码会更干净噪声减少。运行结果轮廓检测与过滤contourscv2.findContours(fgmask_new,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]forc in contours:perimetercv2.arcLength(c,True)ifperimeter188:x,y,w,hcv2.boundingRect(c)fgmask_new_rectcv2.rectangle(fream,(x,y),(xw,yh),(0,0,255),2)cv2.findContours 在去噪后的前景掩码上查找轮廓。RETR_EXTERNAL 只检测最外层轮廓CHAIN_APPROX_SIMPLE 压缩轮廓点以节省内存。遍历每个轮廓 ccv2.arcLength(c, True) 计算轮廓的周长闭合。如果周长 大于 188则认为这个目标足够大过滤掉小噪点然后cv2.boundingRect© 获取外接矩形的左上角坐标 (x,y) 和宽高 (w,h)。cv2.rectangle 在原图 fream 上绘制红色矩形框线宽 2。显示结果与退出控制cv2.imshow(fgmask_new_rect,fgmask_new_rect)kcv2.waitKey(60)ifk27:break显示绘制了矩形框的帧。运行结果释放资源cap.release()cv2.destroyAllWindows()释放视频捕获资源关闭所有 OpenCV 窗口。调优建议关键参数调优周长阈值 188需要根据视频中目标的大小调整。如果目标较小可降低阈值如果背景噪声多可提高阈值。内核尺寸3×3 适合小目标若目标大或噪声多可增大内核如 5×5增强去噪效果。形态学操作开运算适合去除噪声如果前景内部空洞多可改用闭运算先膨胀后腐蚀填充空洞。等待时间 waitKey数值越大播放越慢若设为 1则播放尽可能快。如果视频没有运动物体前景掩码将是全黑矩形框也不会出现。