Сохранение видео в 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). Тогда он может сохранять видео.