こちらの記事ではPyTorch版YOLOv5をJetson Nanoで動作させました。またこちらの記事ではOpenCV版YOLOv5をJetson Nanoで動作させました。
今回は、ncnn版のYOLOv5とYOLOv7をJetson Nanoで動作させる方法を解説します。ncnnはモバイルデバイスに特化したニューラルネットワークの推論のフレームワークで依存ライブラリが無いことが特徴です。今回OpenCVを使用して画面を表示しますが、OpenCVは画像の読み込みや画像の表示を担当するだけで推論の処理に関わりません。フレームワークも非常に小さく、ビルドも数分で終わります。PyTorchのビルドのように13時間もかかりません。
Installing ncnn on Jetson Nano
Jetson Nanoへのncnnのインストール方法はこちらにありますがこの記事では簡単に紹介します。
sudo apt-get update
sudo apt-get install -y cmake wget
sudo apt-get install -y libprotobuf-dev protobuf-compiler libvulkan-dev
git clone --depth=1 https://github.com/Tencent/ncnn.git
cd ncnn
git submodule update --depth=1 --init
mkdir build
cd build
cmake -D CMAKE_TOOLCHAIN_FILE=../toolchains/jetson.toolchain.cmake \
-D NCNN_DISABLE_RTTI=OFF \
-D NCNN_BUILD_TOOLS=ON \
-D NCNN_VULKAN=ON \
-D CMAKE_BUILD_TYPE=Release ..
make -j4
make install
sudo mkdir /usr/local/lib/ncnn
sudo cp -r install/include/ncnn /usr/local/include/ncnn
sudo cp -r install/lib/*.a /usr/local/lib/ncnn/
Code language: Bash (bash)
OpenCVをソースからインストールした場合など上記cmake
のところで、以下のエラーが出ることがあります。
CMake Error at /usr/share/cmake-3.10/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
Could NOT find CUDA (missing: CUDA_TOOLKIT_ROOT_DIR CUDA_NVCC_EXECUTABLE
CUDA_INCLUDE_DIRS CUDA_CUDART_LIBRARY) (Required is exact version "10.2")
Code language: Bash (bash)
このエラーが発生したら以下を実施しcmake
から処理を再開してください。
sudo rm /usr/local/lib/cmake/opencv4
Code language: Bash (bash)
Building and running YOLOv5 on Jetson Nano
Code::Blocksをダウンロードします。Code::BlocksはIDEで、ncnn版YOLOv5を提供するhttps://github.com/Qengineering/YoloV5-ncnn-Jetson-NanoレポジトリではCode::Blocksを採用しています。
sudo apt-get install -y codeblocks
Code language: Bash (bash)
YOLOv5をビルドします。オリジナルのncnn版YOLOv5レポジトリは静止画像を物体検出しますが、カメラ画像を物体検出したいためフォークした以下のレポジトリを使用します。
git clone https://github.com/otamajakusi/YoloV5-ncnn-Jetson-Nano
codeblock
Code language: Bash (bash)
以下の画面が表示されたら、GNU GCC Compiler
を選択肢OK
を選択します。

以下の画面の1でYoloV5-ncnn-Jetson-Nano/YoloV5.cbp
を選択します。以下2, 3, 4
を実施します。

映像が表示されるはずです。5.1 FPS程度出るようです。

Building and running YOLOv7 on Jetson Nano
YOLOv7も同様に以下のレポジトリをチェックアウトします。
git clone https://github.com/otamajakusi/YoloV7-ncnn-Jetson-Nano/
codeblock
Code language: Bash (bash)
上記Code::Blocksの画面の1でYoloV7-ncnn-Jetson-Nano/YoloV7.cbp
を選択します。以下2, 3, 4
を実施します。
映像が表示されるはずです。7.1 FPS程度出るようです。

FPS is lower than expected
映像の速度が出ない場合、カメラデバイスに応じてコードを修正する必要があります。YoloV5-ncnn-Jetson-Nano/yolov5.cpp
とYoloV7-ncnn-Jetson-Nano/yolov7main.cpp
に以下のコードがあります。
#if 0 /* depends on your device */
cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('Y','U','Y','V'));
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
cap.set(cv::CAP_PROP_FPS, 25);
#endif
Code language: Bash (bash)
この部分を修正する必要がありますが、修正方法を説明します。まず、v4l-utils
をインストールします。
sudo apt install v4l-utils -y
Code language: Bash (bash)
v4l2-ctl
でデバイスをリストします。
$ v4l2-ctl --list-devices
1080P Webcam (usb-70090000.xusb-2.1):
/dev/video0
Code language: JavaScript (javascript)
対象のデバイスのフォーマットリスト情報を取得します。下の例は/dev/video0のフォーマットリスト情報を取得しています。
$ v4l2-ctl -d /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
Size: Discrete 1280x720
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 640x480
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 1024x768
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 1280x1024
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.040s (25.000 fps)
Index : 1
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Size: Discrete 1280x720
Interval: Discrete 0.167s (6.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 640x480
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 1024x768
Interval: Discrete 0.167s (6.000 fps)
Size: Discrete 1280x1024
Interval: Discrete 0.167s (6.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.167s (6.000 fps)
Code language: Bash (bash)
OpenCVでカメラデバイスを初期化するときに例えば上記Pixel Format: 'YUYV'
、Size: Discrete 1280x720
が選択されてしまうと、 6.000 fps
しか出ないことが分かります。OpenCVがどのフォーマットとサイズを選択するのかよく分かってないですが、これが原因でfpsが期待通り出ないことがあります。上記のカメラでは25fpsを出したい場合は以下のように修正します。
cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('Y','U','Y','V'));
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
cap.set(cv::CAP_PROP_FPS, 25);
Code language: Bash (bash)
カメラデバイスのフレームレートを確認する方法は以下のとおりです。
$ v4l2-ctl -d /dev/video0 -P
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 25.000 (25/1)
Read buffers : 0
Code language: Bash (bash)
以上です。