I capture video from my camera, but when i save this i received very fast video. Can i capture video with original frame rate?
import cv2
import time
# exit(1)
cap = cv2.VideoCapture("rtsp://192.168.0.66/live1.sdp")
ps = cap.get(cv2.CAP_PROP_FPS)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
# Get current height of frame
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float
fourcc = cv2.VideoWriter_fourcc(*'XVID')
FILE_OUTPUT = 'out.avi'
FPS = 20.0
cap.set(cv2.CAP_PROP_FPS, FPS)
out = cv2.VideoWriter(FILE_OUTPUT, fourcc, FPS, (int(width), int(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)
# cv2.waitKey(100)
# 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()
P.S i use opencv 4 and python3. I try change waitKey option but it had no effect
Related
I want to save a video after converting to gray scale. I don't know where exactly put the line out.write(gray_video). I use jupyter notebook with Python 3, and the Opencv library.
the code is:
import cv2
import numpy as np
video = cv2.VideoCapture("video1.mp4")
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('out_gray_scale.mp4', fourcc, 10.0, (640, 480),0)
while (True):
(ret, frame) = video.read()
if not ret:
print("Video Completed")
break
# Convert the frames into Grayscaleo
gray_video = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#writing
gray_frame = cv2.flip(gray_video, 0)
out.write(gray_video) #it suppose to save the gray video
#Show the binary frames
if ret == True:
cv2.imshow("video grayscale",gray_video)
#out.write(gray_video)
# Press q to exit the video
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
video.release()
cv2.destroyAllWindows()
The working video writer module of OpenCV depends on three main things:
the available/supported/installed codecs on the OS
getting the right codec and file extension combinations
the input video resolution should be same as output video resolution otherwise resize the frames before writing
If any of this is wrong openCV will probably write a very small video file which will not open in video player. The following code should work fine:
import cv2
import numpy as np
video = cv2.VideoCapture("inp.mp4")
video_width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) # float `width`
video_height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) # float `height`
video_fps = int(video.get(cv2.CAP_PROP_FPS))
print(video_width, video_height, video_fps)
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
out = cv2.VideoWriter('out_gray_scale1.avi', fourcc, video_fps, (video_width, video_height),0)
while (True):
ret, frame = video.read()
if not ret:
print("Video Completed")
break
# Convert the frames into Grayscale
gray_video = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#Show the binary frames
if ret == True:
cv2.imshow("video grayscale",gray_video)
#Writing video
out.write(gray_video)
# Press q to exit the video
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
video.release()
out.release()
cv2.destroyAllWindows()
I'm trying to get the current playing time position ( in milliseconds if possible) from a playing video using CV2 with Python.
Currently I'm using this sample code to play the video file
import cv2
import numpy as np
file_name = "2.mp4"
window_name = "window"
interframe_wait_ms = 30
cap = cv2.VideoCapture(file_name)
if not cap.isOpened():
print("Error: Could not open video.")
exit()
cv2.namedWindow(window_name, cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
while (True):
ret, frame = cap.read()
if not ret:
print("Reached end of video, exiting.")
break
cv2.imshow(window_name, frame)
if cv2.waitKey(interframe_wait_ms) & 0x7F == ord('q'):
print("Exit requested.")
break
cap.release()
cv2.destroyAllWindows()
Is there a way to get this value or calculate it, it has to represent what's the position (in time, i.e 12.500 seconds of 24.000 seconds video) of the playback at the request time.
Thanks!
Yes, this can be achieved by querying the video FPS using VideoCapture.get(cv2.CAP_PROP_FPS) and keeping track of the frame index.
Example:
file_name = "2.mp4"
window_name = "window"
interframe_wait_ms = 30
cap = cv2.VideoCapture(file_name)
if not cap.isOpened():
print("Error: Could not open video.")
exit()
fps = cap.get(cv2.CAP_PROP_FPS)
cv2.namedWindow(window_name, cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
frame_index = 0
while True:
ret, frame = cap.read()
if not ret:
print("Reached end of video, exiting.")
break
cv2.imshow(window_name, frame)
print(F"playback time: {(frame_index/fps)*1000}ms")
if cv2.waitKey(interframe_wait_ms) & 0x7F == ord('q'):
print("Exit requested.")
break
frame_index += 1
cap.release()
cv2.destroyAllWindows()
This is my code to save web_cam streaming. It is working but the problem with output video file.
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()
Here's some simple code to save frames into a video file. I recommend creating another thread for obtaining the frames since cv2.VideoCapture.read() is blocking. This can be expensive and cause latency as the main thread has to wait until it has obtained a frame. By putting this operation into a separate thread that just focuses on grabbing frames and processing/saving the frames in the main thread, it dramatically improves performance due to I/O latency reduction. You also can experiment with other codecs but using MJPG should be safe since its built into OpenCV.
from threading import Thread
import cv2
class WebcamVideoWriter(object):
def __init__(self, src=0):
# Create a VideoCapture object
self.capture = cv2.VideoCapture(src)
# Default resolutions of the frame are obtained (system dependent)
self.frame_width = int(self.capture.get(3))
self.frame_height = int(self.capture.get(4))
# Set up codec and output video settings
self.codec = cv2.VideoWriter_fourcc('M','J','P','G')
self.output_video = cv2.VideoWriter('output.avi', self.codec, 30, (self.frame_width, self.frame_height))
# Start the thread to read frames from the video stream
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
self.thread.start()
def update(self):
# Read the next frame from the stream in a different thread
while True:
if self.capture.isOpened():
(self.status, self.frame) = self.capture.read()
def show_frame(self):
# Display frames in main program
if self.status:
cv2.imshow('frame', self.frame)
# Press Q on keyboard to stop recording
key = cv2.waitKey(1)
if key == ord('q'):
self.capture.release()
self.output_video.release()
cv2.destroyAllWindows()
exit(1)
def save_frame(self):
# Save obtained frame into video output file
self.output_video.write(self.frame)
if __name__ == '__main__':
webcam_videowriter = WebcamVideoWriter()
while True:
try:
webcam_videowriter.show_frame()
webcam_videowriter.save_frame()
except AttributeError:
pass
The output file is corrupted because of the wrong frame rate and frame resolution. Using this code :
out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))
We set the fps/frame rate per second 20. Which was not correct. Also, the frame width and height was wrong. I solved by getting fps, width, height from the captured web_cam profile.
cap = cv2.VideoCapture(0) #web-cam capture
fps = cap.get(cv2.CAP_PROP_FPS)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float
out = cv2.VideoWriter('output.avi', -1,fps, (int(width), int(height)))
I added codec parameter to function cv2.videowriter.
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))
fps = cap.get(cv2.CAP_PROP_FPS)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
codec = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
out = cv2.VideoWriter('output.avi',codec,fps, (int(width),\
int (height)))
#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()
I hope you may see what is different in my code and your code.
Mine works now. Using MJPG codec for .avi extention
the indention is a bit messed,please do forgive cause I am very first time user.
The video file is no longer corrupt.
I got the info from: Link
I would like to play a video in openCV using python and close that window at any time, but it is not working.
import numpy as np
import cv2
fileName='test.mp4' # change the file name if needed
cap = cv2.VideoCapture(fileName) # load the video
while(cap.isOpened()):
# play the video by reading frame by frame
ret, frame = cap.read()
if ret==True:
# optional: do some image processing here
cv2.imshow('frame',frame) # show the video
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cv2.waitKey(1)
cv2.destroyAllWindows()
cv2.waitKey(1)
The window opens and starts playing the video, but I cannot close the window.
You can use cv2.getWindowProperty('window-name', index) to detect if the window is closed. I'm not totally sure about the index but this worked for me:
import cv2
filename = 'test.mp4'
cam = cv2.VideoCapture(filename)
while True:
ret, frame = cam.read()
if not ret:
break
cv2.imshow('asd', frame)
cv2.waitKey(1)
if cv2.getWindowProperty('asd', 4) < 1:
break
Why does the following code not save the video?
Also is it mandatory that the frame rate of the webcam matches exactly with the VideoWriter frame size?
import numpy as np
import cv2
import time
def videoaufzeichnung(video_wdth, video_hight, video_fps, seconds):
cap = cv2.VideoCapture(6)
cap.set(3, video_wdth) # wdth
cap.set(4, video_hight) #hight
cap.set(5, video_fps) #hight
# Define the codec and create VideoWriter object
fps = cap.get(5)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, video_fps, (video_wdth, video_hight))
#out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
start = time.time()
zeitdauer = 0
while(zeitdauer < seconds):
end = time.time()
zeitdauer = end - start
ret, frame = cap.read()
if ret == True:
frame = cv2.flip(frame, 180)
# 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()
videoaufzeichnung.videoaufzeichnung(1024, 720, 10, 30)
I suspect you're using the libv4l version of OpenCV for video I/O. There's a bug in OpenCV's libv4l API that prevents VideoCapture::set method from changing the video resolution. See links 1, 2 and 3. If you do the following:
...
frame = cv2.flip(frame,180)
print(frame.shape[:2] # check to see frame size
out.write(frame)
...
You'll notice that the frame size has not been modified to match the resolution provided in the function arguments. One way to overcome this limitation is to manually resize the frame to match resolution arguments.
...
frame = cv2.flip(frame,180)
frame = cv2.resize(frame,(video_wdth,video_hight)) # manually resize frame
print(frame.shape[:2] # check to see frame size
out.write(frame)
...
output-frame & input-frame sizes must be same for writing...