JetsonNano指南

注意,本指南原本只针对4GB版本使用,后期因为使用2GB版本而新增加了一部分内容,有区别的均已经标注

具体资源请参照JetsonNano开发者套件(2GB版本:Jetson Nano 2GB Developer Kit)、Jetson Linux开发手册Jetson Zoo(各种开源框架及其安装说明)

一、入门

1.准备

2.开始

将microSD卡(已写入系统映像)插入Jetson Nano模块底部的插槽中。接上各种外设即可进入系统

目前安装的最新版JetPack SDK为4.4,具体包含内容可以参见官方链接

二、基本环境搭建

1.更换国内源

更换为清华源,注意这里采用的是ARM设备的源,对应的是ubuntu-ports镜像:

1
2
sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vim /etc/apt/sources.list

对应的配置文件为:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse

# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-proposed main restricted universe multiverse

阿里源:

1
2
3
4
5
6
7
8
9
10
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-security main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-updates main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-backports main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse

更新:

1
2
sudo apt-get update
sudo apt-get upgrade

2.安装CUDA

由于Jeston Nano中已经安装了CUDA,但是需要更改环境变量之后,才能够查询到版本信息,所以首先添加环境变量:

1
sudo vim ~/.bashrc

在最后添加:

1
2
3
export CUDA_HOME=/usr/local/cuda-10.2
export LD_LIBRARY_PATH=/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH
export PATH=/usr/local/cuda-10.2/bin:$PATH

保存后更新:

1
source ~/.bashrc

检查:

1
nvcc -V

3.配置python

注意:

  • 目前anaconda官方已经支持arm64位版本,但是实测目前能够安装上,但是不能正常的创建环境——2021/7/20
  • 推荐使用conda-forge/miniforge: A conda-forge distribution.,支持conda命令,能够正常的创建环境,但是只能使用conda-forge源,不推荐换源(换源之后尝试过创建环境失败)

由于Jetson Nano中已经预装了Python3.6版本,所以可以直接安装pip。

在终端中输入下述命令进行安装:

1
sudo apt-get install python3-pip python3-dev python3-venv
  • python3-venv是管理虚拟环境的包,由于conda没有arm版本的,所以推荐用venv管理虚拟环境

  • 可以此时同时安装autoenv自动激活插件,配合venv使用(注意换源):

    1
    pip3 install autoenv
    • autoenv需要在.bashrc最后添加以下脚本才能使用:

      1
      source `which activate.sh`
      • 如果找不到activate.sh,一般都在~/.local/bin/activate.sh

安装完成后此时的pip是9.01版本,需要对pip进行一下升级,否则后面在安装其它Python库的时候会出问题。这里顺带着将pip的源换了:

1
2
3
4
5
6
# 临时换源升级pip
python3 -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
# 换源
python3 -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 测试版本
python3 -m pip --version
  • 换源之后的pip源保存在/home/jetson/.config/pip/pip.conf

  • 阿里源:https://mirrors.aliyun.com/pypi/simple

    • 阿里源记得在配置文件~/.config/pip/pip.conf中加入以下选项:

      1
      2
      [install]
      trusted-host=mirrors.aliyun.com

      否则会在用pip下载时一直弹出警告

安装常用库(还是建议在虚拟环境中用pip安装):

1
2
3
sudo apt-get install python3-scipy
sudo apt-get install python3-pandas
sudo apt-get install python3-sklearn

4.安装Code OSS

不再推荐,VSC已经支持arm版本

原生的VS Code并不适用于Jetson Nano,当前,还没有针对Jetson Nano这样的ARM设备的VS Code正式版本。但是,由于它是开源的,所以任何人都可以编译一个版本。其中,Code-OSS就是这样一款嵌入式环境下的“VS Code”。Code-OSS基于VS Code,它并不仅仅是一个代码编辑器,它具有用于管理整个项目文件夹而不是单个脚本的内置资源管理器功能以及丰富的第三方插件。实际上Code-OSS几乎具备了VS Code的所有完整功能,因此用它作为代码编辑器来编辑代码,例如python,会使得整个开发过程更加便捷。

官方的VSC-OSS没有ARM版本的,但是该网址为第三方对ARM的适配版本,只需选择后缀带有arm64(aarch64)的,单击后进入详情页面后,找到对应的wget命令即可:

