11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AMBL株式会社Advent Calendar 2022

Day 19

Jetson Nanoでyolov7-tinyを動かしてみた

Last updated at Posted at 2022-12-17

はじめに

AMBL株式会社 AI開発事業部の見原です。
この記事は、AMBL株式会社 Advent Calendar 2022の19日目の記事になります。
業務では画像系のエッジAIアプリの開発を行っています。
この記事では、Jetsonにyolov7-tinyを組込んでDeepStream上でリアルタイムに物体検出を行う方法を紹介します。参考になれば幸いです。

目的

yolov7をJetsonのDeepStream上で動かせるようにする。サンプルアプリdeepstream-appを使ってyolov7で推論を行う。

環境

  • Jetson Nano 4GB
  • Jetpack 4.5
  • DeepStream SDK 5.1

Jetsonとは?

  • NVIDIAが開発した小型コンピュータ
  • NVIDIAのGPUが搭載されている
PXL_20221211_050420330

DeepStreamとは?

  • GStreamerをベースにしたストリーム分析ツールキット
  • AIを使ったビデオ解析、音声分析、画像分析のためのパイプラインを構築できる
  • C/C++またはPythonで開発できる(Graph ComposerというUIを使った開発もできるらしい)
スクリーンショット 2022-12-11 15 03 53

組込み

組込み手順

  1. モデルのTensorRT化: モデルをDeepStreamで使える形式に変換する。デバイスに合わせてモデルを高速化する。
  2. コンフィグファイルの作成: 前処理の設定などを行う。
  3. パーサー作成: 後処理(NMS処理など)を行うファイルを作成する。
  4. サンプルアプリ実行

1. モデルのTensorRT化

.pt -> .wts -> .engineの順に変換する。  
.wtsファイルまではgoogle colabで変換し、.engineファイルへの変換はJetsonで行う。   
以下のgithubを参考に行う。
https://github.com/wang-xinyu/tensorrtx/tree/master/yolov7

.ptファイルの変換

まず必要なリポジトリをクローンする。

!git clone https://github.com/WongKinYiu/yolov7
!git clone https://github.com/wang-xinyu/tensorrtx.git -b yolov5-v6.2

以下のリンクから事前学習済みモデルyolov7-tiny.ptをダウンロードし、yolov7フォルダに保存する。
https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt

gen_wts.pyファイルをyolov7下にコピーする。

!cp tensorrtx/yolov7/gen_wts.py yolov7

以下のように変換前の.ptファイルと変換後の.wtsファイルを指定して実行する。

%cd yolov7
!python3 gen_wts.py -w yolov7-tiny.pt -o yolov7-tiny.wts

yolov7下にyolov7-tiny.wtsが生成する。

.wtsファイルの変換

Jetsonで行う。
以下のリポジトリをダウンロードし、yolov7フォルダをホームディレクトリにコピーする。
https://github.com/mihara-shoko/yolov7_tensorrt
buildフォルダを作成し、yolov7-tiny.wtsファイルをbuildフォルダにコピーする。
yololayer.hの"static constexpr int INPUT_H"と"static constexpr int INPUT_W"を416に変更する。

yololayer.h
    static constexpr int CHECK_COUNT = 3;
    static constexpr float IGNORE_THRESH = 0.5f;
    struct YoloKernel
    {
        int width;
        int height;
        float anchors[CHECK_COUNT * 2];
    };
    static constexpr int MAX_OUTPUT_BBOX_COUNT = 1000;
    static constexpr int CLASS_NUM = 80;
    static constexpr int INPUT_H = 416;  // <-変更
    static constexpr int INPUT_W = 416;  // <-変更

buildフォルダに移動し、以下を実行する。

cmake ..
make
sudo ./yolov7 -s yolov7-tiny.wts yolov7-tiny.engine t

buildフォルダにyolov7-tiny.engineが生成する。これがTensorRT化されたモデル。

2. コンフィグファイルの作成

