在网上找了好多关于Jetson Nano部署Yolo v5的帖子,由于每个人的环境和版本都不同,过程也都有所不同,因此在Jetson Orin Nano CLB上安装Yolo v5也有必要记录一下过程,以便后续无脑重装,让我们开始。
由于我这个Jetson Orin Nano CLB是固态硬盘的形式,没有SD卡槽,因此不能按Nvidia官方采用SD卡进行系统烧录的方式。
环境:
- Jetpack : 5.1.1
- CUDA : 11.4
- OpenCV : 4.5.4
- Python : 3.8.10
- DeepStream : 6.2
一、烧录
1. 由于之前虚拟机的系统是22.04很多东西都太新了,导致按教程安装有问题,懒得降级,这里在VMware虚拟机里直接安装64位ubuntu18.04系统并保持apt-get update 和 grade到最新,如果太慢就换源。
2. 安装烧录环境,分别执行以下命令。
sudo apt-get install qemu-user-static
sudo apt-get install python
直到输入python -V能显示python 2.7就OK。
3. 将Jetson Orin Nano CLB套件客户资料文件夹下的这两个文件拷贝到ubuntu的某个文件夹下。
Jetson Orin Nano CLB套件客户资料,百度云盘地址:
链接:https://pan.baidu.com/s/1qZOkOxiAFLRZep6InPwpTw
提取码:xx4i
4. cd到这两个文件所在目录下,分别执行以下命令解压缩文件,这两个解压缩时间都很久,要耐心等候。
tar xf Jetson_Linux_R35.3.1_aarch64.tbz2
sudo tar xpf Tegra_Linux_Sample-Root-Filesystem_R35.3.1_aarch64.tbz2 -C Linux_for_Tegra/rootfs/
以上是参考Nvidia官网的烧录教程
Quick Start — Jetson Linux Developer Guide documentation
如果遇到下图所示的错误信息,说明文件有错误,解压失败。那就需要到官网Jetson Linux Archive | NVIDIA Developer重新下载固件并执行以上操作。
官网固件下载指引见下图:
5. 配置
cd 到Linux_for_Tegra目录下,分别执行以下命令:
sudo ./apply_binaries.sh
./tools/l4t_flash_prerequisites.sh
6. 烧录
短接FC_REC和GND(这个角度看,是从上往下第二个和第三个引脚),接上TypeC接口,完了之后上电。
尽量插到USB2.0的口子上,并且保证USB插拔时,VMware有提示,此时选择“连接到虚拟机”,否则烧不进去,会显示找不到设备。
确保NVIDIA APX被勾选
如果没有,并且连接显示为灰色。请移步到这位兄台的页面下:
VMware能识别usb设备,但无法连接(灰色)的问题解决办法_虚拟机显示所有usb输入设备灰色_黑刀夜的博客-CSDN博客
cd 到Linux_for_Tegra目录下,分别执行以下命令开始烧写,需要耐心等待,中间有一步会显示以上两个画面(证明已经识别到硬件),要及时选择"连接到虚拟机",才能正常烧录进去。(建议带个耳机,这样在中间耳机有连接的声音时,就可以及时做出响应)
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --external-device nvme0n1p1 \
-c tools/kernel_flash/flash_l4t_external.xml -p "-c bootloader/t186ref/cfg/flash_t234_qspi.xml" \
--showlogs --network usb0 jetson-orin-nano-devkit internal
直到出现以下信息,烧录完毕,拔掉跳线,重新上电即可。
二、CUDA环境安装
1. 安装pip3
sudo apt-get install python3-pip
sudo pip3 install -U pip
2. 安装Jtop
sudo pip3 install -U jetson-stats
安装好之后,就可以输入命令打开jtop,看到Libraries没有安装。
sudo jtop
3. 安装Library
sudo apt-get install nvidia-jetpack
完成之后再来看jtop,库已经装好了,并且能显示版本。
4. 连接并测试摄像头(这个角度看,排线黑色一面朝里,金手指朝外)
通过以下命令查看是否成功挂载了摄像头
ls /dev/video*
执行以下命令以启动CSI-Camera摄像头的测试程序,检测摄像头显示是否正常。
nvgstcapture-1.0
5、配置CUDA
# 打开文档
sudo gedit ~/.bashrc
# 在文档末尾添加
export CUDA_HOME=/usr/local/cuda-11.4
export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH
export PATH=/usr/local/cuda-11.4/bin:$PATH
# 保存并查看配置
source ~/.bashrc
nvcc -V #如果配置成功可查看CUDA的版本号
6、修改显存
命令如下:
sudo gedit /etc/systemd/nvzramconfig.sh
'''
修改mem = $((("${totalmem}"/2/"${NRDEVICES}")*1024))
为mem = $((("${totalmem}"*2/"${NRDEVICES}")*1024)) # 不要复制粘贴,可能会导致修改不成功
'''
即将2前面的/改为*
# 保存
修改显存后重启Nano
reboot
# 重启之后
free -h #可以看到"交换"已经不是0,我这里变成14G
三、安装pytorch与torchvision
由jtop的信息中可以得知Jetpack的版本为Jeppack 5.1.1。根据Nvidia官网链接 以及PyTorch链接可知对应的pytorch和torchvision版本如下:
但实际上,Jetpack 5.1.1可用的版本组合是 pytorch 1.14.0,而torchvision对应的版本为torchvision 0.15.1
先安装依赖库
sudo apt-get -y install autoconf bc build-essential g++-8 gcc-8 clang-8 lld-8 gettext-base gfortran-8 iputils-ping libbz2-dev libc++-dev libcgal-dev libffi-dev libfreetype6-dev libhdf5-dev libjpeg-dev liblzma-dev libncurses5-dev libncursesw5-dev libpng-dev libreadline-dev libssl-dev libsqlite3-dev libxml2-dev libxslt-dev locales moreutils openssl python-openssl rsync scons python3-pip libopenblas-dev;
Nvidia官网里Jetpack对应的torch和torchvision 这里选v51/pytorch/里的最后一个
下载whl文件后安装torch
pip3 install torch-1.14.0a0+44dac51c.nv23.02-cp38-cp38-linux_aarch64.whl
使用下面的命令行从源码安装torchvision 0.15.1及其依赖库:
sudo apt install libjpeg-dev zlib1g-dev libpython3-dev libavcodec-dev libavformat-dev libswscale-dev
pip3 install --upgrade pillow
wget https://github.com/pytorch/vision/archive/refs/tags/v0.15.1.zip
unzip v0.15.1.zip
cd vision-0.15.1
export BUILD_VERSION=0.15.1
python3 setup.py install --user
这个过程有点慢,需耐心等候,如果失败,再多试几次 。
安装完成之后通过以下命令验证是否安装成功:
python3
import torch
import torchvision
print(torch.cuda.is_available()) # 这一步如果输出True那么就成功了!
到这里再执行以下命令,摄像头应该能正常打开。
nvgstcapture-1.0
如果摄像头打不开,可能是因为安装了opencv-python,因为它默认没有开启GStreamer的支持,
检查是否安装了opencv-python
pip3 list
输入python3进入python环境下执行以下命令:
import cv2 as cv
print(cv.getBuildInformation())
会发现GStreamer没有开启,那也就是说默认安装的OpenCV是不支持GStreamer的,那么就要手动重新编译并打开这个选项了,去第四步,如果摄像头能正常打开,GStreamer : YES,则可以跳到第五步。
四、手动编译OpenCV并使能GStreamer=ON
1. 卸载现有的opencv-python
sudo pip3 uninstall opencv-python
2. 安装编译需要的环境
sudo apt-get install cmake
sudo apt-get install gcc g++
3. 安装python依赖库
sudo apt-get install python3-dev python3-numpy
sudo apt-get install libgtk-3-dev
sudo apt-get install libpng-dev
sudo apt-get install libjpeg-dev
sudo apt-get install libopenexr-dev
sudo apt-get install libtiff-dev
sudo apt-get install libwebp-dev
4. 下载Opencv4.5.4
5. 配置编译选项,使能GStreamer选项
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_C_EXAMPLES=OFF -D PYTHON_EXECUTABLE=$(which python3) -D BUILD_opencv_python2=OFF -D CMAKE_INSTALL_PREFIX=$(python3 -c "import sys; print(sys.prefix)") -D PYTHON3_EXECUTABLE=$(which python3) -D PYTHON3_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") -D PYTHON3_PACKAGES_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") -D WITH_GSTREAMER=ON -D BUILD_opencv_python3=yes \-D BUILD_EXAMPLES=ON ..
6. 安装
make -j8
sudo make install
再次输入python3进入python环境下执行以下命令:
import cv2 as cv
print(cv.getBuildInformation())
发现已经OK了,GStreamer : YES
到这里再执行CSI_Camera文件夹下的python3 simple_camera.py时,摄像头已经成功显示图像。
7. 不要安装opencv-python(这个一装上一步的GStreamer又变成NO了,摄像头又不显示了,还得卸载了,重新编译)
pip3 install opencv-python==4.5.4.60
五、部署yolo v5
git clone https://github.com/ultralytics/yolov5.git
python3 -m pip install --upgrade pip
cd yolov5
pip3 install -r requirements.txt
python3 -m pip list
python3 detect.py --source data/images/bus.jpg --weights yolov5n.pt --img 640 #图片测试
python3 detect.py --source video.mp4 --weights yolov5n.pt --img 640 #视频测试频
python3 detect.py --source 0 --weights yolov5n.pt --img 640 #摄像头测试
如果是单独插了一个USB摄像头,执行上述最后一条命令,应该会成功执行示例目标检测程序:
可是,如果是连接的是排线那种CSI摄像头,那么可能就显示不出图像,或者图像是绿色的。这是因为CSI Camera是通过gstreamer这种跨平台管道模式进行图像传输,跟USB不是一回事,而yolov5中的detect.py中又没有针对这种视频源提供接口,因此还要安装DeepStream,通过它来调用摄像头。如果你一定要使用这种排线的CSI Camera,就需要进一步安装DeepStream。
六、安装DeepStream
1. 安装依赖项
执行以下命令,参考自Quickstart Guide — DeepStream 6.2 Release documentation
sudo apt install \
libssl1.1 \
libgstreamer1.0-0 \
gstreamer1.0-tools \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
libgstreamer-plugins-base1.0-dev \
libgstrtspserver-1.0-0 \
libjansson4 \
libyaml-cpp-dev
2. 安装 librdkafka
$git clone https://github.com/edenhill/librdkafka.git
$cd librdkafka
$ git reset --hard 7101c2310341ab3f4675fc565f64f0967e135a6a
./configure
$ make
$ sudo make install
$ sudo mkdir -p /opt/nvidia/deepstream/deepstream-6.2/lib
$ sudo cp /usr/local/lib/librdkafka* /opt/nvidia/deepstream/deepstream-6.2/lib
3. 安装DeepStream
DeepStream的版本与Jetpack版本是有对应关系的,因此在官网找到与自己Jetpack对应的版本后才能下载安装,参考自Quickstart Guide — DeepStream 6.2 Release documentation
按照以上表格,我应该安装DeepStream-l4t:6.2版本。
下载地址:DeepStream SDK - Get Started | NVIDIA Developer
到Jetson的DeepStream的目录下,安装DeepStream命令如下:
$ sudo tar -xvf deepstream_sdk_v6.2.0_jetson.tbz2 -C /
$ cd /opt/nvidia/deepstream/deepstream-6.2
$ sudo ./install.sh
$ sudo ldconfig
通过以下命令进行测试,CSI摄像头正常打开就OK了。
cd /opt/nvidia/deepstream/deepstream-6.2/samples/configs/deepstream-app/
sudo deepstream-app -c source1_csi_dec_infer_resnet_int8.txt
关于source文件里的配置,以及摄像头参数,请参考:如何在deepstream-app里调用USB与CSI摄像头-电子发烧友网
在调用摄像头之前,建议先确认一下摄像头的位置与分辨率等信息,因为 DeepStream 会检查设定文件里的分辨率是否符合要求。使用 v4l2-utils 工具包来检查摄像头的信息,请按照以下步骤进行安装,并且检测摄像头分辨率:
sudo apt-get install v4l-utils
v4l2-ctl --list-devices
如上图所示,我插了两个摄像头,第一个IMX219就是上面提到的CSI摄像头,而另外一个是USB摄像头。
接下执行以下指令,查看个别摄像头可使用的分辨率为多少:
v4l2-ctl --list-formats-ext --device=0
v4l2-ctl --list-formats-ext --device=1
可以看到CSI摄像头的最大分辨率是3280×2464 ,能显示5种分辨率。而USB摄像头的最大分辨率为640×480。
在DeepStream路径(/opt/nvidia/deepstream/deepstream-6.2/samples/configs/deepstream-app/)下面有个 source2_csi_usb_dec_infer_resnet_int8.txt 文件,这是专门以 CSI 与 USB 摄像头为输入源的配置,里面可以看到以下关于摄像头设置的内容:
[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP 5=CSI
type=5
camera-width=1280
camera-height=720
camera-fps-n=30
camera-fps-d=1
camera-csi-sensor-id=0
[source1]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI
type=1
camera-width=1280
camera-height=720
camera-fps-n=30
camera-fps-d=1
camera-v4l2-dev-node=6
在[source1]的参数为USB摄像头的参数,显然有些参数不对,USB摄像头最大分辨率为640x480,因此camera-width与camera-height必须修改为摄像头所支持的分辨率,而USB摄像头编号为“dev/video1”,因此这里改为1。
将上面三地方修改完后,就可以直接执行以下指令去启动摄像头,将会同时显示两个摄像头:
deepstream-app -c source2_csi_usb_dec_infer_resnet_int8.txt
以上方式 是deepstream-app调用csi摄像头实现目标识别,但是并没有调用yolov5,为了实现deepstream和yolo的结合,需要部署一个开源的项目DeepStream-Yolo,通过他把deepstream和yolov5进行结合。
七、部署DeepStreamYolo
1. 在yolov5文件夹同级目录下克隆DeepStream-Yolo
git clone https://github.com/marcoslucianops/DeepStream-Yolo.git
cd DeepStream-Yolo/utils
#主要拷贝转换脚本到yolov5项目下即可
sudo cp gen_wts_yoloV5.py ../../yolov5
cd ../../yolov5
2. 从以下地址下载yolov5n.pt预训练文件,放到yolov5文件夹下。GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
3. 模型转换
进入到yolov5文件夹下,执行如下代码,会生成yolov5n.cfg
,yolov5n.wts
文件,将这两个文件拷贝到Deepstream-Yolo文件夹。
python gen_wts_yoloV5.py -w ./yolov5n.pt
sudo cp yolov5n.cfg ../DeepStream-Yolo/
sudo cp yolov5n.wts ../DeepStream-Yolo/
4. Deepstream部署yolov5
将DeepStream-Yolo项目放到如下目录/opt/nvidia/deepstream/deepstream-6.2/sources中(注意我的deepstream版本号是6.2,根据你的目录去复制)
sudo cp -r DeepStream-Yolo /opt/nvidia/deepstream/deepstream-6.2/sources
cd /opt/nvidia/deepstream/deepstream-6.2/sources/DeepStream-Yolo
5. 修改deepstream配置
修改DeepStream-Yolo目录下的deepstream_app_config.txt文件的以下变量
config-file=config_infer_primary_yoloV5.txt
[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP 5=CSI
type=5
camera-width=1280 #输入源的分辨率-宽
camera-height=720 #输入源的分辨率-高
camera-fps-n=30 #刷新率
camera-fps-d=1
camera-csi-sensor-id=0 #CSI摄像头默认为0号设备
修改config_infer_primary_yoloV5.txt 文件的一下变量
custom-network-config=yolov5n.cfg
model-file=yolov5n.wts
6. 编译DeepStream-Yolo
DeepStream 6.2 / 6.1.1 / 6.1 on Jetson platform
CUDA_VER=11.4 make -C nvdsinfer_custom_impl_Yolo
参考以下链接:
DeepStream-Yolo/YOLOv5.md at master · marcoslucianops/DeepStream-Yolo · GitHub
7. 运行DeepStream案例
deepstream-app -c deepstream_app_config.txt