opencv 如何在按下某个键时连续捕获直播源的图像?

1cosmwyk  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(171)

我集成了联合视觉相机蝠鲼G-201C与Python。我想开始捕捉imgaes当我按下键'c',否则它应该continuosly显示图像(即使我按下了键)。我有整个代码,这是完美的运行,但我不知道如何添加此任务的代码。
代码如下所示:

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

我想执行的do_something()函数(基本上保存图像)当我按下一次键'c',然后它应该不断保存图像,随着显示图像,直到我按下键'q'停止相机和关闭所有窗口。我不知道如何继续。任何帮助是感谢!!

von4xj4u

von4xj4u1#

从代码中可以看到,您正在尝试保存图像,格式为IMG0.jpg,IMG1.jpg,IMG2.jpg等,直到按下“q”键。请参见下面的代码,它在我的设备(华硕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()

我创建了一个函数delete_frames(),它将当前帧号作为参数。因此,当您执行代码时,它将从头保存图像(例如IMG1. jpg、IMG2. jpg ....),当您按下键盘按钮“c”时,它将获取帧编号并将其保存在一个变量中,该变量将成为函数detele_frames的参数(),它将删除您作为参数输入的特定帧编号之前的所有帧,因此,当您按下按钮“c”时,您将获得所需的所有图像。

相关问题