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

使用cv2.fillPoly与位运算处理视频特定区域时出现img data type=17不支持错误的技术求助

解决OpenCV fillPoly在视频处理中崩溃的问题

我帮你排查了代码里的几个关键问题,这才导致视频处理时内核崩溃——图片上正常是因为单张图片读取不会出现帧为空的情况,而视频是逐帧读取,很容易遇到无效帧的情况。咱们一步步拆解问题并修复:

问题根源

  1. 帧读取顺序错误:你现在是先调用roi(frame)再判断ret是否为True,当视频读到结尾或者帧损坏时,frame会是无效值,这时候np.zeros_like(frame)会生成不符合OpenCV要求的数组类型,直接触发fillPoly的参数错误。
  2. 颜色通道不匹配:如果你的视频是彩色(3通道BGR格式),mask会是3通道数组,但你用单值(255)填充,通道数不匹配导致OpenCV无法处理。
  3. 返回值错误:你的roi函数最后返回的是mask遮罩层,而不是你想要的遮罩叠加后的视频帧,这也会导致显示异常。

修复后的完整代码

import cv2
import numpy as np

# 初始化视频捕获,去掉多余的0参数,让OpenCV自动选择合适的解码器
cap = cv2.VideoCapture("heartvideo.wmv")

def roi(frame):
    # 创建和原帧通道数一致的遮罩
    mask = np.zeros_like(frame)
    # 目标区域点集,注意要和帧尺寸匹配(可通过frame.shape查看帧的宽高)
    array = np.array([[148,550],[300,650],[400,680],[800,680],[880,560],[555,70],[492,50]], dtype=np.int32)
    # 彩色帧用3通道颜色值(比如白色),灰度帧用单值255即可
    cv2.fillPoly(mask, pts=[array], color=(255, 255, 255))
    # 位运算保留帧的目标区域,注意顺序是frame在前
    masked = cv2.bitwise_and(frame, mask)
    return masked

while cap.isOpened():
    ret, frame = cap.read()
    # 先确认帧读取成功,再进行处理
    if ret:
        adj = roi(frame)
        cv2.imshow("Image", adj)
    else:
        # 重置到视频开头循环播放,重置后要跳过本次循环避免处理空帧
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
        continue
    # 控制帧率并监听退出按键
    if cv2.waitKey(15) & 0xFF == ord('q'):
        break

# 释放资源
cap.release()
cv2.destroyAllWindows()

额外注意事项

  • 先打印frame.shape确认视频帧的尺寸,确保你的目标区域坐标array没有超出帧的宽高范围,越界也可能导致异常。
  • 如果你的视频是灰度格式,把color=(255,255,255)改成color=(255)即可。
  • WMV格式可能需要额外解码器支持,如果还是有问题,可以尝试把视频转成MP4格式再测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:52:33