前処理、モデルファイル、信頼度の閾値、クラス数の設定などを行う。
以下のリポジトリをダウンロードし、parserフォルダをJetsonの/opt/nvidia/deepstream/deepstream-5.1/sources/ディレクトリにコピーする。
https://github.com/mihara-shoko/yolo_parser  
「1. モデルのTensorRT化」で作成したyolov7-tiny.engineファイルを/opt/nvidia/deepstream/deepstream-5.1/sources/parser下にコピーする。
/opt/nvidia/deepstream/deepstream-5.1/sources/parser下にあるconfig_infer_primary.txtを必要に応じて修正する。

config_infer_primary.txt
[property]
gpu-id=0
net-scale-factor=0.0039215697906911373
model-color-format=0
model-engine-file=yolov7-tiny.engine # TensorRT化したモデルのパス
labelfile-path=labels.txt # ラベルが書かれたテキストファイルのパス
num-detected-classes=80 # クラス数
interval=0
gie-unique-id=1
process-mode=1
network-type=0
cluster-mode=4
maintain-aspect-ratio=1
parse-bbox-func-name=NvDsInferParseCustomYoloV5
custom-lib-path=nvdsinfer_custom_impl_Yolo/libnvdsinfer_custom_impl_Yolo.so

[class-attrs-all]
pre-cluster-threshold=0.25 # 信頼度の閾値

前処理に関係する項目

項目 説明 yolov7の場合の設定値
net-scale-factor ピクセル値にかける値
モデルにはyのピクセル値が入力される。
y = net scale factor*(x-offset)
0.0039215697906911373
0-255を0-1のrangeにしている
offset ピクセル値から引く値
RGBそれぞれ別に設定できる。
モデルにはyのピクセル値が入力される。
y = net scale factor*(x-offset)
0:0:0
設定しなくて良い
model-color-format 0:RGB
1:BGR
2:GRAY
0
maintain-aspect-ratio リサイズするときにアスペクト比を維持するかどうか 1

詳しくはNVIDIAのページを参照
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_plugin_gst-nvinfer.html

3. パーサー作成

後処理(NMS処理など)を行うファイルを作成する。

Jetsonの/opt/nvidia/deepstream/deepstream-5.1/sources/parserに移動する。
nvdsinfer_custom_impl_Yolo/yololayer.hのクラス数(19行目)、input size(20, 21行目)を適宜変更する(TensorRT化したときと同じ値にする)。

nvdsinfer_custom_impl_Yolo/yololayer.h
#ifndef _YOLO_LAYER_H
#define _YOLO_LAYER_H

#include <vector>
#include <string>
#include "NvInfer.h"

namespace Yolo
{
    static constexpr int CHECK_COUNT = 3;
    static constexpr float IGNORE_THRESH = 0.1f;
    struct YoloKernel
    {
        int width;
        int height;
        float anchors[CHECK_COUNT * 2];
    };
    static constexpr int MAX_OUTPUT_BBOX_COUNT = 1000;
    static constexpr int CLASS_NUM = 1;
    static constexpr int INPUT_H = 416;  // yolov5's input height and width must be divisible by 32.
    static constexpr int INPUT_W = 416;

以下のコマンドでコンパイルする。

CUDA_VER=10.2 make -C nvdsinfer_custom_imple_Yolo

nvdsinfer_custom_impl_Yolo下に生成した.soファイルがパーサーとなる。

4. アプリ実行

Jetsonの/opt/nvidia/deepstream/deepstream-5.1/sources/parserに移動する。  
deepstream_app_config.txtのuriに読み込ませたい動画のパスを設定する。

deepstream_app_config.txt
[source0]
enable=1
type=3
uri=file://../../samples/streams/sample_1080p_h264.mp4
num-sources=1
gpu-id=0
cudadec-memtype=0

以下のコマンドを実行し、アプリを実行する。

deepstream-app -c deepstream_app_config.txt

アプリ実行結果

35 FPSでリアルタイムに推論をかけることができた!

yolov7-tiny.gif

おわりに

この記事では、Jetsonにyolov7-tinyを組込んでリアルタイムに物体検出を行う方法を紹介しました。無事にDeepstreamのパイプライン上で動かすことができました。yolov5sよりもアプリ実行速度が速い(同じ条件で実行するとyolov5sの場合は30 FPS未満)ので、リアルタイムに推論をかけたい場合はおすすめです。組込みの手法は何通りかあると思うので、別の方法を知っている方いましたら教えていただきたいです!

参考ページ

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?