1
wget --content-disposition https://packagecloud.io/headmelted/codebuilds/packages/debian/stretch/code-oss_1.45.0-1586135971_arm64.deb/download.deb

下载后直接安装:

1
sudo dpkg -i code-oss_1.45.0-1586135971_arm64.deb

5.安装OPENCV

手动编译参考链接:Build OpenCV on Nvidia Jetson Nano(手动编译opencv脚本,详见后文)、Installing OpenCV 3.4.6 on Jetson Nano

如果在conda环境中,可以直接通过pip安装:

1
pip install opencv-contrib-python

四种opencv的区别:

  • opencv-python: 只包含opencv库的主要模块. 一般不推荐安装
  • opencv-contrib-python: 包含主要模块和contrib模块, 功能基本完整, 推荐安装
  • opencv-python-headless: 和opencv-python一样, 但是没有GUI功能, 无外设系统可用
  • opencv-contrib-python-headless: 和opencv-contrib-python一样但是没有GUI功能. 无外设系统可用

注意:如果需要安装QT,带GUI的版本会与QT冲突

默认自带opencv 4.1.1,可以通过如下命令测试:

1
sudo opencv_version

其中opencv的:

  • 头文件目录为:/usr/include/opencv4
  • 库文件目录为:/usr/lib/aarch64-linux-gnu
  • 常用链接库:-lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui -lopencv_objdetect -lopencv_videoio

5.1python环境

默认系统的python版本分别为python3.6和python2.7,所以在系统中使用这两个版本是不需要任何设置的,此时可以直接import cv2即可

但是如果当前环境不是上述两个版本,或者说是在虚拟环境中,则需要设置下opecv

注意:

  1. 使用pip安装的opencv默认是cpu版本的,不能全部发挥出jetson的性能。
  2. 不推荐直接使用系统环境的python,推荐自己创建虚拟环境。(系统带的python中有些库需要通过apt安装)

一般来说有如下两种方式:

  1. 链接系统默认的opencv到对应的python环境中(仅适用于虚拟环境和系统的python版本一致时,在虚拟环境中直接将系统环境中的opencv库链接过来)
  2. 重新编译opencv,并链接到python环境中(该方式详见第三章)

这里先采用上述第一种方式。一般来说,jetson中默认的opencv库放在如下两个路径:

  1. /usr/lib/python3.6/dist-packages/cv2/python-3.6/cv2.cpython-36m-aarch64-linux-gnu.so:系统默认python3.6版本的库文件
  2. /usr/lib/python2.7/dist-packages/cv2/python-2.7/cv2.so:系统默认python2.7的库文件

找到目前使用的python环境,将上述库文件链接到site-packages文件夹下即可(如果没有就自行创建)。一般来说有如下两种情况:

  1. 系统中的python路径:/usr/lib/python3.8/site-packages/
  2. 虚拟环境中的python路径:./env/lib/python3.8/site-packages/

之后创建opencv库的软连接到目标python环境中即可:

1
ln -s opencv库文件(xxx.so) cv2.so

5.2摄像头读取

CSI摄像头

读取CSI摄像头主要使用Gstreamer,可以通过如下命令测试摄像头:

1
2
3
nvgstcapture
# 或者
gst-launch-1.0 nvarguscamerasrc sensor-id=0 sensor-mode=3 ! 'video/x-raw(memory:NVMM),width=3820, height=2464, framerate=21/1, format=NV12' ! nvvidconv flip-method=0 ! 'video/x-raw,width=960, height=616' ! nvvidconv ! nvegltransform ! nveglglessink -e
1
gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=3820, height=2464, framerate=21/1, format=NV12' ! nvvidconv flip-method=0 ! 'video/x-raw,width=960, height=616' ! nvvidconv ! nvegltransform ! nveglglessink -e

opencv中的调用方法:

python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import cv2

# 设置gstreamer管道参数
def gstreamer_pipeline(
sensor_id=0,
sensor_mode=3,
capture_width=1280, #摄像头预捕获的图像宽度
capture_height=720, #摄像头预捕获的图像高度
display_width=1280, #窗口显示的图像宽度
display_height=720, #窗口显示的图像高度
framerate=60, #捕获帧率
flip_method=0, #是否旋转图像
):
return (
"nvarguscamerasrc sensor-id=%d sensor-mode=%d ! "
"video/x-raw(memory:NVMM), "
"width=(int)%d, height=(int)%d, "
"format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
"video/x-raw, format=(string)BGR ! appsink"
% (
sensor_id,
sensor_mode,
capture_width,
capture_height,
framerate,
flip_method,
display_width,
display_height,
)
)

