Ive got a video which ive im trying to show a specific region using cv2.polyfill and bitwise operation. When I do this on a image it works fine but when done on a video it comes up with the following error. Ive had no problems doing this earlier on with another picture/video. The region to be shown does show up as a frozen picture but also crashes the kernel. The code is:
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()
error: OpenCV(4.5.3) :-1: error: (-5:Bad argument) in function 'fillPoly'
Overload resolution failed:
- img data type = 17 is not supported
- Expected Ptr<cv::UMat> for argument 'img'
CodePudding user response:
The issue is that you're using a 3-channel BGR mask (datatype 17 is a 3-channel image). You used np.zeros_like(frame) to set your mask which means that it'll have the exact same dimensions as the image you passed in. If you meant for it to be a 1-channel image you should set the dimensions.
I'm not sure what version of OpenCV you're using and I can't replicate the error with OpenCV 4.4. On this version it allows a 3-channel image even if you've specified a 1-channel color as the fillPoly argument though it does this by assuming you meant (255,0,0) for the color. It could be that on a different version of OpenCV the color dimensions had to match the image dimensions and it's complaining about that.
Try out this revised version of the code and see if it works.
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()