I want to capture video from a webcam and save it to an mp4 file using opencv. I found example code on stackoverflow (below) that works great. The only hitch is that I\'m trying
There are some things to change in your code:
0x7634706d
: out = cv2.VideoWriter('output.mp4',0x7634706d , 20.0, (640,480))
This is the default code given to save a video captured by camera
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
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)
# 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()
For about two minutes of a clip captured that FULL HD
Using
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
cap.set(3,1920)
cap.set(4,1080)
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (1920,1080))
The file saved was more than 150MB
Then had to use ffmpeg
to reduce the size of the file saved, between 30MB
to 60MB
based on the quality of the video that is required changed using crf
lower the crf better the quality of the video and larger the file size generated. You can also change the format avi
,mp4
,mkv
,etc
Then i found ffmpeg-python
Here a code to save numpy array
of each frame as video using ffmpeg-python
import numpy as np
import cv2
import ffmpeg
def save_video(cap,saving_file_name,fps=33.0):
while cap.isOpened():
ret, frame = cap.read()
if ret:
i_width,i_height = frame.shape[1],frame.shape[0]
break
process = (
ffmpeg
.input('pipe:',format='rawvideo', pix_fmt='rgb24',s='{}x{}'.format(i_width,i_height))
.output(saved_video_file_name,pix_fmt='yuv420p',vcodec='libx264',r=fps,crf=37)
.overwrite_output()
.run_async(pipe_stdin=True)
)
return process
if __name__=='__main__':
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
cap.set(3,1920)
cap.set(4,1080)
saved_video_file_name = 'output.avi'
process = save_video(cap,saved_video_file_name)
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
process.stdin.write(
cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
.astype(np.uint8)
.tobytes()
)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
process.stdin.close()
process.wait()
cap.release()
cv2.destroyAllWindows()
break
else:
process.stdin.close()
process.wait()
cap.release()
cv2.destroyAllWindows()
break
This worked for me, I added images.sort() to keep the sequence order:
import cv2
import numpy as np
import os
image_folder = 'data-set-race-01'
video_file = 'race-01.mp4'
image_size = (160, 120)
fps = 24
images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]
images.sort()
out = cv2.VideoWriter(video_file, cv2.VideoWriter_fourcc(*'MP4V'), fps, image_size)
img_array = []
for filename in images:
img = cv2.imread(os.path.join(image_folder, filename))
img_array.append(img)
out.write(img)
out.release()
What worked for me was to make sure the input 'frame' size is equal to output video's size (in this case, (680, 480) ).
http://answers.opencv.org/question/27902/how-to-record-video-using-opencv-and-python/
Here is my working code (Mac OSX Sierra 10.12.6):
cap = cv2.VideoCapture(0)
cap.set(3,640)
cap.set(4,480)
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (640,480))
while(True):
ret, frame = cap.read()
out.write(frame)
cv2.imshow('frame', frame)
c = cv2.waitKey(1)
if c & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
Note: I installed openh264 as suggested by @10SecTom but I'm not sure if that was relevant to the problem.
Just in case:
brew install openh264
just change the codec to "DIVX"
. This codec works with all formats.
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
i hope this works for you!
This worked for me.
self._name = name + '.mp4'
self._cap = VideoCapture(0)
self._fourcc = VideoWriter_fourcc(*'MP4V')
self._out = VideoWriter(self._name, self._fourcc, 20.0, (640,480))