Changing FPS in OpenCV - python

I have an application that needs to capture only a few frames per second from a webcam. Setting videowriter in the below code to 3 frames per second results in the webcam's normal framerate of approximately 30 fps being saved.
What are the options to save only the recorded 3 frames per second, and let the other 27 or so go? Thanks in advance.
import cv2
import numpy as np
import time
import datetime
import pathlib
import imutils
cap = cv2.VideoCapture(0)
if (cap.isOpened() == False):
print("Unable to read camera feed")
capture_duration = 15
frame_per_sec = 3
frame_width = 80
frame_height = 60
out = cv2.VideoWriter('C:\\Users\\student\\Desktop\\videoFile.avi',cv2.VideoWriter_fourcc('m','j','p','g'),frame_per_sec, (frame_width,frame_height))
start_time = time.time()
while( int(time.time() - start_time) < capture_duration ):
ret, frame = cap.read()
if ret==True:
frame = imutils.resize(frame, width=frame_width)
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()

You set the FPS for the output via the VideoWriter,
but you didn't attempt to set the FPS for the input via the VideoCapture.
In order to do that you can try to call cv2.VideoCapture, with the cv2.CAP_PROP_FPS property after you create cap.
For example:
cap.set(cv2.CAP_PROP_FPS, 3)
However - note that the actual behavior is dependant on the specific capture device you are using. Some support only certain FPSs. See also this post regarding it: change frame rate in opencv 3.4.2.
If it does work you will be able to simplify your code a lot - just capture frames, process them and save (without any manual fps management).

