/*--------------------CSS部分-------------------*/ /*--------------------JS部分-------------------*/

使用gradio和opencv实现摄像头的读取

测试程序的界面如下:

其程序在多线程实现摄像机读取的基础上直接进行调用和读取。

代码中实现前后摄像头的读取。

class IntelliGuideTab:
    def __init__(self) -> None:
        self.camera_info = {"height": 480, "width": 640}
        self.create_ui()

        self.camera1_process = None
        self.camera0_process = None
        self.camera0 = None
        self.camera1 = None
        self.create_camera()

    def create_camera(self):
        self.camera0 = CameraBroadcaster(self.camera_info,0)
        self.camera0_process = Process(target=self.camera0.run)
        self.camera0_process.start()

        self.camera1 = CameraBroadcaster(self.camera_info, 1)
        self.camera1_process = Process(target=self.camera1.run)
        self.camera1_process.start()


    def inference(self):
        while True:
            #图像从共享内存中获取
            frame0 = np.ndarray((self.camera0.height, self.camera0.width, 3), dtype=np.uint8,
                                buffer=self.camera0.frame.buf)
            frame1 = np.ndarray((self.camera1.height, self.camera1.width, 3), dtype=np.uint8,
                                buffer=self.camera1.frame.buf)

            #必须转换,否则显示图像有问题,主要是opencv读取是BGR,显示是RGB
            frame0 = cv2.cvtColor(frame0, cv2.COLOR_BGR2RGB)
            frame1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2RGB)

            #此处必须是while循环,然后不停地返回图像
            yield frame0,frame1


    def stop(self):
        #此处stop不起作用个,不知道为啥
        print("start stop read camera")
        self.camera0.stop_sign.value = True
        self.camera0_process.join()

        self.camera0.stop_sign.value = True
        self.camera1_process.join()
        print("finish stop read camera")


    def create_ui(self):
        #按照格局进行图像控件的读取
        with gr.Column():
            with gr.Row():
                front_ouput = gr.Image(
                    label='前置',
                    source='upload',
                    width=self.camera_info["width"],
                    height=self.camera_info["height"],
                    interactive=False
                )

                back_input = gr.Image(
                    label='后置',
                    source='upload',
                    width=self.camera_info["width"],
                    height=self.camera_info["height"],
                    interactive=False
                )

        with gr.Row():
            start_btn = gr.Button("Start")
            #关键点在这,inference是处理函数,返回值是两个图像,然后绑定在gr.Image中
            start_btn.click(self.inference, outputs=[front_ouput, back_input])

            stop_btn = gr.Button("Stop")
            stop_btn.click(self.stop)





if __name__ == "__main__":
    title = 'Web Demo'

    DESCRIPTION = '''its corresponding grounding mask'''

    with gr.Blocks(analytics_enabled=False, title=title) as demo:
        gr.Markdown(DESCRIPTION)
        with gr.Tabs():
            with gr.TabItem('IntelliGuide'):
                IntelliGuideTab()
    demo.queue().launch()

本来在程序中将图像放入到queue中,然后主线程获取,发现主线程获取较慢,导致显示延缓,queue的size不停地变大。
下面将基于queue的程序附上,但效果较差,关键是主线程读取图像太慢,导致显示慢,估计是在gr.Image中刷新时,会影响耗时。

点击查看代码
class IntelliGuideTab:
    def __init__(self) -> None:
        self.camera_info = {"height": 480, "width": 640}
        self.create_ui()
        self.camera0 = None
        self.camera1 = None
        self.frame_queue0 = Queue(maxsize=30)
        self.frame_queue1 = Queue(maxsize=30)
        self.create_camera()

    def create_camera(self):
        self.camera0 = CameraReader(self.camera_info,0,self.frame_queue0)
        self.camera0.start()

        self.camera1 = CameraReader(self.camera_info, 1,self.frame_queue1)
        self.camera1.start()


    def inference(self):
        while True:
            if self.frame_queue0.empty() or self.frame_queue1.empty():
            #     print("333333 start get the length is ", self.frame_queue0.qsize())
            #     print("444444 start get the length is ", self.frame_queue1.qsize())
                continue
            frame0 = self.frame_queue0.get(timeout=1)
            frame1 = self.frame_queue1.get(timeout=1)
            print("0000 start get the length is ", self.frame_queue0.qsize())
            print("1111 start get the length is ", self.frame_queue1.qsize())
            frame0 = cv2.cvtColor(frame0, cv2.COLOR_BGR2RGB)
            frame1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2RGB)

            yield frame0,frame1


    def stop(self):
        print("start stop read camera")
        self.camera0.join()

        self.camera1.join()
        print("finish stop read camera")


    def create_ui(self):
        with gr.Column():
            with gr.Row():
                front_ouput = gr.Image(
                    label='前置',
                    source='upload',
                    width=self.camera_info["width"],
                    height=self.camera_info["height"],
                    interactive=False
                )

                back_input = gr.Image(
                    label='后置',
                    source='upload',
                    width=self.camera_info["width"],
                    height=self.camera_info["height"],
                    interactive=False
                )

        with gr.Row():
            start_btn = gr.Button("Start")
            # start_btn.click(self.inference, outputs=[front_ouput, back_input])
            start_btn.click(self.inference)

            stop_btn = gr.Button("Stop")
            stop_btn.click(self.stop)
在将start_btn.click(self.inference, outputs=[front_ouput, back_input])注释后,日志打印显示,读取瞬间无压力。说明gr.Image的问题。
posted @ 2023-08-07 16:57  bldong  阅读(998)  评论(0编辑  收藏  举报