You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用BackgroundSubtractorMOG2背景减法后,如何获取目标原始颜色?

获取BackgroundSubtractorMOG2掩码对应的原始目标颜色

要从MOG2输出的二值掩码里拿到运动目标的原始颜色,其实很简单——核心就是用掩码和原始帧做按位与操作,让掩码中白色(代表前景目标)的区域保留原始帧的像素,黑色区域则置黑,这样就能精准提取出带原始色彩的目标了。

关键步骤说明

  • 首先确保你的掩码是单通道二值图(MOG2输出的fgmask本身就是单通道灰度图,满足要求)
  • 由于原始帧是三通道的BGR图像,需要先把单通道掩码转换成三通道格式,保证和原始帧通道数一致
  • 用cv2.bitwise_and将原始帧和转换后的掩码做运算,得到仅保留前景目标原始颜色的图像

修改后的完整代码(结合你的原有逻辑)

我已经把提取彩色目标的逻辑整合到你的代码里,还修正了原代码里的小笔误,调整了噪声过滤的阈值:

import cv2
import numpy as np

cap = cv2.VideoCapture("people.mkv")
kernel_dil = np.ones((10,10), np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
fgbg = cv2.createBackgroundSubtractorMOG2(history=0, varThreshold=444, detectShadows=False)

while True:
    ret, frame1 = cap.read()
    if not ret:  # 新增帧读取检查,避免视频结束后报错
        break
    frame = cv2.resize(frame1,(1364,700),fx=0,fy=0, interpolation = cv2.INTER_CUBIC)
    
    # 构建ROI掩码(保留你的原有逻辑)
    mask = np.zeros(frame.shape, dtype=np.uint8)
    mask.fill(255)
    roi_corners = np.array([[(11,652), (1353,652), (940,84), (424,84)]], dtype=np.int32)
    cv2.fillPoly(mask, roi_corners, 0)
    masking = cv2.bitwise_or(frame, mask)
    
    # 生成前景掩码(保留你的原有逻辑)
    fgmask = fgbg.apply(masking,mask)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    # 修正原代码的笔误:fgmask2改为fgmask
    dilation = cv2.dilate(fgmask, kernel_dil, iterations = 1)
    
    # --------------------- 核心:提取原始颜色的前景目标 ---------------------
    # 将单通道掩码转换为三通道,和原始帧通道数匹配
    fgmask_3ch = cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR)
    # 按位与操作,仅保留掩码白色区域的原始像素
    colored_foreground = cv2.bitwise_and(frame, fgmask_3ch)
    
    # 可选:如果想基于膨胀后的掩码提取更大范围的目标,用下面两行替换上面的
    # dilation_3ch = cv2.cvtColor(dilation, cv2.COLOR_GRAY2BGR)
    # colored_foreground = cv2.bitwise_and(frame, dilation_3ch)
    # ----------------------------------------------------------------------
    
    # 轮廓检测与绘制(调整面积阈值,过滤小噪声)
    (contours,hierarchy) = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    for pic, contour in enumerate(contours):
        area = cv2.contourArea(contour)
        x,y,w,h = cv2.boundingRect(contour)
        if area > 100:  # 原0.001阈值太小,改为实际有效的数值,避免检测到噪声
            cv2.rectangle(frame, (x,y), (x+w,y+h), (0,0,255), 2)
            cv2.putText(frame, 'People', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,0,0), 2, cv2.LINE_AA)
    
    # 新增显示彩色前景的窗口
    cv2.imshow("Colored Foreground", colored_foreground)
    cv2.imshow("FullScreen", frame)
    cv2.imshow("FGMask1", fgmask)
    cv2.imshow("FGMask2", dilation)
    
    key = cv2.waitKey(12)
    if key == ord("q"):
        break

# 释放资源(原代码遗漏,新增)
cap.release()
cv2.destroyAllWindows()

额外说明

  • 转换三通道掩码的原因:cv2.bitwise_and要求输入的两个图像必须通道数一致,原始帧是3通道BGR,所以需要把单通道灰度掩码转成3通道格式(每个通道的像素值和原灰度掩码一致)。
  • 面积阈值调整:原代码里的area>0.001几乎会把所有微小噪声都当成目标,实际使用时建议根据你的视频分辨率调整合适的阈值(比如100、200等)。

内容的提问来源于stack exchange,提问作者Syamim Amiruddin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:42:56