if __name__ == "__main__":
# 创建管道
print(gstreamer_pipeline())

#管道与视频流绑定
cap = cv2.VideoCapture(gstreamer_pipeline(flip_method=0), cv2.CAP_GSTREAMER)

if cap.isOpened():
window_handle = cv2.namedWindow("CSI Camera", cv2.WINDOW_AUTOSIZE)

# 逐帧显示
while cv2.getWindowProperty("CSI Camera", 0) >= 0:
ret_val, img = cap.read()
cv2.imshow("CSI Camera", img)

keyCode = cv2.waitKey(30) & 0xFF
if keyCode == 27:# ESC键退出
break

cap.release()
cv2.destroyAllWindows()
else:
print("打开摄像头失败")

C++:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/videoio.hpp>

using namespace std;
using namespace cv;

string gstreamer_pipeline (int sensor_id, int sensor_mode, int capture_width, int capture_height, int display_width, int display_height, int framerate, int flip_method)
{
return "nvarguscamerasrc sensor-id=" + to_string(sensor_id) + " sensor-mode=" + to_string(sensor_mode) + " ! video/x-raw(memory:NVMM), width=(int)" + to_string(capture_width) + ", height=(int)" +
to_string(capture_height) + ", format=(string)NV12, framerate=(fraction)" + to_string(framerate) +
"/1 ! nvvidconv flip-method=" + to_string(flip_method) + " ! video/x-raw, width=(int)" + to_string(display_width) + ", height=(int)" +
to_string(display_height) + ", format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink";
}

int main( int argc, char** argv )
{
int capture_width = 1280 ;
int capture_height = 720 ;
int display_width = 1280 ;
int display_height = 720 ;
int framerate = 60 ;
int flip_method = 0 ;
int sensor_id = 0;
int sensor_mode = 3;

//创建管道
string pipeline = gstreamer_pipeline(sensor_id,
sensor_mode,
capture_width,
capture_height,
display_width,
display_height,
framerate,
flip_method);
std::cout << "使用gstreamer管道: \n\t" << pipeline << "\n";

//管道与视频流绑定
VideoCapture cap(pipeline, CAP_GSTREAMER);
if(!cap.isOpened())
{
std::cout<<"打开摄像头失败."<<std::endl;
return (-1);
}

//创建显示窗口
namedWindow("CSI Camera", WINDOW_AUTOSIZE);
Mat img;

//逐帧显示
while(true)
{
if (!cap.read(img))
{
std::cout<<"捕获失败"<<std::endl;
break;
}
imshow("CSI Camera",img);

int keycode = cv::waitKey(30) & 0xff ; //ESC键退出
if (keycode == 27) break ;
}

cap.release();
destroyAllWindows() ;
}

NVIDIA提供了一个基于python的cam库:JetCam,可以通过用过该库来调用摄像头(本质上还是调用Gstreamer):

  1. 下载源码,解压

    1
    unzip jetcam-master.zip
  2. 安装

    1
    2
    cd jetcam-master
    sudo python3 setup.py install
  3. 使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import cv2
    from jetcam.csi_camera import CSICamera
    camera = CSICamera(capture_device=0, width=224, height=224, capture_width=1080, capture_height=720, capture_fps=30)
    image = camera.read() # BGR8
    print(image.shape)
    print(camera.value.shape)
    while 1:
    image = camera.read()
    cv2.imshow("CSI Camera", image)
    kk = cv2.waitKey(1)
    if kk == ord('q'): # 按下 q 键,退出
    break
    cv2.destroyAllWindows()
USB摄像头

opencv中的调用方法:

1
2
cv2.VideoCapture(0)
cv2.VideoCapture(1)

JetCam库中的调用方法:

1
2
3
4
5
6
7
8
9
10
11
12
import cv2
from jetcam.usb_camera import USBCamera
camera = USBCamera(capture_device=1)
image = camera.read()
print(image.shape)
print(camera.value.shape)
while 1:
image = camera.read()
cv2.imshow("USB Camera", image)
kk = cv2.waitKey(1)
if kk == ord('q'): # 按下 q 键,退出
break

