How to capture images of live feed continuously when a key is pressed?

Question:

I integrate Allied Vision Camera Manta G-201C with python. I want to start capturing imgaes when I press key ‘c’, otherwise it should continuosly show the image (eventhough I pressed the key). I have the whole code which is running perfectly, but I don’t know how to add this task to the code.

The code is given below:

from datetime import datetime
from functools import partial
import queue
import time
 
from vimba import *
import cv2
 
 
def setup_camera(cam):
    cam.set_pixel_format(PixelFormat.BayerRG8)
    cam.ExposureTimeAbs.set(10000)
    cam.BalanceWhiteAuto.set('Off')
    cam.Gain.set(0)
    cam.AcquisitionMode.set('Continuous')
    cam.GainAuto.set('Off')
    # NB: Following adjusted for my Manta G-033C
    cam.Height.set(492)
    cam.Width.set(656)
 
# Called periodically as frames are received by Vimba's capture thread
# NB: This is invoked in a different thread than the rest of the code!
def frame_handler(frame_queue, cam, frame):
    img = frame.as_numpy_ndarray()
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BAYER_RG2RGB)
    try:
        # Try to put the frame in the queue...
        frame_queue.put_nowait(img_rgb)
    except queue.Full:
        # If that fials (queue is full), just drop the frame
        # NB: You may want to handle this better...
        print('Dropped Frame')
    cam.queue_frame(frame)
    
def do_something(img, count):
    filename = 'data/IMG_' + str(count) + '.jpg'
    cv2.putText(img, str(datetime.now()), (20, 40)
        , cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255)
        , 2, cv2.LINE_AA)
    cv2.imwrite(filename, img)
 
def run_processing(cam):
    try:
        # Create a queue to use for communication between Vimba's capture thread
        # and the main thread, limit capacity to 10 entries
        frame_queue = queue.Queue(maxsize=10)
        # Start asynchronous capture, using frame_handler
        # Bind the first parameter of frame handler to our frame_queue
        cam.start_streaming(handler=partial(frame_handler,frame_queue)
            , buffer_count=10)
 
        start = time.time()
        frame_count = 0
        while True:
            if frame_queue.qsize() > 0:
                # If there's something in the queue, try to fetch it and process
                try:
                    frame = frame_queue.get_nowait()
                    frame_count += 1
                    cv2.imshow('Live feed', frame)
                    do_something(frame, frame_count)
                except queue.Empty:
                    pass
                
            key = cv2.waitKey(1)
            if (key == ord('q')) or (frame_count >= 100):
                cv2.destroyAllWindows()
                break
        
        fps = int((frame_count + 1)/(time.time() - start))
        print('FPS:', fps)
    finally:
        # Stop the asynchronous capture
        cam.stop_streaming()
 
#@profile
def main():
    with Vimba.get_instance() as vimba:
        with vimba.get_all_cameras()[0] as cam:
            setup_camera(cam)
            run_processing(cam)
 
if __name__ == "__main__":
    main()

I want to execute the do_something() function (that basically save the images) when I press once key ‘c’, then it should continously save the images, along with showing image untill I press key ‘q’ to stop the camera and close all the windows. I don’t know how to proceed. Any help is appreciated!!

Asked By: Hardik_Zalavadiya

||

Answers:

As seen from the code, you are trying to save images and the format is IMG0.jpg, IMG1.jpg, IMG2.jpg and so on until the key "q" is pressed. See the code below, it is working on my device (ASUS F570Z, python 3.7.8):

from datetime import datetime
from functools import partial
import queue
import time
from vimba import *
import cv2
import os
import glob
import keyboard

path = 'E:\JPG_dataset\dataset3\'
delete_frame_number = 0

def delete_frames(count):
    removing_files = glob.glob(path+'*jpg')
    for file in removing_files:
        if int(file.replace("\", ".").split(".")[3].split("IMG")[1]) < int(count):
            os.remove(file)
        else:
            continue

def setup_camera(cam):
    feature = cam.get_feature_by_name("AcquisitionFrameRateAbs")
    feature.set(30) #specifies 30FPS
    # set the other features TriggerSelector and TriggerMode
    feature = cam.get_feature_by_name("TriggerSelector")
    feature.set("FrameStart")
    feature = cam.get_feature_by_name("TriggerMode")
    feature.set("Off")

    cam.ExposureTimeAbs.set(30000)
    cam.set_pixel_format(PixelFormat.BayerRG8)
    cam.BalanceWhiteAuto.set('Off')
    cam.Gain.set(0)
    cam.AcquisitionMode.set('Continuous')
    cam.GainAuto.set('Off')
    # NB: Following adjusted for my Manta G-201C
    cam.Height.set(720)
    cam.Width.set(1280)
 
# Called periodically as frames are received by Vimba's capture thread
# NB: This is invoked in a different thread than the rest of the code!
def frame_handler(frame_queue, cam, frame):
    img = frame.as_numpy_ndarray()
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BAYER_RG2RGB)
    try:
        # Try to put the frame in the queue...
        frame_queue.put_nowait(img_rgb)
    except queue.Full:
        # If that fials (queue is full), just drop the frame
        # NB: You may want to handle this better...
        print('Dropped Frame')
    cam.queue_frame(frame)
    
def do_something(img, count):
    # datetime.now().strftime('%Y-%m-%d %H-%M-%S')
    # datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
    filename = 'IMG' + str(count) + '.jpg'
    cv2.putText(img, str(datetime.now()), (20, 40)
        , cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255)
        , 2, cv2.LINE_AA)
    cv2.imwrite(filename, img)
 
def run_processing(cam):
    global delete_frame_number
    try:
        # Create a queue to use for communication between Vimba's capture thread
        # and the main thread, limit capacity to 10 entries
        frame_queue = queue.Queue(maxsize=30)
        # Start asynchronous capture, using frame_handler
        # Bind the first parameter of frame handler to our frame_queue
        cam.start_streaming(handler=partial(frame_handler,frame_queue)
            , buffer_count=10)
 
        start = time.time()
        frame_count = 0
        while True:
            if frame_queue.qsize() > 0:
                # If there's something in the queue, try to fetch it and process
                try:
                    frame = frame_queue.get_nowait()
                    frame_count += 1
                    cv2.putText(frame, str(datetime.now()), (20, 40)
                    , cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255)
                    , 2, cv2.LINE_AA)
                    cv2.imshow('Live feed', frame)
                    if keyboard.is_pressed("c"):
                        delete_frame_number = frame_count
                    do_something(frame, frame_count)
                except queue.Empty:
                    pass
                
            key = cv2.waitKey(5)
            if (key == ord('q')):
                cv2.destroyAllWindows()
                delete_frames(delete_frame_number)
                break
        
            fps = int((frame_count + 1)/(time.time() - start))
            print('FPS:', fps)
    finally:
        # Stop the asynchronous capture
        cam.stop_streaming()
 
#@profile
def main():
    with Vimba.get_instance() as vimba:
        with vimba.get_all_cameras()[0] as cam:
            os.chdir(path)
            setup_camera(cam)
            run_processing(cam)
 
if __name__ == "__main__":
    main()

I have created a function delete_frames(), that will take current frame number as argument. As a result, when you execute the code, it will save the images from the beginning (for example IMG1.jpg, IMG2.jpg ….) and when you press the keyboard button "c", it will take the frame number and save it in a variable that will be the argument of function detele_frames() and in that it will delete all the frames before that particular frame number that you feed as argument and hence you will get all the images that is required when you press the button ‘c’.

Answered By: SmitShah_19
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.