我的NVIDIA开发者之旅——Jetson-Utils库使用及报错解决

The_Dark_Shark 2022-06-07 14:48:16
加精

Jetson-Utils简介:

        Nvidia的工程师在Github上开源了一个叫Jetson-inference的项目,这个项目也就是Hello-AI-World,作为Jetson深度学习开发的入门教程被NVIDIA推广。著名的《10行代码实现目标检测》即出自其中,这10行代码如下:

import jetson.utils
input = jetson.utils.videoSource("csi://0") #或"/dev/video0"
output = jetson.utils.videoOutput("display://0")

import jetson.inference
net = jetson.inference.detectNet("ssd-mobilene-v2",threshold=0.5)

while output.IsStreaming():
    img = input.Capture()
    detections = net.Detect(img)
    output.Render(img)
    output.SetStatus("Performance:{:.0}FPS".format(net.GetNetworkFPS())

        其中第一行导入了一个叫jetson.utils的库,这个库其实是这个作者的另一个项目,可以单独使用,也就是今天我们的主角。但是由于jetson-inference名气太大,导致jetson-utils这个项目的很多issue都在jetson-inference项目里,这也导致jetson-utils的问题,并不能在jetson-utils项目里找到答案,而要去jetson-inference里去找,甚至jetson-utils的一些使用方法,也需要去jetson-inference里找案例。

        由于jetson-inference只提供了一些常见模型,精度也有限,一般不能满足实际需求,但是视频硬件编解码、GPU图像处理这些我们又希望在GPU里做,甚至希望Jetson能直接硬解码视频到显存,然后在GPU里做resize、Normalization、Color Conversion等图像操作,再把处理好的图像放进高精度的模型中进行推理,这个时候我们不需要jetson-inference的东西,而只需要jetson-utils,因为jetson-utils提供了上述推理以外的现成函数,有了这个库,我们不需要手动写编解码库,不需要手动写基础图像处理的GPU函数,只需要调用相关函数即可完成相应操作,因此这个库可能能帮助许多人。

        这个库的详细C++手册在:https://rawgit.com/dusty-nv/jetson-inference/dev/docs/html/group__util.html 这个页面。

        这个库的Python手册则在:https://rawgit.com/dusty-nv/jetson-inference/dev/docs/html/python/jetson.utils.html#videoOutput

        打开对比一下可以发现,python版的手册很短,甚至很多函数没有参数列表,只有一句功能描述:

         可能作者觉得,我们从函数名就能才出来函数是干什么的,因此没必要再描述一下。。。。

Jetson-Utils库使用

    

        相关的python案例在jetson-inference/utils/python/examples/下可以找到,比如视频流读取、输出到显示设备、RTP流、编码成视频文件、解码后图像转opencv图像、转numpy数组等,但是依然有normalize等函数没有提及,至于format之类的参数,有没有介绍。导致使用起来,需要不断测试参数是否正确,甚至无法测试,只能看不能用,其实更详细的用法在这个页面:https://github.com/dusty-nv/jetson-inference/blob/master/docs/aux-image.md

        没错,这个库的详细使用案例,其实在jetson-inference项目的doc下。。。

        我们对这个库进行最常用的两个函数:视频输入读取、屏幕显示画面,进行介绍,并介绍这两个函数的一个bug和解决方案。

        我们先来看一下一个简单案例:

        

import jetson.utils
input = jetson.utils.videoSource("jellyfish.mkv")
output = jetson.utils.videoOutput("display://0")

while output.IsStreaming():
    img = input.Capture()
    output.Render(img)

        代码第二行读取视频流,第三行指定屏幕输出,jellyfish.mkv是NVIDIA提供的一个h264编码的视频。如果不出意外的话,可以运行良好,读取视频显示画面。

但是,如果改成自己的视频,就有可能出现,视频读取成功,终端输出解码信息,解码成功,但是不显示画面,如果你把信息拉到最上面,可以看到这个报错:

 

        [OpenGL] failed to create X11 Window.

        笔者测试将解码后的图像转为opencv帧,再调用cv2.imshow()是可以正常显示的,也即解码是正常的,只是jetson.utils.videoOutput出了问题。

        甚至在我这台NX上,上述代码不做任何改动,也即还是用jellyfish.mkv只在import.utils之后,新加入一行:import jetson.inference,也会报上面的错误,将解码后的帧转为opencv再调用cv2.imshow()也是可以正常显示的,又是解码正常但是jetson.utils.videoOutput出了问题。

        这个问题的解决方法是将input、output行代码位置对调,也即改为:

import jetson.utils

output = jetson.utils.videoOutput("display://0")
input = jetson.utils.videoSource("2.mp4")

while output.IsStreaming():
    img = input.Capture()
    output.Render(img)

        其中2.mp4是我自己的测试视频,也即改之前不能正常显示的视频,位置对调后,即可成功渲染画面。

        如果你是import jetosn.utils后马上import jetson.inference,出现的这个错误,然后对“[OpenGL] failed to create X11 Window.”这个错误进行搜索,可能会找到作者提供的另一种解决办法:

        在videoOutput之后再导入jetson.inference,也即代码为这样:

import jetson.utils
input = jetson.utils.videoSource("2.mp4")
output = jetson.utils.videoOutput("display://0")
import jetson.inference


while output.IsStreaming():
    img = input.Capture()
    output.Render(img)

        但是这种方法不是所有情况都有效,笔者测试后发现,input、output行代码位置对调一般都有效。

        对于这个bug,作者是这么回复的:

 “我无法复现,你先这么用吧。”

"我的NVIDIA开发者之旅” | 征文活动进行中.......

 

...全文
2676 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,335

社区成员

发帖
与我相关
我的任务
社区描述
NVIDIA 开发者技术交流
人工智能 企业社区
社区管理员
  • nvdev
  • 活动通知
  • AI_CUDA_Training
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