6.安装VNC服务

注意:该方案目前在JetPack SDK 4.4上失效,暂时未找到解决方法

  1. 解决bug

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <key name='enabled' type='b'>
    <summary>Enable remote access to the desktop</summary>
    <description>
    If true, allows remote access to the desktop via the RFB
    protocol. Users on remote machines may then connect to the
    desktop using a VNC viewer.
    </description>
    <default>false</default>
    </key>
  2. 安装必备软件

    1
    2
    sudo apt update
    sudo apt install vino
  3. 安装VNC server

    自带有VNC,只需设置使能即可:

    1
    sudo ln -s ../vino-server.server /usr/lib/systemd/user/graphical-session.target.wants

    配置VNC server

    1
    2
    3
    gsettings set org.gnome.Vino enabled true
    gsettings set org.gnome.Vino prompt-enabled false
    gsettings set org.gnome.Vino require-encryption false

    设置密码

    1
    2
    gsettings set org.gnome.Vino authentication-methods "['vnc']"
    gsettings set org.gnome.Vino vnc-password $(echo -n 'thepassword'|base64)

    重启机器

    1
    sudo reboot
  4. 连接VNC server:用VNC客户端连接即可

  5. 设置桌面分辨率:由显示器决定,默认640*480,可以通过编辑/etc/X11/xorg.conf文件,加入以下内容修改分辨率:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Section "Screen"
    Identifier "Default Screen"
    Monitor "Configured Monitor"
    Device "Tegra0"
    SubSection "Display"
    Depth 24
    Virtual 1280 800 # Modify the resolution by editing these values
    EndSubSection
    EndSection

注意:VNC server只有当用户登录后才能使用,如果希望VNC能够自动启动,可以使能自动登录功能

实验:水流检测代码环境搭建

注意,这里需要用到以下几个包:

  • opencv
  • numpy
  • matplotlib
  • skimage

其中skimage对python的最低版本支持为3.7,所以需要先安装python3.7以上版本,并基于此创建虚拟环境:

1
2
3
4
sudo apt install python3.8 python3.8-dev python3.8-venv
python3.8 -m venv waterspeed-env
# 在虚拟环境中直接下载安装:
pip install numpy skimage matplotlib
  • 下载安装过程会比较漫长,因为有些包没有arm64平台的,需要在本地编译

手动编译并安装opencv

编译

手动完整编译一次opencv 4.4.0在jetson nano 2GB上预计5~6小时

opencv比较特殊,推荐直接编译然后创建软连接的方式安装,当然也可以通过apt的方式直接安装(该方式安装的是cpu版本,且已经过时(系统环境默认带了opencv),仅供参考):[第一次用Jetson Nano 就上手]OpenCV基础应用

可以根据前文提到的GitHub上的开源脚本来一部编译、配置opencv:Build OpenCV on Nvidia Jetson Nano

1
git clone  https://github.com/mdegans/nano_build_opencv.git
  • 需要有梯子从外网拉取代码opencv源码

下载对应的仓库:

1
2
git clone --depth 1 --branch 4.4.0 https://github.com/opencv/opencv.git
git clone --depth 1 --branch 4.4.0 https://github.com/opencv/opencv_contrib.git
  • 注意:上述4.4.0是opencv的版本号,需要自己根据github仓库分支确定

配置opencv:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 到opencv/build(没有build就自己创建)下执行
cmake -D BUILD_EXAMPLES=OFF \
-D BUILD_opencv_python2=ON \
-D BUILD_opencv_python3=ON \
-D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/home/jetson/opencv \
-D CUDA_ARCH_BIN=5.3,6.2,7.2 \
-D CUDA_ARCH_PTX= \
-D CUDA_FAST_MATH=ON \
-D CUDNN_VERSION='8.0' \
-D EIGEN_INCLUDE_PATH=/usr/include/eigen3 \
-D ENABLE_NEON=ON \
-D OPENCV_DNN_CUDA=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D OPENCV_EXTRA_MODULES_PATH=/home/jetson/package/nano_build_opencv/build_opencv/opencv_contrib/modules \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D WITH_CUBLAS=ON \
-D WITH_CUDA=ON \
-D WITH_CUDNN=ON \
-D WITH_GSTREAMER=ON \
-D WITH_LIBV4L=ON \
-D WITH_OPENGL=ON \
..
  • 注意以下配置需要自定义:
    • CMAKE_INSTALL_PREFIX:指定的安装目录,不推荐到全局目录(需要sudo权限)
    • OPENCV_EXTRA_MODULES_PATH:外部模块目录,即opencv_contrib/modules

