When testing the video playback example from the OpenCV introductory video tutorial, my videos (.m4v and .mov) always freeze for a little bit after they are done and then throws this error message:
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-33-6ff11ed068b5> in <module>()
15
16 # Our operations on the frame come here
---> 17 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
18
19 # Display the resulting frame
error: /home/user/opencv-2.4.9/modules/imgproc/src/color.cpp:3737: error: (-215) scn == 3 || scn == 4 in function cvtColor
My interpretation is that this is because the last frame
will be empty and lack the channels that cvtColor()
expects and the image can therefore not be displayed. If I modify the example code slightly and replace the while(True)
with a for loop that ends after the last frame in the video, I get no such message and the video window closes instead of freezing.
However, I assume there is a reason to why this is not the default behaviour in OpenCV and I'm afraid my modification will screw something up further down the road (completely new to OpenCV). So now I would like input on a few things:
- Why is the
while(True)
the default for showing the video, since it is freezing and throwing an error message (if this is not unique to my setup)? - Is it safe to have the for loop or should I stick to
while(True)
and wait for the error message every time I play a video? - Is there a preferred way to have OpenCV exit video playback gracefully?
I have tried the suggestions here and they did help with not freezing up the kernel completely, but the video still freezes and the error message still shows. The for loop alternative seems smoother.
I'm using the Ipython Notebook with Python 2.7.9 and OpenCV 2.4.9 on Ubuntu 14.04. Below is the code I'm executing.
import cv2
video_name = '/path/to/video'
cap = cv2.VideoCapture(video_name)
# while(True): #causes freeze and throws error
for num in range(0,int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()