背景建模(混合⾼斯模型)----opencvpython(附代码)
混合⾼斯模型进⾏背景建模
项⽬理论和源码来⾃唐宇迪opencv项⽬实战
混合⾼斯模型的原理
⽤混合⾼斯背景建模提取出基于⼆值化图像中的运动⽬标。对于输⼊的⼀段视频⽂件,⽆论是提取视频中⾏⼈的运动情况还是车的运动情况,某⼀帧图像以某⼀像素点为中⼼和其相邻像素点呈现⾼斯分布。
如果像素点的值偏离中⼼值较远,那么,这个像素值属于前景,如果像素点的值偏离中⼼值很近(在⼀定⽅差范围内),那么可以说这个点属于背景。理论上,如果不存在任何⼲扰的话,是可以准确区分前景和背景的。
简单来说,
创建第⼀个⾼斯模型:对于输⼊的视频⽂件假设⼀共有T帧数据,⽤第⼀帧第⼀个像素点对第⼀个⾼斯模型的期望值μ1进⾏初始化,σ1⽤默认值来初始化。
下⼀帧图⽚对应相同位置的像素点为μ2,与μ1的差值和3×σ1的数值⽐较。如果差距较⼩,则把第⼆帧与第⼀帧图⽚在同⼀像素点上的分布视为相同的⾼斯分布。并且更新当前分布的μ和σ值。如果传⼊⼼得⼀帧图⽚μ2与μ1相差较⼤,则说明新传⼊的帧与上⼀真图⽚在该像素点位置属于不同的分布,则利⽤新传⼊的⼀帧再建⽴⼀个新的分布,⽤新传⼊⼀帧来初始化新的分布的μ和σ值。
对于⼀个T帧的视频流数据,通常设置3-5个不同的⾼斯分布。
创建⾼斯混合模型的过程可以看作是⼀个不断学习的过程。对于⼀个已经完成学习的模型,在测试过程中,输⼊⼀张图⽚某⼀像素点和该像素点已经建⽴好的模型进⾏对⽐,有较⼤差异,说明该像素点为前景图像。则说明该像素点属于我们要识别的运动的物体。将前景像素点⽤255来赋值,背景像素点⽤0来赋值。
理论上,如果不存在任何⼲扰的话,是可以准确区分前景和背景的。
但实际情况下,视频会受到很多因素影响,光线亮或暗,摄像头可能出现抖动,画⾯中可能存在摆动的物体。在混合⾼斯模型中这些因素会造成⼲扰。
混合⾼斯模型适合处理缓慢运动的物体,⽽频繁变化的物体像素点可能会被视为噪声。
⽣成⾼斯模型的代码:
背景建模的代码如下:
import numpy as np
import cv2
cap = cv2.VideoCapture('test.avi')
# cap = cv2.VideoCapture(0)
kernel = StructuringElement(cv2.MORPH_ELLIPSE,(3,3))
fgbg = ateBackgroundSubtractorMOG2()
while(True):
ret, frame = ad()
fgmask = fgbg.apply(frame)
fgmask = phologyEx(fgmask, cv2.MORPH_OPEN, kernel)
im, contours, hierarchy = cv2.findContours(fgmask, 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)
cv2.imshow('frame',frame)
cv2.imshow('fgmask', fgmask)
k = cv2.waitKey(150)&0xff
if k ==27:
break
cv2.destroyAllWindows()
MORPH_RECT MORPH_CROSS MORPH_ELLIPSE 矩形交叉形椭圆形
⽣成的结构通常⽤于形态学操作(腐蚀、膨胀)
然后调⽤这个混合⾼斯模型的函数⽤于背景建模ateBackgroundSubtractorMOG2(),前⾯解释的那么多原理就是通过这⼀句代码实现的。
然后⽤循环来读取视频中的每⼀帧图⽚:
while(True):
ret, frame = ad()# 有两个返回值,第⼀个返回值表⽰是否读取到图⽚,返回True或者False,第⼆个参数表⽰截取到的每⼀帧图⽚。
fgmask = fgbg.apply(frame)
fgmask = phologyEx(fgmask, cv2.MORPH_OPEN, kernel)
im, contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rectangle函数opencv
对于读取到的每⼀帧图⽚,将混合⾼斯模型应⽤于每⼀张图⽚。
还记得前⾯那个⼈⼤⼩为(3,3)的椭圆形的内核吗,⽤作形态学开运算,作⽤是去除噪声。
然后对于每⼀张图⽚,查外轮廓
for c in contours:
perimeter = cv2.arcLength(c,True)
if perimeter >188:
x,y,w,h = cv2.boundingRect(c)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。