使用pysimplegui+opencv编写一个摄像头的播放器

需求

使用pysimplegui和opencv实现一个播放器,播放 摄像头的画面。

代码实现

python 复制代码
import cv2
import time
from typing import Iterable, NamedTuple, Optional

import PySimpleGUI as sg

class CameraSpec(NamedTuple):
    name: str
    index: int
    width: int
    height: int
    fps: int

def init_window(theme_name: str = "DarkBlack", window_name: str = "UVC capture"):
    print(f"init theme with name {theme_name!r}")
    sg.theme(theme_name)

    layout = [
      [sg.Text('UVC Demo', size=(60, 1), justification='center')],
      [sg.Image(filename='', key='-IMAGE-')],
      [sg.Button('退出', size=(10, 1), key='-Exit-')]
    ]

    print(f"init window with name {window_name!r}")
    window = sg.Window(window_name, layout, location=(10, 10), resizable=True)
    return window

def main(camera_spec: CameraSpec):
    print(f"init {camera_spec.index}th camera with name {camera_spec.name}")
    capture = cv2.VideoCapture(camera_spec.index)
    if capture == None:
        print(f"No matching camera with CameraSpec {camera_spec} found")
        return
    
    size = (int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    print(f"get size:{size}")

    wret = capture.set(cv2.CAP_PROP_FRAME_WIDTH, camera_spec.width)
    hret = capture.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_spec.height)
    print(f"wret:{wret} hret:{hret}")
    size = (int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    print(f"get size:{size}")

    
    window = init_window(window_name=camera_spec.name)
    #last_update = time.perf_counter()

    try:
        keep_running = True
        i  = 0
        while keep_running:
            before = time.perf_counter()
            event, values = window.read(timeout=5)
            if event == '-Exit-' or event == sg.WIN_CLOSED:
                break

            after_event = time.perf_counter()
            print(f"====after_event:{after_event-before}====")

            try:
                _, frame = capture.read()
            except TimeoutError:
                pass
            else:
                after_frame = time.perf_counter()
                print(f"after_frame:{after_frame-after_event}")

                #将每一帧编码成png播放
                imgbytes = cv2.imencode('.png', frame)[1].tobytes()
                
                after_show = time.perf_counter()
                print(f"after_show:{after_show-after_frame}")
                print(f"sum:{after_show-before}")
                window['-IMAGE-'].update(data=imgbytes)

                #cv2.imshow(camera_spec.name, bgr)  
                # if cv2.waitKey(1) & 0xFF == 27:
                #    break  
                # with open(f"bgr{i}.bgr",'wb') as f:
                #     f.write(bgr)
                # i += 1
    except KeyboardInterrupt:
        pass

    capture.close()
    print(f"close camera:{camera_spec}")


if __name__ == "__main__":
    main(
            CameraSpec(
                name="播放摄像头测试",
                index=0, #摄像头编号
                width=1280,
                height=720,
                fps=10,
            ),

    )

效果:

代码说明

打开摄像头:

python 复制代码
capture = cv2.VideoCapture(camera_spec.index)

从摄像头取帧:

python 复制代码
_, frame = capture.read()

将帧送到窗口播放:

python 复制代码
#将每一帧编码成png图片
imgbytes = cv2.imencode('.png', frame)[1].tobytes()
window['-IMAGE-'].update(data=imgbytes)  #这里播放

由于使用PySimpleGUI的Image作为播放控件,所以每一帧都要转换成图片。除了png, 好像tif也可以,我没试。

从这里也可以看出来,pysimplegui播放的效率还是有点低的,要先编码成图片。但是作为一些小工具来讲,可以接受。

相关推荐
菜鸟的人工智能之路8 分钟前
极坐标气泡图:医学数据分析的可视化新视角
python·数据分析·健康医疗
菜鸟学Python9 分钟前
Python 数据分析核心库大全!
开发语言·python·数据挖掘·数据分析
小白不太白95011 分钟前
设计模式之 责任链模式
python·设计模式·责任链模式
喜欢猪猪16 分钟前
Django:从入门到精通
后端·python·django
糖豆豆今天也要努力鸭22 分钟前
torch.__version__的torch版本和conda list的torch版本不一致
linux·pytorch·python·深度学习·conda·torch
何大春38 分钟前
【弱监督语义分割】Self-supervised Image-specific Prototype Exploration for WSSS 论文阅读
论文阅读·人工智能·python·深度学习·论文笔记·原型模式
在下不上天1 小时前
Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复
大数据·开发语言·python
SEVEN-YEARS1 小时前
深入理解TensorFlow中的形状处理函数
人工智能·python·tensorflow
EterNity_TiMe_1 小时前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
Suyuoa1 小时前
附录2-pytorch yolov5目标检测
python·深度学习·yolo