OpenCV背景建模,图像跟踪

背景建模

简介

背景建模简单来说,在视频监视中我们对移动的人感兴趣,对视频里的环境和其他静物不感兴趣。因此我们关注的运动的人为前景,而相对静止的环境就为背景,为获取运动的区域方法就叫做背景建模。

帧差法

帧差法:由于物体移动,目标区域的值在变换。而静止区域的值将不会发生变化。将视频的两帧的画面值相减,相对静止的区域差值很小,运动区域的会出现一定的差值,通过阈值的设置,就可以实现目标的检测。
公式:
D n ( x , y ) = ∣ f n ( x , y ) − f n − 1 ( x , y ) ∣ D_n(x,y)=|f_n(x,y)-f_{n-1}(x,y)| Dn(x,y)=fn(x,y)fn1(x,y)
R n ( x , y ) = { 255 , D ( x , y ) > T 0 , e l s e R_n(x, y)= \begin{cases} 255, D(x, y)>T\\ 0,else \end{cases} Rn(x,y)={255,D(x,y)>T0,else
其中n为当前帧的画面,n-1为前一帧画面。两帧的差值,和阈值T作对比,大于阈值部分为255,小于阈值部分为0。
代码:

  • 通过视频截取了两帧的画面
  • 通过代码实现上方公式(注:彩色图片存在3个颜色通道)
    第一帧画面:
    在这里插入图片描述
    第二帧画面:
    在这里插入图片描述
# 导入opencv库
import cv2

# 加载图片
img1 = cv2.imread("C:/Users/98046/Desktop/video/image1.jpg") # 第一帧
img2 = cv2.imread("C:/Users/98046/Desktop/video/image2.jpg") # 第二帧

# 计算图片大小
height = img1.shape[0]
width = img1.shape[1]
print(img1.shape)
# 求差值
val = img1 - img2

# 根据阈值, 获取差值图像
for i in range(height):
    for j in range(width):
        if val[i, j][0] > 40 and val[i, j][1] > 40 and val[i, j][2] > 40:
            val[i, j][0] = 255
            val[i, j][1] = 255
            val[i, j][2] = 255
        else:
            val[i, j][0] = 0
            val[i, j][1] = 0
            val[i, j][2] = 0

cv2.imshow("val", val)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述
运动的人已经获取到了,虽然帧差法简单,但是容易出现噪声和空洞。

高斯混合模型法

原理

高斯混合模型过繁琐,下面是知乎大神的讲解。
高斯混合模型法,点击即可查看。

代码实现

import cv2
import numpy as np

# 测试视频
cap = cv2.VideoCapture("C:/Users/98046/Desktop/test.avi")
#cap = cv2.VideoCapture(0)
# 形态学操作
print(cap)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
fgbg = cv2.createBackgroundSubtractorMOG2()

print(kernel)
while (1):
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    # 形态学开运算去噪声
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    # 寻找视频中的轮廓
    countours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for c in countours:
        # 计算个轮廓的周长
        p = cv2.arcLength(c, True)
        if p > 200:
            x, y, w, h = cv2.boundingRect(c)
            # 画出这个矩形
            cv2.rectangle(frame, (x, y), (x+w, y+h),(0, 255, 0), 2)
    cv2.imshow("imshow", frame)
    cv2.imshow("fgmask", fgmask)
    k = cv2.waitKey(150) & 0xff
    if k == 27:
        break

cap.release();
cv2.destroyAllWindows();

运行结果:
1.图片演示:
在这里插入图片描述
2.视频演示:
点击观看

测试的视频文件

在这里插入图片描述

关注回复“背景建模”,即可获取测试视频和源码

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值