Возможен случай, когда хотя бы один из кадров в вашем видео не был прочитан должным образом. Вот почему метод cv2.cvtColor
выдает ошибку, поскольку данные фрейма, которые вы предоставляете, пусты.
Вам следует рассмотреть возможность использования первого вывода cv2.VideoCapture.read()
, чтобы убедиться, что видеокадр был правильно захвачен, а затем записать его в файл. Первый вывод - это флаг, который определяет, был ли текущий кадр прочитан успешно. Кроме того, вам нужно обработать конец, где мы достигаем конца видео. В этом случае флаг будет False
, поэтому мы должны выйти из цикла. Наконец, если вы намерены писать кадры в градациях серого, в cv2.VideoWriter
есть необязательный пятый параметр, называемый isColor
, где мы можем установить значение False
, чтобы позволить нам напрямую писать кадры в градациях серого. Это означает, что звонок на cv2.cvtColor
больше не требуется.
Еще одна вещь, которую я бы порекомендовал, - это выводить ширину и высоту кадра из видеофайла, а не устанавливать их самостоятельно. Таким образом, разрешение на входе и выходе одинаково. Наконец, не забудьте освободить объект cv2.VideoWriter
, когда вы закончите, и я добавил дополнительную проверку видеофайла, чтобы проверить, правильно ли он открылся:
import numpy as np
import cv2
import sys
cap = cv2.VideoCapture('videos/output.avi')
# Check to see if the video has properly opened
if not cap.isOpened():
print("File could not be opened")
sys.exit(1)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # Get the frame width and height
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# Change
out = cv2.VideoWriter('results/output.avi', fourcc, 20.0, (frame_width, frame_height), isColor=False)
while True:
ret, frame = cap.read() # New
if not ret: # New
break # Get out if we don't read a frame successfully
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out.write(frame)
# Key events
key = cv2.waitKey(1)
if key == 27: # esc
break
cap.release()
out.release() # New
cv2.destroyAllWindows()
Как небольшая заметка, у вас нет отображаемых окон, поэтому cv2.destroyAllWindows()
здесь излишне. Попробуйте удалить его из своего кода.