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

Python视频目标检测与背景移除:代码报错修复请求

视频目标检测与背景移除代码修复方案

错误原因分析

  • background变量初始值为0,并非与视频帧同尺寸、同通道数的图像,执行cv2.bitwise_and时因输入尺寸/类型不匹配触发断言错误。
  • cv2.VideoWriter使用-1作为fourcc参数存在兼容性问题,部分环境下无法正确编码MP4文件。

修复后的颜色检测版代码

import cv2
import numpy as np
import time

video_capture = cv2.VideoCapture(0)
frame_width = int(video_capture.get(3))
frame_height = int(video_capture.get(4))

# 指定MP4兼容的编码格式
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output.mp4', fourcc, 10, (frame_width, frame_height), True)

# 等待3秒后捕获背景帧
time.sleep(3)
ret, background = video_capture.read()
if not ret:
    print("无法捕获背景帧")
    video_capture.release()
    exit()
background = np.flip(background, axis=1)  # 和后续帧保持镜像一致

while video_capture.isOpened():
    ret, image = video_capture.read()
    if not ret:
        break
    image = np.flip(image, axis=1)
    
    # 转换为HSV颜色空间,检测蓝色目标
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower_blue = np.array([94, 80, 2])
    upper_blue = np.array([126, 255, 255])
    mask_all = cv2.inRange(hsv, lower_blue, upper_blue)
    
    # 形态学操作优化掩码
    mask_all = cv2.morphologyEx(mask_all, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))
    mask_all = cv2.morphologyEx(mask_all, cv2.MORPH_DILATE, np.ones((3, 3), np.uint8))
    
    # 分离目标与背景
    mask2 = cv2.bitwise_not(mask_all)
    streamA = cv2.bitwise_and(image, image, mask=mask2)  # 保留非蓝色区域(原帧内容)
    streamB = cv2.bitwise_and(background, background, mask=mask_all)  # 蓝色区域替换为背景
    
    output = cv2.addWeighted(streamA, 1, streamB, 1, 0)
    out.write(output)
    cv2.imshow("cloak_trick", output)
    
    if cv2.waitKey(25) == 13:  # 回车键退出
        break

video_capture.release()
out.release()
cv2.destroyAllWindows()

通用人像分割替代方案(无需颜色检测)

如果需要检测人像并移除背景,推荐使用MediaPipe的人像分割模型,无需依赖颜色特征,保留RGB格式的人像目标:

import cv2
import mediapipe as mp
import numpy as np

mp_selfie_segmentation = mp.solutions.selfie_segmentation
segmentation_model = mp_selfie_segmentation.SelfieSegmentation(model_selection=1)

video_capture = cv2.VideoCapture(0)
frame_width = int(video_capture.get(3))
frame_height = int(video_capture.get(4))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('portrait_output.mp4', fourcc, 10, (frame_width, frame_height), True)

# 自定义背景(可以替换为任意图像路径)
background = cv2.imread('background.jpg')
background = cv2.resize(background, (frame_width, frame_height))

while video_capture.isOpened():
    ret, frame = video_capture.read()
    if not ret:
        break
    
    # 镜像翻转帧
    frame = np.flip(frame, axis=1)
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    
    # 执行人像分割
    results = segmentation_model.process(rgb_frame)
    mask = results.segmentation_mask
    
    # 将掩码转换为3通道,用于与帧和背景做融合
    mask = np.stack((mask,)*3, axis=-1)
    mask = cv2.GaussianBlur(mask, (5,5), 0)  # 模糊掩码边缘,避免生硬
    
    # 融合人像与背景,保留RGB格式的人像
    output = frame * mask + background * (1 - mask)
    output = output.astype(np.uint8)  # 转换为OpenCV支持的8位格式
    
    out.write(output)
    cv2.imshow("Portrait Segmentation", output)
    
    if cv2.waitKey(25) == 13:
        break

video_capture.release()
out.release()
cv2.destroyAllWindows()

说明

  • 颜色检测版适合特定颜色的目标(如蓝色衣物),通过HSV阈值分离目标
  • 人像分割版适合通用人像场景,无需指定颜色,分割精度更高,背景可自定义为任意图像

内容的提问来源于stack exchange,提问作者hh tt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:31:50