目录
一、为什么要对视频背景建模进行图像处理?
背景建模是计算机视觉领域中的一项重要技术,它可以将图像中的前景物体与背景分离,从而实现对前景物体的跟踪、识别等操作。通过对一段时间内的图像序列进行分析,提取出图像中的背景信息,并将其建模成一个背景模型,可以为后续的目标检测、跟踪、分割等任务提供基础。例如,在实际应用中我们可以通过背景建模图像处理,对人物进行分割,从而达到筛选人和物的目标,可以应用在人数统计,人物追踪等方面。
二、实际案例应用展示
下面通过实际的视频进行演示
1、读取视频并对视频进行形态学处理
cap = cv2.VideoCapture('test.avi')
# getStructuringElement(shape, ksize, anchor=None)得到一个卷积核。主要用于后续的腐蚀、膨胀、开、闭等运算。
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
#创建混合高斯模型,用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2()
相关参数解释:
cv2.VideoCapture:
OpenCV中用于捕获或读取视频的类。cv2.getStructuringElement(cv2.MORPH_CROSS,(16,16)):
创建一个形态学核,这个核是一个5x5的十字形结构元素。形态学操作常常用于图像处理中以消除噪声、分割图像或测量图像中的形状。在这里,cv2.MORPH_CROSS
定义了结构元素的形状为十字形,而(16,16)
定义了十字形的大小。cv2.createBackgroundSubtractorMOG2():
创建了一个背景减除器。背景减除是从视频或图像序列中提取前景对象(移动物体)的一种方法。使用高斯混合模型来模拟背景,对前景对象进行检测。
混合高斯模型(MOG2)假设每个像素点的值服从一个高斯分布,通过计算每个像素点的高斯分布参数来区分前景物体和背景。这种方法可以适应背景的变化,但是需要训练过程。
2、提取运动对象轮廓
while(True):
ret, frame = cap.read() #ret:True表示正常读取到图像,frame:从视频中获取当前一帧图片
cv2.imshow('frame',frame)
fgmask = fgbg.apply(frame) #视频处理
cv2.imshow('fgmask', fgmask)
fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)#开运算去噪点,先腐蚀后膨胀。
#寻找视频中的轮廓
_,contours,h = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
在这里,对视频帧进行处理和分析,其中使用到了背景减除器进行前景物体的提取,并对提取出来的前景物体进行了形态学开运算处理,最后通过findContours函数找到物体的轮廓。
相关参数详细解释:
fgbg.apply(frame):
使用背景减除器fgbg
对帧frame
进行处理,以提取前景对象。cv2.morphologyEx(f1,cv2.MORPH_OPEN,kernel):
使用形态学开运算对提取的前景对象进行处理,以消除小的对象和噪声。_,contours,h = cv2.findContours(f1_new,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE):
查找提取的前景对象中的轮廓。contours
是一个列表,其中包含每个轮廓的点。
3、前景提取和轮廓检测
for c in contours:
#计算各轮廓的周长
perimeter = cv2.arcLength(c,True)
if perimeter > 188:
#找到一个直矩形(不会旋转)
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(100) & 0xff
if k == 27:
break
相关参数解释:
cv2.arcLength(c,True):
计算轮廓c
的长度。cv2.arcLength
函数计算的是轮廓的欧氏长度,即轮廓上所有点的直线距离。True
参数表示计算的是凸包的长度。x,y,w,h = cv2.boundingRect(c):
获取轮廓c
的边界框。cv2.boundingRect
函数返回一个矩形的左上角坐标(x
,y
)以及矩形的宽度(w
)和高度(h
)。f1_new_reck = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2):
在原始帧frame
上绘制一个矩形,这个矩形与轮廓c
的边界框相对应。矩形的颜色是绿色(RGB值为(0,255,0)
),并且线宽为2。k = cv2.waitKey(100) & 0xff:
等待一段时间(100毫秒),并捕获用户按下的键。cv2.waitKey
函数返回一个整数,表示用户按下的键的ASCII码。& 0xff
是将返回的整数转换为无符号整数。if k == 27:
检查用户是否按下了'Esc'键(ASCII码为27)。如果用户按下了'Esc'键,则执行下面的代码块。即执行break,程序退出循环。
总之,对于每个轮廓,如果其长度大于300,就在原始帧上绘制该轮廓的边界框,并显示绘制了边界框的帧。如果用户按下'Esc'键,程序会立即退出。
4、完整代码及结果展示
import numpy as np
import cv2
#经典的测试视频
cap = cv2.VideoCapture('test.avi')
# getStructuringElement(shape, ksize, anchor=None)得到一个卷积核。主要用于后续的腐蚀、膨胀、开、闭等运算。
# 参数:shape:设定卷积核的形状,可选如下三个参数:
# ①:MORPH_RECT(矩形卷积核)
# ②:MORPH_CROSS(十字形卷积核)
# ③:MORPH_ELLIPSE(椭圆形卷积核)
# ksize:设定卷积核的大小、
# anchor:表示描点的位置,一般 c = 1,表示描点位于中心
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
#创建混合高斯模型,用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2()
while(True):
ret, frame = cap.read() #ret:True表示正常读取到图像,frame:从视频中获取当前一帧图片
cv2.imshow('frame',frame)
fgmask = fgbg.apply(frame) #视频处理
cv2.imshow('fgmask', fgmask)
fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)#开运算去噪点,先腐蚀后膨胀。
#寻找视频中的轮廓
_,contours,h = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
#计算各轮廓的周长
perimeter = cv2.arcLength(c,True)
if perimeter > 188:
#找到一个直矩形(不会旋转)
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(100) & 0xff
if k == 27:
break
人物背景提取:
原图及人物提取对比图:
注:由于此处使用的文件为视频文件,故具体效果不一定相同,效果根据所使用的视频文件而定。上述案例视频文件如有需要可在下列提取https://pan.baidu.com/s/1fX29gKgO7uo3GsTVLk9XeQ 提取码: we46
三、总结
在计算机视觉领域中,视频背景建模和图像处理技术是两个非常重要的研究方向。将它们结合应用可以为许多实际应用场景提供强大的支持。不同的应用场景具有不同的特点和要求,需要选择合适的背景建模方法和图像处理算法,以确保系统的适应性。而且数据的质量和完整性对系统的性能和准确性具有重要影响。因此,需要选择高质量的数据源和合适的预处理方法,以提高系统的性能和准确性。