Сохранение видео в openCV в python
Я пытаюсь сохранить видео, но он не работает.
Я выполнил инструкции из документации openCV.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
Что не так?
Ответы
Ответ 1
попробуйте это. он работает для меня.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
#fourcc = cv2.cv.CV_FOURCC(*'DIVX')
#out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
Ответ 2
В моем случае я обнаружил, что размер Writer должен совпадать с размером кадра как с камеры, так и с файлов. Чтобы сначала прочитать размер кадра и примениться к настройке автора, как показано ниже.
(grabbed, frame) = camera.read()
fshape = frame.shape
fheight = fshape[0]
fwidth = fshape[1]
print fwidth , fheight
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (fwidth,fheight))
Ответ 3
У меня также была такая же проблема, но она работала, когда я использовал "MJPG" вместо 'XVID'
Я использовал
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
вместо
fourcc = cv2.VideoWriter_fourcc(*'XVID')
Ответ 4
У меня была такая же проблема, и я пробовал это:
frame = cv2.flip(frame,180)
вместо
frame= cv2.flip(frame,0)
и он работает.
Ответ 5
jveitchmichaelis на https://github.com/ContinuumIO/anaconda-issues/issues/223 предоставил исчерпывающий ответ. Здесь я скопировал его ответ:
Документация в OpenCV говорит (скрыто), что вы можете писать только в avi, используя OpenCV3. Верно это или нет, я не смог определить, но я не смог написать ни к чему другому.
Однако OpenCV - это в основном библиотека компьютерного зрения, а не видеопоток, кодек и запись. Поэтому разработчики постарались сделать эту часть максимально простой. Благодаря этому OpenCV для видео контейнеров поддерживает только расширение avi, его первая версия.
От: http://docs.opencv.org/3.1.0/d7/d9e/tutorial_video_write.html
Моя установка: я собрал OpenCV 3 из исходного кода, используя MSVC 2015, включая ffmpeg. Я также скачал и установил XVID и openh264 от Cisco, которые я добавил в свой PATH. Я использую Anaconda Python 3. Я также скачал свежую сборку ffmpeg и добавил папку bin в мой путь, хотя это не должно иметь значения, так как она встроена в OpenCV.
Я бегу в Win 10 64-битной.
Этот код, кажется, отлично работает на моем компьютере. Будет сгенерировано видео, содержащее случайную статику:
writer = cv2.VideoWriter("output.avi",
cv2.VideoWriter_fourcc(*"MJPG"), 30,(640,480))
for frame in range(1000):
writer.write(np.random.randint(0, 255, (480,640,3)).astype('uint8'))
writer.release()
Некоторые вещи, которые я выучил методом проб и ошибок:
- Используйте только ".avi", это просто контейнер, кодек важен.
-
Будьте осторожны с указанием размеров кадра. В конструкторе вы должны передать размер кадра как (столбец, строка), например 640x480. Однако передаваемый вами массив индексируется как (строка, столбец). Посмотрите в приведенном выше примере, как он переключился?
-
Если ваше входное изображение имеет другой размер, чем VideoWriter, оно не будет работать (часто молча)
- Передавать только 8-битные изображения, вручную приводить массивы, если это необходимо (.astype('uint8'))
- На самом деле, неважно, просто всегда снимали. Даже если вы загружаете изображения с помощью cv2.imread, вам нужно привести к uint8...
- MJPG потерпит неудачу, если вы не передадите 3-канальное 8-битное изображение. По крайней мере, я получаю ошибочное утверждение.
- XVID также требует 3-канальное изображение, но молча терпит неудачу, если вы этого не сделаете.
- H264, кажется, хорошо с изображением одного канала
- Если вам нужен необработанный вывод, скажем, с камеры машинного зрения, вы можете использовать "DIB". "RAW" или пустой кодек иногда работает. Как ни странно, если я использую DIB, я получаю ошибку ffmpeg, но видео сохраняется нормально. Если я использую RAW, ошибки не возникает, но проигрыватель Windows Video не открывает ее. Все хорошо в VLC.
В конце я думаю, что ключевым моментом является то, что OpenCV не предназначен для библиотеки захвата видео - он даже не поддерживает звук. VideoWriter полезен, но в 99% случаев лучше сохранять все изображения в папке и использовать ffmpeg, чтобы превратить их в полезное видео.
Ответ 6
Ответ на Nuru действительно работает, только вещь удаляет эту строку frame = cv2.flip(frame,0)
в цикле if ret==True:
, которая выведет видеофайл без щелчка
Ответ 7
В качестве примера:
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out_corner = cv2.VideoWriter('img_corner_1.avi',fourcc, 20.0, (640, 480))
В этом месте нужно определить X, Y как ширину и высоту
Но, когда вы создаете изображение (например, пустое изображение), вы должны определить Y, X как высоту и ширину:
img_corner = np.zeros((480, 640, 3), np.uint8)
Ответ 8
Как сказал @ปรีดา ตั้ง น ภากร: размеры Writer должны соответствовать кадру с камеры или файлов.
Вы можете использовать такой код, чтобы проверить, является ли ваша камера (640, 480) или нет:
print(int(cap.get(3)), int(cap.get(4)))
Для себя я нашел свою камеру (1280, 720) и заменил (640, 480) на (1280, 720). Тогда он может сохранять видео.