使用cv2.fillPoly与位运算处理视频特定区域时出现img data type=17不支持错误的技术求助
解决OpenCV fillPoly在视频处理中崩溃的问题
我帮你排查了代码里的几个关键问题,这才导致视频处理时内核崩溃——图片上正常是因为单张图片读取不会出现帧为空的情况,而视频是逐帧读取,很容易遇到无效帧的情况。咱们一步步拆解问题并修复:
问题根源
- 帧读取顺序错误:你现在是先调用
roi(frame)再判断ret是否为True,当视频读到结尾或者帧损坏时,frame会是无效值,这时候np.zeros_like(frame)会生成不符合OpenCV要求的数组类型,直接触发fillPoly的参数错误。 - 颜色通道不匹配:如果你的视频是彩色(3通道BGR格式),
mask会是3通道数组,但你用单值(255)填充,通道数不匹配导致OpenCV无法处理。 - 返回值错误:你的
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
相关产品推荐
相关产品推荐

