sayem48 sayem48 - 1 year ago 87
Python Question

Can't open saved video using OpenCV in Python (Windows 10)

Code reads the

train1.mov
file, shows
cv2.imshow('res', res)
also saves a file named
output.avi
. Problem is, output.avi is around 40 kb and empty. But
cv2.imshow('res', res)
shows the whole video. Then show the following error.

Python Code:

import numpy as np
import cv2

cap = cv2.VideoCapture('C:\\Users\\khan1\\Desktop\\python project\\color_threshold\\train1.mov')

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('C:\\Users\\khan1\\Desktop\\python project\\color_threshold\\output.avi',fourcc, 20.0, (640,480))

while(cap.isOpened()):
_, frame = cap.read()

hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_green = np.array([40, 60, 60])
upper_green = np.array([80, 255, 255])

mask = cv2.inRange(hsv, lower_green, upper_green)
mask = cv2.GaussianBlur(mask, (7, 7), 0)
res = cv2.bitwise_and(frame, frame, mask=mask)

out.write(res)

cv2.namedWindow("res", cv2.WINDOW_NORMAL)
cv2.imshow('res', res)
if (cv2.waitKey(1) & 0xFF) == ord('q'): # Hit `q` to exit
break

# Release everything if job is finished
out.release()
cap.release()
cv2.destroyAllWindows()


Error:

OpenCV Error: Assertion failed ((scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F)) in cv::cvtColor, file C:\build\master_winpack-bindings-win32-vc14-static\opencv\modules\imgproc\src\color.cpp, line 9815
Traceback (most recent call last):
File "C:/Users/khan1/Desktop/python project/color_threshold/savevid.py", line 19, in <module>
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
cv2.error: C:\build\master_winpack-bindings-win32-vc14-static\opencv\modules\imgproc\src\color.cpp:9815: error: (-215) (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) in function cv::cvtColor


Process finished with exit code 1


How can I fix it?

Answer Source

It's clear your error is happening on the last frame; that's why your imshow is still working the whole time but it errors out and doesn't complete writing the video which happens after the while loop.

The first value returned by cap.read() is a boolean on whether or not the frame exists/was read. So you can simply insert an if-else block in your code to perform your processing if the frame was read, and quit the while loop if not, so that you can finish writing the frame.

This should patch up your code:

import numpy as np
import cv2

cap = cv2.VideoCapture('C:\\Users\\khan1\\Desktop\\python project\\color_threshold\\train1.mov')

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('C:\\Users\\khan1\\Desktop\\python project\\color_threshold\\output.avi',fourcc, 20.0, (640,480))

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret:

        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        lower_green = np.array([40, 60, 60]) 
        upper_green = np.array([80, 255, 255])

        mask = cv2.inRange(hsv, lower_green, upper_green)
        mask = cv2.GaussianBlur(mask, (7, 7), 0)
        res = cv2.bitwise_and(frame, frame, mask=mask)

        out.write(res)

        cv2.namedWindow("res", cv2.WINDOW_NORMAL)
        cv2.imshow('res', res)
        if (cv2.waitKey(1) & 0xFF) == ord('q'): # Hit `q` to exit
            break
    else:
        break

# Release everything if job is finished
out.release()
cap.release()
cv2.destroyAllWindows()

See an example of this same process here.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download