This method programmatically sets frames per second. A 6.1mb file was created when frame rate was set for 30fps, and a 0.9mb file when set for 3fps.
#!/usr/bin/env python3
import cv2
import numpy as np
import time
import datetime
import pathlib
import imutils
cap = cv2.VideoCapture(0)
if (cap.isOpened() == False):
print("Unable to read camera feed")
capture_duration = 15
frame_per_sec = 30
prev = 0
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
out = cv2.VideoWriter('C:\\videoPy\\LZ\\'outpout.avi',cv2.VideoWriter_fourcc('m','j','p','g'),frame_per_sec, (frame_width,frame_height))
start_time = time.time()
while( int(time.time() - start_time) < capture_duration ):
#start fps
time_elapsed = time.time() - prev
while(time_elapsed > 1./frame_per_sec):
ret, frame = cap.read()
if not ret:
break
if time_elapsed > 1./frame_per_sec:
prev = time.time()
#end fps
if ret==True:
frame = imutils.resize(frame, width=frame_width)
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()

Related

How to record video rtsp and save video for 5 minutes using python and opencv

How to record video rtsp and save video for 5 minutes using python and opencv
i m using to record some of the code but for 5 minutes using clas and function video is very tuff to download for 5 minutes.
You will need to import cv2. You may need to execute pip install opencv-python to install the module for importation.
import cv2
import time
# open video stream
cap = cv2.VideoCapture('rtsp://127.0.0.1/stream')
# set video resolution
cap.set(3, 640)
cap.set(4, 480)
# set video codec
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
# start timer
start_time = time.time()
while (int(time.time() - start_time) < 300):
ret, frame = cap.read()
if ret == True:
out.write(frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# release resources
cap.release()
out.release()
cv2.destroyAllWindows()

How to save a video after changing its speed with opencv in your folder?

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()

vedio frame is closing automatically in open cv python

i am trying to stream a live vedio from cctv camera using open cv but vedio frame is showing and closing immediately. kindly help me out
import cv2
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
kernel=None
# This is a test video
cap = cv2.VideoCapture('rtsp://192.168.18.2277:554/user=admin_password=_channel=4_stream=0.sdp?real_stream.sdp')
while (cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
# This function will return a boolean variable telling if someone was present or not, it will also draw boxes if it
# finds someone
ret = cap.set(3, 200)
ret = cap.set(4, 300)
cv2.imshow('frame', frame)
# Calculate the Average FPS
frame_counter += 1
fps = (frame_counter / (time.time() - start_time))
# Exit if q is pressed.
if cv2.waitKey(30) == ord('q'):
break
# Release Capture and destroy windows
cap.release()
cv2.destroyAllWindows()
Instead of using a if and else you can just write cv2.waitKey(1) at the end of your while loop. Hope that fixes the problem
Remove the if not ret: break statement and your code should work properly
I see 3 points to be changed above:
you have not imported time library but you have called the current time function in your algorithm.
start_time is specified but what will be the start time isn't. If it is the time that the program is executed then please define it.
Also you have to first define what is Frame_counter, and cannot directly increment it by 1.
import cv2
#import time function
import time
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
kernel=None
cap = cv2.VideoCapture(0)
#define start_time
start_time = time.time()
#frame counter value
frame_counter = 1
while (cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
ret = cap.set(3, 200)
ret = cap.set(4, 300)
cv2.imshow('frame', frame)
frame_counter += 1
fps = (frame_counter / (time.time() - start_time))
if cv2.waitKey(30) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Please excuse if there are any mistakes, I am also a beginner.

Fastest way to grab a picture from webcam

I'm trying to capture an event in real time using a webcam. (maximum delay of 50 - 100 milliseconds is acceptable). Could someone please suggest the fastest way of doing this on python.
This is what I've written, but it's taking about 350 milliseconds
import cv2
import time
cap = cv2.VideoCapture(0)
# Check if the webcam is opened correctly
if not cap.isOpened():
raise IOError("Cannot open webcam")
start = time.time()
ret, frame = cap.read()
end = time.time()
frame = cv2.resize(frame, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
print(end - start)
cv2.imshow('Input', frame)
c = cv2.waitKey(1)
while c!=27:
continue
cap.release()
cv2.destroyAllWindows()

Read video file with fixed frame rate

I captured a video with my camera and fixed frame rate at 25 fps and tried to read it with OpenCV.
When I read video file with OpenCV, it plays but it plays very fast.
I want my program to play video at 25 fps. How to configure OpenCV to read video file at 25 fps?
My code:
import numpy as np
import cv2
cap = cv2.VideoCapture('vtest.avi')
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
I found some solution.
I put a delay time to capture loop. I check delay before captures new image from video file. This is my solution code.
Thanks, everybody.
import numpy as np
import cv2
from time import time as timer
import sys
video = cv2.VideoCapture('2.avi')
fps = video.get(cv2.CAP_PROP_FPS)
fps /= 1000
framerate = timer()
elapsed = int()
cv2.namedWindow('ca1', 0)
while(video.isOpened()):
start = timer()
# print(start)
ret, frame = video.read()
cv2.imshow('ca1',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
diff = timer() - start
while diff < fps:
diff = timer() - start
elapsed += 1
if elapsed % 5 == 0:
sys.stdout.write('\r')
sys.stdout.write('{0:3.3f} FPS'.format(elapsed / (timer() - framerate)))
sys.stdout.flush()
video.release()
cv2.destroyAllWindows()
Here is a working solution for this problem:
fps = vid.get(cv2.CAP_PROP_FPS)
while True:
now = time.time()
_, frame = vid.read()
#Do your thing
timeDiff = time.time() - now
if (timeDiff < 1.0/(fps)):
time.sleep(1.0/(fps) - timeDiff)
Since this is an existing video file, you can not change its FPS. However when you read the video file, you can change the interval you read between each frame. Here is my solution to read at a fixed frame rate 25 fps. Here is the code:
import numpy as np
import cv2
import sys
cap = cv2.VideoCapture('C:/Media/videos/Wildlife.wmv')
# Check if camera opened successfully
if (cap.isOpened()== False):
print("Error opening video stream or file")
fps = 25
#if you want to have the FPS according to the video then uncomment this code
#fps = cap.get(cv2.CAP_PROP_FPS)
#calculate the interval between frame.
interval = int(1000/fps)
print("FPS: ",fps, ", interval: ", interval)
# Read the video
while(cap.isOpened()):
ret, frame = cap.read()
if ret == True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('Frame',gray)
if cv2.waitKey(interval) & 0xFF == ord('q'):
break
# Break the loop
else:
break
cap.release()
cv2.destroyAllWindows()
Inspired by your answer:
while(cap.isOpened()):
ret, frame = cap.read()
now = time.time()
frameLimit = 2.0
#Do your stuff
timeDiff = time.time() - now
if (timeDiff < 1.0/(frameLimit)): time.sleep( 1.0/(frameLimit) - timeDiff )
you can add the required fps in place of 'fps' below
cap.set(cv2.cv.CV_CAP_PROP_FPS, fps)

Categories

Resources