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()
Related
I would like to insert a text in a video dynamically. When I run the code below it displays a window with the text inside the video, but the .mp4 output generated file is empty (0kb)
EDIT: problem persists after right indentation
path = r'C:\\Users\\semnome\\Desktop\\automatizacoes\\m\\'
video_file = 'a.mp4'
x = True
cap = cv.VideoCapture(video_file) #cap for "Video Capture Object"
fourcc = cv.VideoWriter_fourcc(*'mp4v')
out = cv.VideoWriter('outpu2t.mp4', fourcc, 20.0, (640,480))
try:
while(True):
# Capture frames in the video
ret, frame = cap.read()
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(frame,
'TEXT ON VIDEO',
(50, 50),
font, 1,
(0, 640, 480),
2,
cv.LINE_4)
out.write(frame)
cv.imshow('video', frame)
if cv.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv.destroyAllWindows()
except:
print("Video has ended.")
cap.release()
cv.destroyAllWindows()
this is simply an indentation error. (and it's got nothing to do with writing text !)
you want out.write(frame) inside the loop, not after it (currently it only writes a single frame)
Using OpenCV, I have been extracting the frames from a video and after working on the frames, I have been trying to save them to a new video file. But the new video file is not being saved properly. It gets saved as 0 KB in size and throws the following error when I try to open it.
OpenCV Error
My code is as follows:
import cv2
cap = cv2.VideoCapture("Path to source video")
out = cv2.VideoWriter("Path to save video", cv2.VideoWriter_fourcc(*"VIDX"), 5, (1000, 1200))
print(cap.isOpened())
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# Write the video
out.write(frame)
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
I tried to follow the solution Can't save a video in opencv but it did not help in my case.
when saving the file, your width and height should match with frame's width and height, so in order to get the width and height of the frame automatically, use
import cv2
cap = cv2.VideoCapture(0)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # to get width of the frame
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # to get height of the frame
out = cv2.VideoWriter("dummy_video.mp4", cv2.VideoWriter_fourcc(*"VIDX"), 5, (width, height))
print(cap.isOpened())
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# Write the video
out.write(frame)
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
Trying to record "time true" video with openCV. When recording video footage it seems to be slightly sped up. If I hold a timer up to the webcam and then play it back saved footage is 3 - 5 seconds too fast per minute of saved footage.
How can I get the saved video to be exactly 1 minute if I record 1 minute from my webcam? Or 2 minutes of recording to be an exported 2-minute video?
import cv2
cap = cv2.VideoCapture(0)
fps = cap.get(cv2.CAP_PROP_FPS)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float `width`
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float `height`
fourcc = cv2.VideoWriter_fourcc(*'XVID')
videoWriter = cv2.VideoWriter('MYPATH\\video.avi', fourcc, fps, (int(width),int(height)))
while (True):
ret, frame = cap.read()
if ret:
cv2.imshow('video', frame)
videoWriter.write(frame)
if cv2.waitKey(1) == 27:
break
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
I have no idea why this fixed it... but changing the forcc to fourcc = cv2.VideoWriter_fourcc(*'MP4V') and then changing the output file from .avi to .mp4 fixed the problem.
Your program may write additional frames because True sentence at line 16 in your while loop, then change that value to check as conditional ret, by:
...
ret, frame = cap.read()
while (ret):
cv2.imshow('video', frame)
videoWriter.write(frame)
ret, frame = cap.read()
if cv2.waitKey(1) == 27:
break
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
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'm a python beginner so sorry in advance for the mistakes.
I'm trying to rotate a video 180 degrees and then work with that video that I should have created.
At the moment I'm doing this:
import cv2
import numpy as np
#that's my original video - the one that I want to rotate 180 degrees
cap = cv2.VideoCapture('/Users/name/Desktop/VIDEO 12.05/PIC_P01.mp4')
frame_number = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# Original Frames
frames = []
for i in range(frame_number):
ret, frame = cap.read()
frames.append(frame)
#here's where I try to rotate the video
new = cv2.rotate(frame, cv2.ROTATE_180)
cv2.imshow('output', new)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#here I'm trying to write the new rotated video
newvideoR = cv2.VideoWriter('PIC_P01R.mp4',0x7634706d, 50, (360, 640))
for jj in range(len(new)):
newvideoR.write(new[jj])
newvideoR.release()
cap.release()
In the end, however, when I go to read the file I find only an empty file that I cannot open.
From this, I deduce that there is an error in the steps that I have made.
Would anyone have any advice on how am I suppose to do this?
** I've also tried to change the parameter on cv2.Videowriter (for example fps, size) but is still not working
You don't need to accumulate the frames, and write them in another loop.
You can read a frame, rotate it, and write it in the same loop.
Get width and height:
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
Open the output video file before the loop:
newvideoR = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*"mp4v"), 50, (frame_width, frame_height))
Read the frame, rotate it and write it in a loop:
for i in range(frame_number):
ret, frame = cap.read()
new = cv2.rotate(frame, cv2.ROTATE_180)
cv2.imshow('output', new)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
newvideoR.write(new)
Release video reader and writer:
newvideoR.release()
cap.release()
Complete code sample (I named the files input.mp4 and output.mp4):
import cv2
#that's my original video - the one that I want to rotate 180 degrees
cap = cv2.VideoCapture('input.mp4')
frame_number = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# Get width and height
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# here I'm trying to write the new rotated video
# Open the output video file before the loop, cv2.VideoWriter_fourcc(*"mp4v") = 0x7634706d
newvideoR = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*"mp4v"), 50, (frame_width, frame_height))
# Original Frames
#frames = []
for i in range(frame_number):
ret, frame = cap.read()
#frames.append(frame) # No need to append the original frames
#here's where I try to rotate the video
new = cv2.rotate(frame, cv2.ROTATE_180)
cv2.imshow('output', new)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
newvideoR.write(new)
newvideoR.release()
cap.release()