编译并安装到本地:

1
2
3
4
# 编译
make -j4
# 安装到指定目录
make install
  • 编译过程中如果遇到以下问题:

    • fatal error: boostdesc_bgm.i: No such file or directory:网络问题,编译时还需要下载一部分文件,此时无法下载完成,所以失败。
      1. 详见fatal error: boostdesc_bgm.i: No such file or directory · Issue #1301最后一部分,给出了缺少文件的下载链接,手动下载放到对应文件夹即可
      2. 不断重试,直至成功下载完成缺少的文件
  • 建议安装之后通过如下方式打包备份opencv:

    1
    2
    3
    4
    # 打包
    tar -jcvf opencv4.4.0.tar.bz2 ./opencv
    # 解压
    tar jxvf opencv4.4.0.tar.bz2
链接到python虚拟环境

经历过上述步骤后,opencv正确的安装到了指定的路径,此时需要将opencv的库链接到python中来:

1
2
3
4
5
6
7
8
9
10
# 找到刚刚编译的opencv的python库路径
cd opencv/lib/python3.8/site-packages/cv2/python-3.8
# 重命名库文件
mv cv2.cpython-36m-xxx-linux-gnu.so cv2.so
# 去虚拟环境中的site-packages文件夹
cd ./env/lib/python3.8/site-packages/
# 如果不是虚拟环境就直接去家目录的的全局python环境下
cd ~
# 链接库文件
ln -s ~/opencv/lib/python3.8/site-packages/cv2/python-3.8/cv2.so cv2.so

此时,opencv可以通过如下方式测试版本:

1
2
import cv2
cv2.__version__

pytorch安装

官方参考链接:PyTorch for Jetson - version 1.8.0 now available

对于Python 2.7与Python 3.6来说,在上面的链接中找到合适的版本直接下载安装即可,对于其他版本的python需要自己手动从源码编译

编译

注意:

  • 该过程在jetson nano 4GB版本上需要12小时左右(不包括torchvision)
  • 自带的4G ram+2G swap小了,编译时会报工具链错误,这里直接将虚拟内存加到了10G
  • 最好单独创建一个虚拟环境进行编译
  1. 打开交换分区(如果有则 不需要):Create a Linux swap file

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 创建交换分区文件(dd或fallocate二选一即可)
    # sudo dd if=/dev/zero of=/swapfile bs=64M count=16#count的大小就是增加的swap空间的大小,64M是块大小,所以空间大小是bs*count=1024MB
    sudo fallocate -l 8G /mnt/8GB.swap
    # 格式化成swap格式
    sudo mkswap /mnt/8GB.swap
    # 使用刚才创建的swap空间
    sudo swapon /mnt/8GB.swap

    # 验证swap是否打开
    free -h

    # 编译完成后关闭并删除swap
    sudo swapoff /mnt/8GB.swap
    sudo rm /mnt/8GB.swap
  2. 打开最高性能模式:

    1
    2
    sudo nvpmodel -m 0     # on Xavier NX, use -m 2  instead (15W 6-core mode)
    sudo jetson_clocks
  3. 下载源码

    1
    2
    3
    4
    # git clone --recursive --branch v1.8.0 http://github.com/pytorch/pytorch # 拉取1.8.0版本
    # git submodule update --init --recursive # 若上述拉取子模块的过程中失败。可以用该命令继续拉取
    git clone --recursive --branch <version> http://github.com/pytorch/pytorch
    cd pytorch
    • 若拉取子模块没有问题,但是最后子模块文件夹下没有文件,可以通过删除文件夹继续执行拉取子模块命令解决
  4. 打补丁(防止在jetson上报错)

    1
    2
    cd pytorch
    patch -p1 < pytorch-1.8-jetpack-4.4.1.patch
    • 如果有.rej文件则表示打补丁失败,一般是代码冲突。需要打开.rej以及相应的.orig文件对比一下找到冲突在哪,解决掉冲突即可
  5. 配置构建选项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    export USE_NCCL=0
    #如果要启用OpenMPI后端,请跳过此设置
    export USE_DISTRIBUTED=0
    export USE_QNNPACK=0
    export USE_PYTORCH_QNNPACK=0
    export TORCH_CUDA_ARCH_LIST="5.3;6.2;7.2"
    #没有前面的'v',如1.3.0表示PyTorch v1.3.0
    export PYTORCH_BUILD_VERSION=<version>
    export PYTORCH_BUILD_NUMBER=1
    export MAX_JOBS=4
    • 注意,#符号不能加入
  6. 编译生成.whl文件

    1. 对于python2:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      sudo apt-get install python-pip cmake libopenblas-dev
      pip install -U pip

      sudo pip install -U setuptools
      sudo pip install -r requirements.txt

      pip install scikit-build --user
      pip install ninja --user

      python setup.py bdist_wheel
    2. 对于python3:

      1
      2
      3
      4
      5
      6
      7
      8
      sudo apt-get install python3-pip cmake libopenblas-dev

      # pip3 install -r requirements.txt
      pip install astunparse future numpy psutil pyyaml requests setuptools six typing_extensions dataclasses
      pip3 install scikit-build
      pip3 install ninja

      python3 setup.py bdist_wheel
  7. 最后生成的路径为:./dist/torch-1.9.0-cp39-cp39-linux_aarch64.whl,通过pip install torch-1.9.0-cp39-cp39-linux_aarch64.whl即可安装

