利用USB摄像头获取视频用于目标检测(Python)——后续心得
收藏回复举报
利用USB摄像头获取视频用于目标检测(Python)——后续心得
发表于2023-08-29 19:32:58
0 查看

通过前面的帖子,已经可以实现用USB摄像头实时采集画面进行模型分析并可以实时显示。不过效果十分不理想。

不过2023年8月3日新版本(23.0.RC2)更新让这些问题得以大幅度缓解。

新版本比上一部版本优化了很大,开机速度变快,镜像运行也更加稳定。用帖一的代码在新版本镜像下运行已经不会出现卡顿和掉帧问题,最后输出的视频也够流畅。这项功能终于可以用了,但对于帖二来说我们还需要实时显示分析画面。

我的代码中给出了一种解决方式:

就是利用plt库来创建图像窗口,我们显示用plt.figure()创建窗口,在用plt.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) 进行格式转换,最后利用plt.pause(0.01) 刷新图像并进行成像。

但plt库是一个用于绘图的Python库,用它来实时显示画面还是很为难,通过实验我发现每次刷新窗口需要时间过长,会占用90%的运行时间,这就导致出来的图像卡顿、掉帧,但这是没办法的事,因为人家本来就不是干这个活的。那有没有其他方法呢?

第二:我发现在CV2库中,要显示图像,可以使用cv2.imshow()函数。这个函数接受两个参数,第一个参数是窗口的名称,第二个参数是要显示的图像。比如说

cv2.imshow('USB Camera', frame)

但是不幸的是,我每次使用会产生如下报错

cv2.error: OpenCV(4.7.0) /io/opencv/modules/highgui/src/window.cpp:1272: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'

这个错误是说我的OpenCV库中没有实现。这可能是因为你的库没有使用必要的依赖项来显示图像,可以安装可以通过运行以下命令安装libgtk2.0-dev包和pkg-config工具来安装图像显示所需的依赖项

可以用以下命令安装

sudo apt-get install libgtk2.0-dev pkg-config

但系统提示已经是最新的不需要升级。我也进行了很多尝试但始终无法成功。

第三:在官方资料显示可以登录juypter lab,在“01-yolov5”模型样例中可以实时显示摄像头的分析画面。我分析了一下代码,主要是靠一下程序实现的

先加入库文件

import ipywidgets as widgets
from IPython.display import display

然后在初始化代码前加入

image_widget = widgets.Image(format='jpeg', width=1280, height=720)
display(image_widget)

cke_58641.png

这段代码创建了一个名为image_widget的图像小部件(widget),该小部件用于显示图像。它使用了JPEG格式的图像,并设置了图像的宽度为1280像素,高度为720像素。最后,通过display()函数将该小部件显示在屏幕上。

然后我们在while循环最后加入

image_widget.value = bytes(cv2.imencode('.jpg', img_dw)[1]) #将图片转换为字节码

这段代码将图片转换为字节码,并将字节码赋值给image_widget的value属性。从而不断更新图像

可遗憾的是在jupyter lab软件中可以实时显示图像,但是在MobaXterm中只能输出图像的二进制值。

以上三种实时显示方式是我能想到的,但是都无法很好成功,不过后面两种理论上都没问题,随着产品的更新这些方式应该可以实现。

这应该会是最后一贴,后面应该不在接触了,所用开发板也是学校暂时提供的(大家的留言消息也就无力回复了)。留下一些经验和方式,期待各位去解决这个问题。感谢各位!!!

对了前面所有代码都是使用MindX SDK编程接口。这里提供一下AscendCL接口的代码程序,只需要修改main主函数就行

if __name__ == '__main__':
    context = init_acl(DEVICE_ID)  # 初始化acl相关资源
    det_model = YoloV5(model_path=trained_model_path)  # 初始化模型

    # 打开摄像头
    cap = cv2.VideoCapture(0)  # 打开摄像头

    # 获取保存视频相关变量
    fps = cap.get(cv2.CAP_PROP_FPS)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    outfile = 'output_png/video_result.mp4'  # 设置结果保存文件
    video_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    video_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    writer = cv2.VideoWriter(outfile, fourcc, fps, (video_width, video_height))

    image_widget = widgets.Image(format='jpeg', width=1280, height=720)
    display(image_widget)
    try:
        while (cap.isOpened()):  # 在摄像头打开的情况下循环执行
            ret, frame = cap.read()  # 此处 frame 为 bgr 格式图片
            # 读入文件并推理
            # img = cv2.imread(image_path, cv2.IMREAD_COLOR)  # 读入图片
            img_res = det_model.infer(frame)  # 前处理、推理、后处理, 得到最终推理图片
            # 初始化可视化对象
            image_widget.value = bytes(cv2.imencode('.jpg', img_res)[1])  # 将图片转换为字节码
            writer.write(img_res)  # 将推理结果写入视频
            #cv2.imwrite('img_res.png', img_res)
    except KeyboardInterrupt:
        cap.release()  # 释放摄像头资源
        writer.release()  # 释放视频写入资源
    finally:
        cap.release()
        writer.release()

    # 释放相关资源
    det_model.release()  # 释放 acl 模型相关资源, 包括输入数据、输出数据、模型等
    deinit_acl(context, 0)  # acl 去初始化
    print('save infer result success')

本帖最后由 匿名用户 于 2026/09/03 15:18:45 编辑

我要发帖子