运动图像分割-前景目标提取

运动图像分割

在一个视频文件中,分割出前景目标,之前网上看了一些方法,包括帧差法、GMM等。
帧差法太简单,但是只能提取轮廓,而且会出现前景目标部分区域消失的问题。GMM对于小白菜来说有点高深,看不太懂。
接下来给大家介绍一下帧差和一种能够提取前景目标区域的一种方法。

帧差法

二帧差法:
利用后一帧图像与前一帧图像的差值,取差值的绝对值作为运动目标的检测帧,将检测帧进行使用合适阈值进行二值化,再通过一些常用的图像处理算法进行图像增强。其实二帧差法利用了一阶梯度的思想,对于背景点,变化很小,所以两帧的差很小;对于前景点,像素变化比较大,帧差比较大。不足之处是对噪声比较敏感,如果帧率比较高,可能会出现前景目标整体消失的情况,如果前景目标部分区域未动的话,也会检测不到。
二帧差法流程图
来看一下二帧差的效果,分别用大目标分割和小目标分割测试。大目标可以通过形态学处理增强,小目标很难增强,因为如果膨胀腐蚀的话会改变目标的轮廓和大小,很难去控制。左图红色圈出的就是部分消失的情况。
二帧差法效果
三帧差法:
直接上流程图和结果,三侦差可以抑制一些噪声,但是还会出现前景目标部分消失的问题,因为用的是与操作,所以线条会细一点。
三侦差法流程图
在这里插入图片描述

背景建模法(名字很酷吧)

对于一段视频来说,每个像素点在每一帧的像素值既有可能是背景,也有可能是前景。对于视频文件来说,所有像素点就构成了一个随机过程。
由我们的任务目标,根据统计概率知识做出如下假设:
(1)对于同一个像素点,作为背景时的统计概率较高;
(2)背景的像素值是稳定的。

因此我们利用视频文件中每个像素点出现频率最高的像素值构建出一个背景模型,也就是最大概率准则。
然后再使用每一帧图片,与我们的背景模型在一个可接受域内做前景目标构造。
背景建模法流程图
看一下建立的背景:
均值背景可以看出前景目标的运动轨迹,大家可以试试。最大概率背景也就是我们上面提到的方法建立的背景,有点毛糙,可能是视频录制的不是很好,中值背景稍微光滑点。其实感觉在大多数情况下,中值背景应该和最大概率背景是一样的。
在这里插入图片描述
看一下,分割结果。背景建模法对于小目标检测还是很不错的感觉。
在这里插入图片描述
频域上使用背景建模法
接下来我们尝试把这种方法应用在频域上,将每一帧图片的傅里叶变换减去背景图的傅里叶变换,然后进行反变换得到运动目标的检测帧,然后再利用形态学方法将得到的二值图进行图像增强。效果如下图所示,其实在频域上减去背景的话并不会直接将背景减去,反而是一个类似图像融合的过程,把前景目标和建模的背景融合到了一起。
在这里插入图片描述
最后给大家分享一下背景建模法的代码把,因为个人编程能力有限,编程习惯不太好,不喜勿喷。

import cv2
import numpy as np
from collections import Counter

cap = cv2.VideoCapture("luren.mp4")
cap2 = cv2.VideoCapture("luren.mp4")

frameNum = 0
NpKernel1 = np.uint8(np.ones((3,3)))

NpKernel2 = np.uint8(np.ones((5,5)))

ret, frame = cap.read()
tempframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
h,w = tempframe.shape
tempframe=tempframe.reshape(-1)
pix_list = [[] for i in range(len(tempframe))]
pixbg_list = []
for i in range(len(tempframe)):
    pix_list[i].append(tempframe[i])
frameNum += 1

while cap.isOpened():
    ret, frame = cap.read()
    if ret == True:
        tempframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        tempframe = tempframe.reshape(-1)
        for i in range(len(tempframe)):
            pix_list[i].append(tempframe[i])
        frameNum += 1
        print(frameNum)
    else:
        break
cap.release()

for i in range(len(tempframe)):
   #pixbg_list.append(Counter(pix_list[i]).most_common(1)[0][0]) # 最大概率值
   # pixbg_list.append((np.sum(np.array(pix_list[i])) / len(pix_list[i])).astype(dtype='uint8')) #均值
   pixbg_list.append(np.median(np.array(pix_list[i])).astype(dtype='uint8')) # 中值

pixbg = np.array(pixbg_list).reshape(h,w)
print('ok')
# pixbg = cv2.medianBlur(pixbg, 3)
cv2.imshow('pixbg', pixbg)
cv2.waitKey(0)
while cap2.isOpened():
    cv2.waitKey(100)
    ret, frame = cap2.read()
    if ret == True:
        tempframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        threshold_frame = np.ones_like(tempframe)
        a = tempframe>=pixbg-10
        b = tempframe<=pixbg+10
        threshold_frame[a & b] = 0
        threshold_frame = threshold_frame * 255
        # erode_img = cv2.erode(threshold_frame, NpKernel1)
        # erode_img = cv2.erode(erode_img, NpKernel1)
        # #
        # # erode_img = cv2.erode(threshold_frame, NpKernel1)
        # # dilate_img = cv2.dilate(erode_img, NpKernel2)
        # #
        # dilate_img = cv2.dilate(erode_img, NpKernel2)
        # erode_img = cv2.erode(dilate_img, NpKernel2)
        # dilate_img = cv2.dilate(erode_img, NpKernel2)
        median = cv2.medianBlur(threshold_frame, 3)
        cv2.imshow('Frame', frame)
        cv2.imshow('threshold_frame', median)

        if cv2.waitKey(33) & 0xFF == ord('q'):
            break
    else:
        break
cap2.release()
cv2.destroyAllWindows()
  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
视频运动前景目标提取算法计算机视觉的一个重要问题,本质上是指从视频提取前景目标,即区别于背景的物体或人。 下面是一种简单的视频运动前景目标提取算法的实现,基于背景差分的思想: 1. 视频预处理 将视频转换为灰度图像,并进行高斯滤波和帧差处理,以减少噪声干扰和提取运动目标。 2. 建立背景模型 使用前几帧图像建立背景模型,在算法运行过程,不断更新背景模型。 3. 背景差分 将当前帧图像背景模型相减,得到运动目标的二值图像。可以通过阈值分割方法前景目标提取来。 4. 目标跟踪 对提取前景目标进行形态学处理,如膨胀和腐蚀,以填充空洞和去除噪声。然后,可以使用目标跟踪算法,如卡尔曼滤波或者投影跟踪,对目标进行跟踪。 代码实现: ```python import cv2 import numpy as np # 视频路径 video_path = 'video.mp4' # 创建VideoCapture对象,读取视频 cap = cv2.VideoCapture(video_path) # 读取第一帧的图像作为背景 ret, background = cap.read() background_gray = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY) background_gray = cv2.GaussianBlur(background_gray, (5, 5), 0) # 设置阈值 threshold_value = 25 while True: # 读取视频帧 ret, frame = cap.read() if not ret: break # 转换为灰度图像 gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 高斯滤波 gray_frame = cv2.GaussianBlur(gray_frame, (5, 5), 0) # 帧差处理 diff = cv2.absdiff(background_gray, gray_frame) # 二值化处理 ret, thresh = cv2.threshold(diff, threshold_value, 255, cv2.THRESH_BINARY) # 执行形态学操作,去除噪声和填充空洞 kernel = np.ones((5, 5), np.uint8) thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2) # 显示前景目标 cv2.imshow('Foreground', thresh) # 按下q键退程序 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 cap.release() cv2.destroyAllWindows() ```
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值