How to capture images every n seconds from always running video? - python

I want to capture image and store it on my local system after every n seconds, I can not set frame(5) as I want video and detection to run completely. Currently my code is capturing image whenever a condition is failed.
def create_alert(self):
count = 0
cap = cv2.VideoCapture(0)
while cap.isOpened():
r,f = cap.read()
try:
info = ppe.detection(f)
x,y,w,h,label,conf = info[0]
if label == "lineman_fail":
# engine.say("Warning")
# engine.runAndWait()
ppe.take_screenshot(f,count)
count+=1
print(count)
print("Something wrong")
# cv2.imwrite("img_"+str(count)+".jpg",f)
except Exception as e:
print("_______-",e)
cv2.imshow("image",f)
if cv2.waitKey(1) & 0xFF == ord("q") :
break
cap.release()
cv2.destroyAllWindows()
def take_screenshot(self,frame,count):
prev = time.time()
cv2.imwrite("screen_shot/img_"+str(count)+".jpg",frame)

In order to capture image every n seconds try using datetime library, and find the difference between current time and elapsed time. Then use cv2's imwrite
while True:
current = time()
yolo_v4.delta += current - previous
previous = current
frame = camera.get_frame()
if yolo_v4.delta > 10:
ct=datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
cv2.imwrite("screen_shot/img_"+str(ct)+".jpg",frame)

Related

How to capture a 500 images from a video through webcam in opencv python?

