I'm trying to re-size the video using opencv and then save it back to my system.The code works and does not give any error but output video file is corrupted. The fourcc I am using is mp4v works well with .mp4 but still the output video is corrupted. Need Help.
import numpy as np
import cv2
import sys
import re
vid=""
if len(sys.argv)==3:
vid=sys.argv[1]
compress=int(sys.argv[2])
else:
print("File not mentioned or compression not given")
exit()
if re.search('.mp4',vid):
print("Loading")
else:
exit()
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
def rescale_frame(frame, percent=75):
width = int(frame.shape[1] * percent/ 100)
height = int(frame.shape[0] * percent/ 100)
dim = (width, height)
return cv2.resize(frame, dim, interpolation =cv2.INTER_AREA)
FPS= 15.0
FrameSize=(frame.shape[1], frame.shape[0])
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('Video_output.mp4', fourcc, FPS, FrameSize, 0)
while(cap.isOpened()):
ret, frame = cap.read()
# check for successfulness of cap.read()
if not ret: break
rescaled_frame=rescale_frame(frame,percent=compress)
# Save the video
out.write(rescaled_frame)
cv2.imshow('frame',rescaled_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
The problem is the VideoWriter initialization.
You initialized:
out = cv2.VideoWriter('Video_output.mp4', fourcc, FPS, FrameSize, 0)
The last parameter 0 means, isColor = False. You are telling, you are going to convert frames to the grayscale and then saves. But there is no conversion in your code.
Also, you are resizing each frame in your code based on compress parameter.
If I use the default compress parameter:
cap = cv2.VideoCapture(0)
if cap.isOpened():
ret, frame = cap.read()
rescaled_frame = rescale_frame(frame)
(h, w) = rescaled_frame.shape[:2]
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter('Video_output.mp4',
fourcc, 15.0,
(w, h), True)
else:
print("Camera is not opened")
Now we have initialized the VideoWriter with the desired dimension.
Full Code:
import time
import cv2
def rescale_frame(frame_input, percent=75):
width = int(frame_input.shape[1] * percent / 100)
height = int(frame_input.shape[0] * percent / 100)
dim = (width, height)
return cv2.resize(frame_input, dim, interpolation=cv2.INTER_AREA)
cap = cv2.VideoCapture(0)
if cap.isOpened():
ret, frame = cap.read()
rescaled_frame = rescale_frame(frame)
(h, w) = rescaled_frame.shape[:2]
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter('Video_output.mp4',
fourcc, 15.0,
(w, h), True)
else:
print("Camera is not opened")
while cap.isOpened():
ret, frame = cap.read()
rescaled_frame = rescale_frame(frame)
# write the output frame to file
writer.write(rescaled_frame)
cv2.imshow("Output", rescaled_frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
cv2.destroyAllWindows()
cap.release()
writer.release()
Possible Question: I don't want to change my VideoWriter parameters, what should I do?
Answer: Then you need to change your frames, to the gray image:
while cap.isOpened():
# grab the frame from the video stream and resize it to have a
# maximum width of 300 pixels
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
Related
This is my code to read frame from cam and save to .avi file.
import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print('Camera open failed')
exit()
fps = cap.get(cv2.CAP_PROP_FPS)
w = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
delay = round(1000 / fps)
outputVideo = cv2.VideoWriter('output.avi', fourcc, fps, (w, h))
if not outputVideo.isOpened():
print('file open failed')
exit()
count = 0
while count < 11:
ret, cam = cap.read()
if not ret:
break
#cam = cv2.cvtColor(cam, cv2.COLOR_BGR2GRAY)
outputVideo.write(cam)
cv2.imshow('cam', cam)
if cv2.waitKey(delay) == 27:
break
count += 1
cv2.destroyAllWindows()
This code works perfectly when the cvtColor is in comment.
But when I remove the Sharp, videoWriter writes nothing.
How can I fix it? I want to save video in grayscale.
Used: OpenCV and Python3
I am using Python 3.8.2
Operating System: macOS Big Sur 11.2.3
I tried this code on VScode, it does show a video with changed speed with the cv2.imshow command but I don't know how to save that changed video in my folder:
import cv2
cap = cv2.VideoCapture('Pothole testing.mp4')
frameTime = 100
while(cap.isOpened()):
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(frameTime) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Can anyone tell me what should I add to this code so that the changed video gets saved? And preferably in the .mp4 format itself.
You can use the fps parameter of the cv2.VideoWriter() method. The fps can be calculated by simple diving your frameTime variable by 1000, as the cv2.waitKey() method takes in a number and uses it as a thousandth of a second.
Note that if the cap never closed during the while loop, the while cap.isOpened() won't be any better than while True, meaning by the time the last frame is read, an error would occur, causing the writer.release() method to never be called, thus making the resulting file unreadable.
Here is how I would do it:
import cv2
cap = cv2.VideoCapture('Pothole testing.mp4')
ret, frame = cap.read() # Get one ret and frame
h, w, _ = frame.shape # Use frame to get width and height
frameTime = 100
fourcc = cv2.VideoWriter_fourcc(*"XVID") # XVID is the ID, can be changed to anything
fps = 1000 / frameTime # Calculate fps
writer = cv2.VideoWriter("Pothole testing 2.mp4", fourcc, fps, (w, h)) # Video writing device
while ret: # Use the ret to determin end of video
writer.write(frame) # Write frame
cv2.imshow("frame", frame)
if cv2.waitKey(frameTime) & 0xFF == ord('q'):
break
ret, frame = cap.read()
writer.release()
cap.release()
cv2.destroyAllWindows()
If all you need is the resulting file and not the progress window, you can omit a few lines:
import cv2
cap = cv2.VideoCapture('Pothole testing.mp4')
ret, frame = cap.read()
h, w, _ = frame.shape
frameTime = 100
fourcc = cv2.VideoWriter_fourcc(*"XVID")
fps = 1000 / frameTime
writer = cv2.VideoWriter("Pothole testing 2.mp4", fourcc, fps, (w, h))
while ret:
writer.write(frame)
ret, frame = cap.read()
writer.release()
cap.release()
I want to write a video using OpenCv and process every frames in different seconds.
I am using cv2.VideoWriter, but the output file shows only the first frame of my video and it is not playing. I wanted to add text on the first frame and it did it, but it doesn't continue with the rest of the video.
As you can see from the code below, it creates a new output file for the new processed video.
It does create the mp4 file, but only showing first frame with the added text and it is not playing.
Any suggestion why this is happening?
Here is my code, I am using Spyder and windows.
fps = int(round(cap.get(5)))
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_file,fourcc,fps,(frame_width,frame_height))
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
if ret:
if cv2.waitKey(28) & 0xFF == ord('q'):
break
if between(cap, 0, 10000):
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
cv2.putText(frame,'hello',org=(10,600),fontFace=font,fontScale=10,color=(255,0,0),thickness=4)
pass
# Our operations on the frame come here
out.write(frame)
# Display the resulting frame
cv2.imshow('frame',frame)
Exactly I could not find the problem in your code because you did not give the between function. However you may try following snippet:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
if (cap.isOpened() == False):
print("Unable to read camera feed")
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
fps = int(round(cap.get(5)))
out = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))
while (True):
ret, frame = cap.read()
if ret == True:
cv2.putText(frame, 'hello',
org=(10, 300),
fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=5,
color=(255, 0, 0),
thickness=4)
out.write(frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
I have tried different methods but none of them works.
As video is running but and file output.avi is empty.
Here is code
import cv2
vid=cv2.VideoCapture(0)
if (not vid.isOpened()):
print 'Error'
size = (int(vid.get(3)), int(vid.get(4)))
fourcc = cv2.cv.CV_FOURCC('M','J','P','G')
newVideo=cv2.VideoWriter('output.avi',fourcc,20.0,(640,360))
while(vid.isOpened()):
ret,frame=vid.read()
if ret is True:
frame=cv2.flip(frame,0)
newVideo.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1)& 0xFF==ord('q'):
break
else:
break
vid.release()
newVideo.release()
cv2.destroyAllWindows()
The problem is simple, you are reading frame but you are trying to write them in a different size.
The solution is inside of your code. You defined:
size = (int(vid.get(3)), int(vid.get(4)))
But you didn't use it as like:
newVideo=cv2.VideoWriter('output.avi',fourcc,20.0,size)
You set the sizes as manually(640,360) which is not the size of captured frames.
You need to be sure that the output frame's dimension and initialized VideoWriter dimensions are the same.
cv2.resize(frame, (640, 360))
But, I'm not sure you are using python3. Since print 'Error' and fourcc = cv2.cv.CV_FOURCC('M','J','P','G') are not python3 statements.
For python2 the answer will be:
# Add true at the and of the parameter for specifying the frames are RGB.
newVideo = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 360), True)
.
.
if ret is True:
frame=cv2.flip(frame,0)
frame = cv2.resize(frame, (640, 360)) # missing statement
newVideo.write(frame)
cv2.imshow('frame',frame)
.
.
For python3 the answer will be:
import cv2
vid = cv2.VideoCapture(0)
if not vid.isOpened():
print('Error')
fourcc = cv2.VideoWriter_fourcc(*"MJPG")
newVideo = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 360), True)
while vid.isOpened():
ret, frame = vid.read()
if ret:
frame = cv2.flip(frame, 0)
frame = cv2.resize(frame, (640, 360))
newVideo.write(frame)
cv2.imshow('frame', frame)
if (cv2.waitKey(1) & 0xFF) == ord('q'):
break
else:
break
cv2.destroyAllWindows()
vid.release()
newVideo.release()
I am trying to capture a video from webcam in 1440p but the output file cannot be opened. There aren't any problem when I captured in 1080p and 2592*1944 (5mp), only 1440p that has a problem. Does anybody knows how can I make it work with 1440p?
I am not sure is it about the fourCC but I tried changing it to DIVX and the result still the same.
import cv2
cap = cv2.VideoCapture(0)
framesize = '1440p'
if framesize=='5mp':
cap.set(3, 2592)
cap.set(4, 1944)
resolution = (2592,1944)
elif framesize=='1440p':
cap.set(3, 2560)
cap.set(4, 1440)
resolution = (2560, 1440)
else :
cap.set(3, 1920)
cap.set(4, 1080)
resolution = (1920, 1080)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('new_output.avi',fourcc, 20.0, resolution)
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:
break
cap.release()
out.release()
cv2.destroyAllWindows()
The output file is only 13 KB. When trying to play it, there's a message "This file isn't playable. That might be because the file type is unsupported, the file extension is incorrect, or the file is corrupt. 0xc10100be"
I think you have to resize each frame before passing it to the VideoWriter():
out = VideoWriter(outvid, fourcc, float(fps), size, is_color)
if size[0] != img.shape[1] and size[1] != img.shape[0]:
img = resize(img, size)
out.write(img)
More examples at https://www.programcreek.com/python/example/72134/cv2.VideoWriter