验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# pytorch
import torch
print(torch.__version__)
print('CUDA available: ' + str(torch.cuda.is_available()))
print('cuDNN version: ' + str(torch.backends.cudnn.version()))
a = torch.cuda.FloatTensor(2).zero_()
print('Tensor a = ' + str(a))
b = torch.randn(2).cuda()
print('Tensor b = ' + str(b))
c = a + b
print('Tensor c = ' + str(c))
# torchvision
import torchvision
print(torchvision.__version__)
torchvision安装

注意torchvision与pytorch的对应关系:pytorch/vision: Datasets, Transforms and Models specific to Computer Vision,具体如下:

  • PyTorch v1.0 - torchvision v0.2.2
  • PyTorch v1.1 - torchvision v0.3.0
  • PyTorch v1.2 - torchvision v0.4.0
  • PyTorch v1.3 - torchvision v0.4.2
  • PyTorch v1.4 - torchvision v0.5.0
  • PyTorch v1.5 - torchvision v0.6.0
  • PyTorch v1.6 - torchvision v0.7.0
  • PyTorch v1.7 - torchvision v0.8.1
  • PyTorch v1.8 - torchvision v0.9.0
  • PyTorch v1.9 - torchvision v0.10.0

pip直接安装:

1
pip install torchvision

手动编译:

1
2
3
4
5
6
7
8
9
10
11
# 安装必备包
sudo apt-get install libjpeg-dev zlib1g-dev libpython3-dev libavcodec-dev libavformat-dev libswscale-dev
# clone对应项目源码 注意版本要对应(需要加v,如v0.10.0)
git clone --branch <version> https://github.com/pytorch/vision torchvision
cd torchvision
export BUILD_VERSION=0.x.0 # 0.x.0是torchvision的版本号
export MAX_JOBS=4
python3 setup.py install --user
cd ../ # 尝试从构建目录加载 torchvision 将导致导入错误
# 下面这句在python2.7以及torchvision 0.5.0 以下需要
pip install 'pillow<7'

安装FCOS环境

项目地址:tianzhi0549/FCOS: FCOS: Fully Convolutional One-Stage Object Detection (ICCV’19)

配置:

1
2
3
4
5
6
7
8
9
10
# 创建新的虚拟环境(python需要>=3.7)
python3.8 -m venv fcos-venv
# 编写自动激活脚本(需要安装autoenv插件)
echo "source fcos-venv/bin/activate" > .env
# 激活虚拟环境
source fcos-venv/bin/activate
# 升级虚拟环境自带的pip
pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple
# clone项目
git clone https://github.com/tianzhi0549/FCOS.git

安装依赖:

1
pip install ninja yacs cython matplotlib tqdm scikit-image

