vedio frame is closing automatically in open cv python - 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.

Related

Changing FPS in OpenCV

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

OpenCV input delay in capturing frames

I have written a code to enable capturing images from webcam feed using OpenCV. However there is an input delay whenever I press the key to capture my frame. There is no delay when I use it to quit, but there a significant delay when I use capture. I measured this by printing a statement inside both the cases, on pressing c the statement takes a delay before printing. The problem seems to me something like...the camera resources are being used and not freed up in time for the next key press or something like that....but not sure.
import cv2 as cv
import numpy as np
import glob
import matplotlib.pyplot as plt
cap = cv.VideoCapture(1)
img_counter = 0
while True:
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# cv.imshow('frame',frame)
cv.imshow('gray', gray)
if not ret:
break
if cv.waitKey(1) & 0xFF == ord('q'):
print('helloq')
break
elif cv.waitKey(1) & 0xFF == ord('c'):
print('hello{}'.format(img_counter))
img_name = "opencv_frame_{}.png".format(img_counter)
cv.imwrite(img_name, gray)
img_counter += 1
I am using an external web camera and
cv2.__version__ = 3.4.2`
Solved your issue, it seems like its caused by your key check.
You should not call waitKey(1) more than once. It causes lag.
Try this solution:
cap = cv.VideoCapture(0)
img_counter = 0
while True:
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# cv.imshow('frame',frame)
cv.imshow('gray', gray)
if not ret:
break
key = cv.waitKey(1)
if key==ord('c'):
print('img{}'.format(img_counter))
img_name = "opencv_frame_{}.png".format(img_counter)
cv.imwrite(img_name, gray)
img_counter += 1
print("Succesfully saved!")
if key==ord('q'):
print('Closing cam...')
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()

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)

OpenCV - first frame covers second frame

I am trying to take 2 photos, but as result I see first one two times. I have tried using two variables for frames and saving them as file. How can I fix the problem?
#!/usr/bin/python
import cv2
import time
cap = cv2.VideoCapture(0)
time.sleep(0.25)
ret1, t1 = cap.read()
print 'ret1:', ret1
cv2.imshow('test',t1)
cv2.waitKey(0)
ret1, t1 = cap.read()
print 'ret1:', ret1
cv2.imshow('test1',t1)
cap.release()
while True:
time.sleep(1)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()

Categories

Resources