I'm using the below code to capture images from webcam. But i need only some no.of images to be captured on click.
# Opens the inbuilt camera of laptop to capture video.
cap = cv2.VideoCapture(0)
i = 0
while(cap.isOpened()):
ret, frame = cap.read()
# This condition prevents from infinite looping
# incase video ends.
if ret == False:
break
# Save Frame by Frame into disk using imwrite method
cv2.imwrite('Frame'+str(i)+'.jpg', frame)
i += 1
cap.release()
cv2.destroyAllWindows()```
Assuming you want 500 images add this:
...
i+=1
if (i+1)%500==0:
break
that would be easy. you can use k = cv2.waitKey(1) and check what button was pressed. here is a simple example:
import cv2
def main():
cap = cv2.VideoCapture(0)
if not cap.isOpened(): # Check if the web cam is opened correctly
print("failed to open cam")
return -1
else:
print('webcam open')
for i in range(10 ** 10):
success, cv_frame = cap.read()
if not success:
print('failed to capture frame on iter {}'.format(i))
break
cv2.imshow('click t to save image and q to finish', cv_frame)
k = cv2.waitKey(1)
if k == ord('q'):
print('q was pressed - finishing...')
break
elif k == ord('t'):
print('t was pressed - saving image {}...'.format(i))
image_path = 'Frame_{}.jpg'.format(i) # i recommend a folder and not to save locally to avoid the mess
cv2.imwrite(image_path, cv_frame)
cap.release()
cv2.destroyAllWindows()
return
if __name__ == '__main__':
main()

How can I extract frames from a video at a certain FPS?

I am able to extract the frames of a certain test.mp4 file using the following code:
import cv2
def get_frames():
cap = cv2.VideoCapture('test.mp4')
i = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
cv2.imwrite('test_'+str(i)+'.jpg', frame)
i += 1
cap.release()
cv2.destroyAllWindows()
A lot of the frames that are extracted are useless (they're nearly identical). I need to be able to set a certain rate at which the frame extraction can be done.
I think you need to just skip frames based on a fixed cycle.
import cv2
def get_frames():
cap = cv2.VideoCapture('test.mp4')
i = 0
# a variable to set how many frames you want to skip
frame_skip = 10
# a variable to keep track of the frame to be saved
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
if i > frame_skip - 1:
frame_count += 1
cv2.imwrite('test_'+str(frame_count*frame_skip)+'.jpg', frame)
i = 0
continue
i += 1
cap.release()
cv2.destroyAllWindows()
Try below logic. Here, we are waiting for a period of time(based on frame rate) and reading the last frame.
def get_frames():
cap = cv2.VideoCapture('test.mp4')
frame_rate = 10
prev = 0
i = 0
while cap.isOpened():
time_elapsed = time.time() - prev
ret, frame = cap.read()
if not ret:
break
if time_elapsed > 1./frame_rate:
# print(time_elapsed)
prev = time.time()
cv2.imwrite('./data/sample1/test_'+str(i)+'.jpg', frame)
i += 1
cap.release()
cv2.destroyAllWindows()
As an alternative to writing your own code to do this, have you considered using FFMPEG? FFMPEG has the ability to extract all frames from a video and save them as images, it also can extract frames at a lower frame rate than the source video.
See here for a demonstration of what I think you're trying to do, and the arguments to give ffmpeg to do so.

Terminate a Python script after a time period

My code does capture images every 2 secs. But the problem is it runs endlessly. I need the script to terminate or close at a time period (i.e like terminate or close after 50secs). I tried using sleep() but suspects that doesn't terminate the whole script or closes it, It just puts the script to sleep !
Hope someone could help me with terminating the script after a time period!
My script :
import cv2
import numpy
import time
capture = cv2.VideoCapture(0)
capture.set(3, 640)
capture.set(4, 480)
img_counter = 0
frame_set = []
start_time = time.time()
while True:
ret, frame = capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if time.time() - start_time >= 2:
img_name = "FaceFrame{}.jpg".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_counter))
start_time = time.time()
img_counter += 1
actual_start_time = time.clock()
start_time = time.time()
while ((time.clock() - actual_start_time) < 50):
#do stuff
Alternatively:
actual_start_time = time.clock()
start_time = time.time()
while True:
#do stuff
if (time.clock() - actual_start_time) > 50):
break

Python -> OpenCV -> save one image and end program

I have a RaspberryPi, a few IP camera's and I would like to get a fresh image from all these camera's every 5 minutes. I have the following script, which open the RTSP feed af grabs images ALL THE TIME, talking 10-25 every second it runs.
Is there a way to open the videofeed an take only 1 image?
import cv2
import time
cap = cv2.VideoCapture('rtsp://192.168.86.81:554/11') # it can be rtsp or http $
ret, frame = cap.read()
while ret:
cv2.imwrite('images/{}.jpg'.format(time.time()), frame)
ret, frame = cap.read()
This solved my problem. I removed time as I do not need this. I will let the aboce code stand in case anybody would want to play around with this
import cv2
cap = cv2.VideoCapture('rtsp://192.168.86.81:554/11') # it can be rtsp or http stream
ret, frame = cap.read()
if cap.isOpened():
_,frame = cap.read()
cap.release() #releasing camera immediately after capturing picture
if _ and frame is not None:
cv2.imwrite('images/latest.jpg', frame)
import cv2
import time
from datetime import datetime
import getpass
#imagesFolder = "C:/Users/<user>/documents"
# https://stackoverflow.com/questions/842059/is-there-a-portable-way-to-get-the-current-username-in-python
imagesFolder = "C:/Users/" + getpass.getuser() + "/documents"
#cap = cv2.VideoCapture("rtsp://192.168.86.81:554/11")
# Use public RTSP Streaming for testing, but I am getting black frames!
cap = cv2.VideoCapture("rtsp://192.168.86.81:554/11")
frameRate = cap.get(5) #frame rate
count = 0
while cap.isOpened():
start_time = time.time()
frameId = cap.get(1) # current frame number
ret, frame = cap.read()
if (ret != True):
break
filename = imagesFolder + "/image_" + str(datetime.now().strftime("%d-%m-%Y_%I-%M-%S_%p")) + ".jpg"
cv2.imwrite(filename, frame)
# Show frame for testing
cv2.imshow('frame', frame)
cv2.waitKey(1)
count += 1
#Break loop after 5*60 minus
if count > 5*60:
break
elapsed_time = time.time() - start_time
# Wait for 60 seconds (subtract elapsed_time in order to be accurate).
time.sleep(60 - elapsed_time)
cap.release()
print ("Done!")
cv2.destroyAllWindows()

Save multiple images with OpenCV and Python

I'm using OpenCV and Python to take images. However currently I can only take one picture at a time. I would like to have OpenCV to take multiple pictures. This is my current code.
import cv2.cv as cv
import time
cv.NamedWindow("camera", 1)
capture = cv.CaptureFromCAM(0)
while True:
img = cv.QueryFrame(capture)
cv.ShowImage("camera", img)
cv.SaveImage('pic.jpg', img)
if cv.WaitKey(10) == 27:
break
Your code overwrite a file. Save to different file each time.
For example:
import cv2.cv as cv
import time
cv.NamedWindow("camera", 1)
capture = cv.CaptureFromCAM(0)
i = 0
while True:
img = cv.QueryFrame(capture)
cv.ShowImage("camera", img)
cv.SaveImage('pic{:>05}.jpg'.format(i), img)
if cv.WaitKey(10) == 27:
break
i += 1
A minimal example of what you'd like to do, based on the c++ binded interface.
import cv2
cpt = 0
maxFrames = 5 # if you want 5 frames only.
try:
vidStream = cv2.VideoCapture(0) # index of your camera
except:
print "problem opening input stream"
sys.exit(1)
while cpt < maxFrames:
ret, frame = vidStream.read() # read frame and return code.
if not ret: # if return code is bad, abort.
sys.exit(0)
cv2.imshow("test window", frame) # show image in window
cv2.imwrite("image%04i.jpg" %cpt, frame)
cpt += 1
A full example of script, able to read from a camera index, or a file. Includes some failsafes and some information about read device.
usage: record.py [source] [target folder]
#!/usr/bin/env python
import cv2
import sys
import os
cpt = 0
maxFrames = 30
try:
targetDir = sys.argv[2]
except:
targetDir = "" # if no argument, then use current directory
try: # read input. eval if to transform video index to int
vidStream = cv2.VideoCapture(eval(sys.argv[1]))
except:
print "problem opening input stream"
sys.exit(1)
if not vidStream.isOpened():
print "capture stream not open"
sys.exit(1)
# informations in case the input is a video file.
nFrames = vidStream.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)
print "frame number: %s" %nFrames
fps = vidStream.get(cv2.cv.CV_CAP_PROP_FPS)
print "FPS value: %s" %fps
# note that we could use frame number here, or "while 1"
# so we could read from a live written file or capture devide.
while cpt < maxFrames:
ret, frame = vidStream.read() # read frame and return code.
if not ret:
print "end of stream"
sys.exit(0)
cv2.imshow("test window", frame) # show image in window
cv2.imwrite(os.path.join(targetDir, "image_%04i.jpg" %cpt), frame)
cpt += 1
keyPressed = cv2.waitKey(1) # time to wait between frames
if keyPressed != -1: # if user pressed a key, stop recording.
sys.exit(0)
change the name of the image to be saved to " [image name] [a number which increase after every loop] "
By doing this your image will be stored with a new name after every loop.. otherwise all the images will overwrite the same name !
import cv2.cv as cv
import time
cv.NamedWindow("camera", 1)
capture = cv.CaptureFromCAM(0)
num = 0
while True:
img = cv.QueryFrame(capture)
cv.ShowImage("camera", img)
cv.SaveImage('pic'+str(num)+'.jpg', img)
if cv.WaitKey(10) == 27:
break
num += 1
now your images will be saved as pic0.jpg, pic1.jpg, pic2.jpg and so on..
i think this wil helpful...
import cv2
vid = cv2.VideoCapture("video.mp4")
d = 0
ret, frame = vid.read()
while ret:
ret, frame = vid.read()
filename = "images/file_%d.jpg"%d
cv2.imwrite(filename, frame)
d+=1
this will save every frame with different name.

Categories

Resources