继续安装上一节编译好后的opencv:[链接到python虚拟环境](# 链接到python虚拟环境)

三、深度学习

参考链接:

  1. Tutorials | NVIDIA Developer:官方总链接
  2. Two Days to a Demo | NVIDIA Developer:动手实验
  3. jetson-inference: Hello AI World guide to deploying deep-learning inference networks and deep vision primitives with TensorRT and NVIDIA Jetson:通过docker来快速部署
  4. PyTorch for Jetson - version 1.8.0 now available:pytorch安装

1.jetson-inference项目

jetson-inference 是官方出品,用于快速上手的项目。通过使用NVIDIA TensorRT将神经网络有效地部署到Jetson上,并利用图形优化,内核融合和使用FP16/INT8精度的方式提高了性能

1.1环境搭建

前提是需要在JetPack上。一般来说通过SD卡安装的系统都已经满足该要求

该项目有两种方式进行搭建:

  1. docker
  2. 直接编译源码再安装到系统中
docker方式

该方式需要下载位于 DockerHub 的容器(900M左右),国内可能比较慢,且需要JetPack的版本和容器的版本匹配。以下方法可以获得当前JetPack的版本:

1
2
head -n 1 /etc/nv_tegra_release
# R32 (release), REVISION: 4.4, GCID: 23942405, BOARD: t210ref, EABI: aarch64, DATE: Fri Oct 16 19:44:43 UTC 2020
  • 上方第二行为返回值,其版本为R32.4.4

通过以下方式安装并运行:

1
2
3
git clone --recursive https://github.com/dusty-nv/jetson-inference
cd jetson-inference
docker/run.sh

上述run.sh脚本会执行以下几件事:

  1. 自动检测JetPack版本并自动拉取docker image

  2. 自动挂载设备,以便在容器中使用:

    • jetson-inference/data (存储网络模型,序列化的TensorRT引擎和测试镜像)

      • jetson-inference/data/images/test:建议将容器内部生成的图像保存在此处,对应容器中的路径为:images/test
    • jetson-inference/python/training/classification/data (存储分类训练数据集)

    • jetson-inference/python/training/classification/models (存储PyTorch训练的分类模型)

    • jetson-inference/python/training/detection/ssd/data (存储检测训练数据集)

    • jetson-inference/python/training/detection/ssd/models (存储PyTorch培训的检测模型)

    • 摄像头节点

    • 如果想将其他文件挂载进容器,可以通过传入如下参数:

      1
      docker/run.sh --volume /my/host/path:/my/container/path
  3. 根据选择自动下载模型权重文件

源码方式

执行以下命令即可在本机编译这个项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sudo apt-get update
sudo apt-get install git cmake libpython3-dev python3-numpy
git clone --recursive https://github.com/dusty-nv/jetson-inference
cd jetson-inference
# 配置
mkdir build
cd build
cmake ../
# cmake -D BUILD_DEPS=NO ../ # 配置时不检查依赖(不运行CMakePreBuild.sh下载模型)
# 下载模型(可选)
cd ../tools
./download-models.sh
# 安装PyTorch(可选,迁移学习用)
cd ../build
./install-pytorch.sh
# 编译工程
cd jetson-inference/build
make -j$(nproc)
sudo make install
sudo ldconfig

构建完毕后的镜像会在jetson-inference/build/aarch64中,执行make install会将其安装到系统中( /usr/local/处),其结构如下:

1
2
3
4
5
6
7
|-build
\aarch64
\bin 生成示例二进制文件的位置
\networks 网络模型的存储位置
\images 测试图像的存储位置
\include 头文件位置
\lib 构建的lib库位置

1.2推理

1.2.1分类(ImageNet)
1.2.2检测(DetectNet)

是用自带例子进行检测,能够在图像、视频、摄像头中检测,具体的输入输出流支持与切换可以参考官方文档: Camera Streaming and Multimedia。自带以下俩个例子:

  • detectnet.cpp (C++)
  • detectnet.py(Python)

命令行参数如下:

  • --network:修改模型文件,默认的检测模型为SSD-Mobilenet-v2
  • --overlay:以逗号为分隔符的一个组合,包括box, labels, conf, 和none,默认为--overlay=box,labels,conf,即显示边框、标签和置信度
  • --alpha:设置覆盖时使用的 alpha 混合值(默认值为 120)
  • --threshold: 设置检测的最小阈值(默认值为 0.5)
1.2.3语义分割(SegNet)

1.3训练