如何在 Jetson Nano 上安裝 OpenCV?

在 Jetson Nano 裝 opencv-python 版可不是簡單 pip 一下就好,因為 pip 安裝不會支援 CUDA,同時,也沒有支援 GStreamer!這樣 OpenCV 是無法擷取到 Camera 的影像的!

為何要自己 build OpenCV?

可能有人會疑惑,為何在 Raspberry pi 等 SBC 或者 mac 上使用 openCV 都沒有這個問題?主要是因為在 Jetson Nano 擷取 camera 資料並不是透過 V4L2 API,而是使用 GStreamer 中的 nvarguscamerasrc plugin。總之可以想成 nvidia 自己的 SoC 要走另一套 API 才能擷取影像。所以如果使用以往 V4L2 的方式來寫:

cap = cv2.VideoCapture(0)

會發現擷取出來的影像永遠是綠油油的一片…

如何在 Jetson Nano 上安裝 OpenCV?

必須使用以下方式宣告:

cap = cv2.VideoCapture('nvarguscamerasrc ! video/x-raw(memory:NVMM), width=3280, height=2464, format=(string)NV12, framerate=(fraction)20/1 ! nvvidconv ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink' , cv2.CAP_GSTREAMER)

第一次看到真的很驚人!要這麼長一串字串!參數設定也要寫在裡面。不過好在有神人高手提供 function 可以 gen 出這一串,我們最後再來看。

因此,為了能夠使用 CUDA 以及 GStreamer,真的必須自己下海來 build,而這過程也是繁複又容易失敗,在這裡分享我 build 的過程。

開始 Build OpenCV

Step 1:調整 swap

build 的過程可能會佔用很多記憶體,原本系統給定的 zram 只有 2G,我則是另外再給 4G 的 swap。這邊建議用 jtop 來調整,用完還可以動態關閉釋放硬碟空間,很方便!

如何在 Jetson Nano 上安裝 OpenCV?

Step 2:準備環境

要裝的依賴非常多,可以去喝杯咖啡讓他慢慢安裝。可能每個人缺少的套件略有差異,若後續發生缺少什麼 lib,再 google 一下安裝即可

# reveal the CUDA location
sudo sh -c "echo '/usr/local/cuda/lib64' >> /etc/ld.so.conf.d/nvidia-tegra.conf"
sudo ldconfig

# third-party libraries
sudo apt-get install build-essential cmake git unzip pkg-config
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install libgtk2.0-dev libcanberra-gtk*
sudo apt-get install python3-dev python3-numpy python3-pip
sudo apt-get install libxvidcore-dev libx264-dev libgtk-3-dev
sudo apt-get install libtbb2 libtbb-dev libdc1394-22-dev
sudo apt-get install gstreamer1.0-tools libv4l-dev v4l-utils
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install libavresample-dev libvorbis-dev libxine2-dev
sudo apt-get install libfaac-dev libmp3lame-dev libtheora-dev
sudo apt-get install libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get install libopenblas-dev libatlas-base-dev libblas-dev
sudo apt-get install liblapack-dev libeigen3-dev gfortran
sudo apt-get install libhdf5-dev protobuf-compiler
sudo apt-get install libprotobuf-dev libgoogle-glog-dev libgflags-dev

Step 3:準備 OpenCV source code

這邊以 OpenCV 4.5.2 為例

# download the latest version
cd ~
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.5.2.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.5.2.zip

# unpack
unzip opencv.zip
unzip opencv_contrib.zip

# some administration to make live easier later on
mv opencv-4.5.2 opencv
mv opencv_contrib-4.5.2 opencv_contrib

# clean up the zip files
rm opencv.zip
rm opencv_contrib.zip

Step 4:準備 Build 的參數

首先建立 build folder

cd ~/opencv
mkdir build
cd build

由於系統環境預設使用 python2,我實際 build 的時候發現 cmake 會抓不到 python3 的路徑,所以只 build 出 python2 的 OpenCV。因此我們在 build 之前先做一個手腳,把 python 這道指令重新指向 python3 的 bin,讓預設變成 python3,這樣就能抓到。

# 先查詢目前 python 的位置
$ which python
/usr/bin/python
$ which python3
/usr/bin/python3

# 把 python 重新指向 python3
$ sudo ln -s /usr/bin/python /usr/bin/python3

緊接著用 cmake 產生 build 所需要的檔案。這邊的參數很重要,如果錯了可能就 build 不出來。目前的配置是依照我當時遇到的問題調整過,如果屆時大家自己 build 時有別的錯誤訊息就需要自行調整。

這邊注意 OPENCV_EXTRA_MODULES_PATH 路徑要給對,要指向剛剛下載解壓的 opencv_contrib 資料夾路徑。如果位置不同務必要自行調整。

cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
-D EIGEN_INCLUDE_PATH=/usr/include/eigen3 \
-D WITH_OPENCL=OFF \
-D WITH_CUDA=ON \
-D CUDA_ARCH_BIN=5.3 \
-D CUDA_ARCH_PTX="" \
-D WITH_CUDNN=ON \
-D WITH_CUBLAS=ON \
-D ENABLE_FAST_MATH=ON \
-D CUDA_FAST_MATH=ON \
-D OPENCV_DNN_CUDA=ON \
-D ENABLE_NEON=ON \
-D WITH_QT=OFF \
-D WITH_OPENMP=ON \
-D WITH_OPENGL=ON \
-D BUILD_TIFF=ON \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=ON \
-D WITH_TBB=ON \
-D BUILD_TBB=ON \
-D BUILD_TESTS=OFF \
-D WITH_EIGEN=ON \
-D WITH_V4L=ON \
-D WITH_LIBV4L=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D BUILD_opencv_python3=TRUE \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D BUILD_EXAMPLES=OFF ..

跑完時,務必看 cmake 跑出來的 log 檢查有沒有抓到 python3

如何在 Jetson Nano 上安裝 OpenCV?

Step 5:開始 Build!

這過程大概要快兩個小時,按下 enter 就讓他自己跑吧!

make -j4

Step 6:安裝 OpenCV

build 時間如果去吃頓飯,吃飽應該也就好了,回頭繼續安裝

sudo rm -r /usr/include/opencv4/opencv2
sudo make install
sudo ldconfig

立刻測試一下有沒有安裝成功

>>> import cv2
>>> cv2.__version__
'4.5.0'

檢查有沒有 support CUDA & GStreamer

>>> print(cv2.getBuildInformation())

如果出現以下訊息就代表成功!

General configuration for OpenCV 4.5.0 =====================================
 Version control:               unknown

 Extra modules:
   Location (extra):            /home/jetson/opencv_contrib/modules
   Version control (extra):     unknown

 Platform:
   Timestamp:                   2020-10-14T10:57:53Z
   Host:                        Linux 4.9.140-tegra aarch64

**********

OpenCV modules:
   To be built:                 alphamat aruco bgsegm bioinspired calib3d ccalib core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev datasets dnn dnn_objdetect dnn_superres dpm face features2d flann freetype fuzzy gapi hdf hfs highgui img_hash imgcodecs imgproc intensity_transform line_descriptor ml objdetect optflow phase_unwrapping photo plot python2 python3 quality rapid reg rgbd saliency sfm shape stereo stitching structured_light superres surface_matching text tracking ts video videoio videostab xfeatures2d ximgproc xobjdetect xphoto

**********

Video I/O:
   DC1394:                      YES (2.2.5)
   FFMPEG:                      YES
     avcodec:                   YES (57.107.100)
     avformat:                  YES (57.83.100)
     avutil:                    YES (55.78.100)
     swscale:                   YES (4.8.100)
     avresample:                YES (3.7.0)
   GStreamer:                   YES (1.14.5)
   v4l/v4l2:                    YES (linux/videodev2.h)

**********

 NVIDIA CUDA:                   YES (ver 10.2, CUFFT CUBLAS FAST_MATH)
   NVIDIA GPU arch:             53
   NVIDIA PTX archs:

 cuDNN:                         YES (ver 8.0.0)

Install to:                    /usr

也可以用 jtop 的 info tab 來確認

如何在 Jetson Nano 上安裝 OpenCV?

終於可以收工了,記得清理掉不必要的 source code folder 吧!

額外附加: GStreamer 字串產生

那一段真是又臭又長,使用這個別人整理好的 function 直接帶入自己想要的參數即可產生!方便很多!

def gstreamer_pipeline(
    capture_width=1280,
    capture_height=720,
    display_width=1280,
    display_height=720,
    framerate=60,
    flip_method=0,
):
    return (
        "nvarguscamerasrc ! "
        "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"
        % (
            capture_width,
            capture_height,
            framerate,
            flip_method,
            display_width,
            display_height,
        )
    )

延伸閱讀:如何在 Jetson Nano 上安裝 TensorFlow 以及 PyTorch?

參考資料

Install OpenCV 4.5 on Jetson Nano
How to Compile OpenCV 4.5.2 with CUDA 11.2 and cuDNN 8.1 on Ubuntu 20.04
Taking Your First Picture with CSI or USB Camera

Written by J
雖然大學唸的是生物,但持著興趣與熱情自學,畢業後轉戰硬體工程師,與宅宅工程師們一起過著沒日沒夜的生活,做著台灣最薄的 intel 筆電,要與 macbook air 比拼。 離開後,憑著一股傻勁與朋友創業,再度轉戰軟體工程師,一手扛起前後端、雙平台 app 開發,過程中雖跌跌撞撞,卻也累計不少經驗。 可惜不是那 1% 的成功人士,於是加入其他成功人士的新創公司,專職開發後端。沒想到卻在採前人坑的過程中,拓寬了眼界,得到了深層的領悟。