opencv VideoWriter под OSX не производит вывод
Я пытаюсь создать видео из оболочки Python для OpenCV под OSX. Я использую python 2.7.1, opencv 2.3.1a и оболочки для python из willowgarage, которые поставляются с этой версией opencv. Я имею:
import cv,cv2
w = cv2.VideoWriter('foo.avi', cv.FOURCC('M','J','P','G'), 25, (100,100))
for i in range(100):
w.write(np.ones((100,100,3), np.uint8))
OpenCV говорит
WARNING: Could not create empty movie file container.
Didn't successfully update movie file.
... [ 100 repetitions]
Я не уверен, что попробовать дальше
11 ответов
Есть много устаревших и неправильных онлайн-руководств по этой теме - я думаю, что попробовал почти все. Посмотрев исходную реализацию VideoWriter на базе QTKit для Mac OSX, я наконец смог заставить VideoWriter выводить действительные видеофайлы, используя следующий код:
fps = 15
capSize = (1028,720) # this is the size of my source video
fourcc = cv2.cv.CV_FOURCC('m', 'p', '4', 'v') # note the lower case
self.vout = cv2.VideoWriter()
success = self.vout.open('output.mov',fourcc,fps,capSize,True)
Чтобы написать фрейм изображения (обратите внимание, что размер imgFrame должен быть того же размера, что и capSize выше, иначе обновления не будут выполнены):
self.vout.write(imgFrame)
Когда закончите, обязательно:
vout.release()
self.vout = None
Это работает для меня на Mac OS X 10.8.5 (Mountain Lion): нет никаких гарантий о других платформах. Я надеюсь, что этот фрагмент сэкономит кому-то еще несколько часов экспериментов!
Я на MacOS High Sierra 10.13.4, Python 3.6.5, OpenCV 3.4.1.
Приведенный ниже код (источник: https://www.learnopencv.com/read-write-and-display-a-video-using-opencv-cpp-python/) открывает камеру, успешно закрывает окно после нажатия клавиши "q". и сохраняет видео в формате.avi.
Обратите внимание, что вам нужно запустить это как файл.py. Если вы запускаете его в Jupyter Notebook, окно закрывается при закрытии, и вам нужно принудительно выйти из Python, чтобы закрыть окно.
import cv2
import numpy as np
# Create a VideoCapture object
cap = cv2.VideoCapture(0)
# Check if camera opened successfully
if (cap.isOpened() == False):
print("Unable to read camera feed")
# Default resolutions of the frame are obtained.The default resolutions are system dependent.
# We convert the resolutions from float to integer.
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
# Define the codec and create VideoWriter object.The output is stored in 'outpy.avi' file.
out = cv2.VideoWriter('outpy.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))
while(True):
ret, frame = cap.read()
if ret == True:
# Write the frame into the file 'output.avi'
out.write(frame)
# Display the resulting frame
cv2.imshow('frame',frame)
# Press Q on keyboard to stop recording
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Break the loop
else:
break
# When everything done, release the video capture and video write objects
cap.release()
out.release()
# Closes all the frames
cv2.destroyAllWindows()
Попробовав различные варианты, я обнаружил, что используемый мной frame.size не соответствует размеру, указанному в VideoWriter: так что если установить его по умолчанию в iMac 1280x720, все заработает!
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
out = cv2.VideoWriter()
succes = out.open('output.mp4v',fourcc, 15.0, (1280,720),True)
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()
Вот версия, которая работает с:
- Python 3.6.3
- OpenCV 3.3.1
- macOS 10.13.1
Установлен с brew install opencv
,
#!/usr/bin/env python3
import cv2
def main():
vc = cv2.VideoCapture()
if not vc.open('input.mp4'):
print('failed to open video capture')
return
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# Match source video features.
fps = vc.get(cv2.CAP_PROP_FPS)
size = (
int(vc.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(vc.get(cv2.CAP_PROP_FRAME_HEIGHT)),
)
vw = cv2.VideoWriter()
if not vw.open('output.mp4', fourcc, fps, size):
print('failed to open video writer')
return
while True:
ok, frame = vc.read()
if not ok:
break
# Flip upside down.
frame = cv2.flip(frame, 0)
# Write processed frame.
vw.write(frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
vc.release()
vw.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
Это проблема "размера".
import cv2
import time
filename = time.strftime("%m-%d-%H-%M-%S") + '.avi'
fps = 16
cap = cv2.VideoCapture(0)
#in this way it always works, because your get the right "size"
size = (int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)),
int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))
fourcc = cv2.cv.FOURCC('8', 'B', 'P', 'S') #works, large
out = cv2.VideoWriter(filename, fourcc, fps, size, True)
#in this way, you must set the "size" to your size,
#because you don't know the default "size" is right or not
#cap.set(3, 640)
#cap.set(4, 480)
#out = cv2.VideoWriter(filename, fourcc, fps, (640, 480), True)
while(cap.isOpened()):
ret, frame = cap.read()
if ret == True:
out.write(frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break;
else:
print 'Error...'
break;
cap.release()
out.release()
cv2.destroyAllWindows()
В моем случае проблема была с frame_width и frame_height. Попробуйте следующее:
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
size = (frame_width, frame_height)
fps = 10
out = cv2.VideoWriter("output.avi", fourcc, fps, size)
while(cap.isOpened()):
ret, frame = cap.read()
if ret:
out.write(frame) # write the frame
cv2.imshow('frame', frame)
else:
break
if cv2.waitKey(1) == 27: # Esc
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
Это не очень хорошая идея
Вы должны создать VideoWriter
структура и метод использования WriteFrame
:
import cv
cv.NamedWindow('cap', 1)
w = cv.CreateVideoWriter('test.avi',cv.CV_FOURCC('X','V','I','D'),25,(640,480))
cap = cv.CaptureFromCAM(0)
while(1):
img = cv.QueryFrame(cap)
cv.ShowImage('cap', img)
cv.WriteFrame(w, img)
if cv.WaitKey(1) == 27:
break
cv.DestroyWindow('cap')
Вот вариант ответа @ToddStellanova, который работал для меня:
def write_video(image_dir):
'''
Writes a video from a set of images in `image_dir`
'''
target = join('data/labelled-videos',
basename(image_dir) + '.mp4v')
codec = cv2.cv.CV_FOURCC('m', 'p', '4', 'v')
size = (256, 256)
v = cv2.VideoWriter(target, codec, 16, size)
for image_name in listdir(image_dir):
image_filename = join(image_dir, image_name)
arr = np.asarray(Image.open(image_filename))
assert arr.shape[:2] == size
v.write(arr)
Возможно, ваша версия ffmpeg устарела. Я столкнулся с подобной проблемой с ffmpeg 0.8, и он работал нормально после обновления до ffmpeg 0.11.
Благодаря @TeddStellanova
Вот версия XCode C++:
int fWidth = capture.get(CV_CAP_PROP_FRAME_WIDTH);
int fHeight = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
string vid_path = path + "frames.mov";
VideoWriter vid(vid_path,CV_FOURCC('m','p','4','v'),30,Size(fWidth,fHeight),true);
Этот код сохранит записанное видео с веб-камеры (нажмитеq
ключ для выхода :)
Технические характеристики:
- Название продукта: macOS
- Версия продукта: 13.4.1
- число: 1.25.1
- opencv-питон: 4.8.0.74
Код:
import cv2 as cv
# video capture
vc = cv.VideoCapture(0)
# video writer
video_filename = 'webcam.avi'
frame_rate = 30
frame_size = (int(vc.get(3)), int(vc.get(4)))
fourcc = cv.VideoWriter.fourcc('M', 'J', 'P', 'G')
vw = cv.VideoWriter(
video_filename,
fourcc,
frame_rate,
frame_size
)
while True:
_, frame = vc.read()
vw.write(frame)
cv.imshow('', frame)
if cv.waitKey(1) == ord('q'):
break
vc.release()
vw.release()
cv.destroyAllWindows()