不支持 img 数据类型 = 17

img data type = 17 is not supported

我有一个视频,我正在尝试使用 cv2.polyfill 和按位运算来显示特定区域。当我在图像上执行此操作时它工作正常但在视频上执行此操作时出现以下错误。我早些时候用另一个 picture/video 做这个没有问题。要显示的区域确实显示为冻结图片,但也会使内核崩溃。代码是:

import cv2
import numpy as np
   cap = cv2.VideoCapture("heartvideo.wmv",0)

def roi(frame): 
  mask = np.zeros_like (frame)
  array = np.array([[148,550],[300,650],[400,680],[800,680],[880,560],[555,70],[492,50]])
  contours = np.array([[50,50], [50,150], [150,150], [150,50]])
  cv2.fillPoly(mask, pts = [array], color =(255))
  masked = cv2.bitwise_and(mask,frame)
  return mask


while(cap.isOpened()): # while video is initialised
  ret, frame = cap.read() #reads the video bit by bit
  adj = roi(frame)
 
  if ret:
    cv2.imshow("Image", adj)
  else:
    cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

  if cv2.waitKey(15) & 0xFF == ord('q'):
    break


cap.release()
cv2.destroyAllWindows()

错误: OpenCV(4.5.3) :-1: 错误: (-5:Bad argument) in function 'fillPoly'

Overload resolution failed:

  • img data type = 17 is not supported
  • Expected Ptr<cv::UMat> for argument 'img'

问题是您使用的是 3 通道 BGR 掩码(数据类型 17 是 3 通道图像)。您使用 np.zeros_like(frame) 来设置掩码,这意味着它将具有与您传入的图像完全相同的尺寸。如果您打算将其设置为单通道图像,则应设置尺寸。

我不确定您使用的是哪个版本的 OpenCV,我无法用 OpenCV 4.4 复制错误。在此版本中,即使您已将 1 通道颜色指定为 fillPoly 参数,它也允许 3 通道图像,尽管它通过假设您的意思是 (255,0,0) 作为颜色来实现这一点。可能是在不同版本的 OpenCV 上,颜色尺寸必须与图像尺寸相匹配,并且它对此有所抱怨。

试试这个修改后的代码版本,看看它是否有效。

import cv2
import numpy as np

def roi(frame): 
  # draw a polygon on mask
  height,width = frame.shape[:2];
  mask = np.zeros((height, width), np.uint8);
  array = np.array([[148,550],[300,650],[400,680],[800,680],[880,560],[555,70],[492,50]])
  contours = np.array([[50,50], [50,150], [150,150], [150,50]])
  cv2.fillPoly(mask, pts = [array], color =(255))

  # mask stuff on frame
  # masked = cv2.bitwise_and(mask,frame)
  copy = np.zeros_like(frame);
  copy[mask == 255] = frame[mask == 255];
  return copy;

# open video
cap = cv2.VideoCapture("heartvideo.wmv", 0);

while(cap.isOpened()): # while video is initialised
  ret, frame = cap.read() #reads the video bit by bit
 
  if ret:
    adj = roi(frame)
    cv2.imshow("Image", adj)
  else:
    cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

  if cv2.waitKey(15) == ord('q'):
    break

cap.release()
cv2.destroyAllWindows()