実習:物体検出(YOLOv3) - masuko-shingo/jetson-nano GitHub Wiki
ここでは,YOLOv3を用いた物体検出を行います.
論文や著者のサイトは末尾の"参考文献"に記述しています.
Logicool C310 HD WEBCAM
https://www.amazon.co.jp/dp/B084CC82PH/
Microsoft LifeCam HD5000 7ND-00006
https://www.amazon.co.jp/dp/B003CYMA4U
- ディレクトリを作る
作業する場所を作ります.
ここでは,yolov3としていますが,名前はなんでも構いません.
$ mkdir yolov3
$ cd yolov3
- aptの更新
まず,aptを更新しておきます.
$ sudo apt-get update
- CUDAのパスを通す
CUDA(GPUのドライバ)のパスを通して,GPUを使うための準備をします.
$ export PATH=/usr/local/cuda-10.0/bin${PATH:+:${PATH}}
$ export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
- Yolov3をcloneする
Yolov3のリポジトリをgithubからcloneしてきます.
$ git clone https://github.com/AlexeyAB/darknet
$ cd ~/yolov3/darknet #darknetに移動
- 重みのダウンロード
重みをダウンロードしてきます.
ダウンロードする場所はdarknetのままで問題ありません.
$ wget https://pjreddie.com/media/files/yolov3.weights
$ wget https://pjreddie.com/media/files/yolov3-tiny.weights
- GPU, CUDA, CUDNN, OPENCVを有効にする
Makefileを編集して,GPU,CUDA,CUDNN,OPENCVを有効にします.
$ sudo vi Makefile
上記のコマンドでMakefileを編集できるようにして,
文頭のパラメータを変更します.
※エディタがvi,vimの場合は" i "で文字を打ち込める(編集できる)ようになります
Makefile変更前
GPU=0
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0
変更後
GPU=1
CUDNN=1
OPENCV=1
OPENMP=0
DEBUG=0
- コンパイル(Make)する
Make
と打ち込み,コンパイルを行います.
$ Make
ここからは,デフォルトで入っている学習済みモデルを用いて,画像認識を行ってみます.
- ディレクトリの移動
$ cd ~/yolov3/darknet
- 推定を行う際
$ ./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg
※dog.jpgは例
dataに認識したい画像を追加すると他の画像の推定を行える
frame0000を追加した際の例
$ ./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/frame0000.jpg
ここでは,デフォルトで入っている学習済みモデルを用いて,USBカメラ画像から物体認識を行ってみます.
- ディレクトリの移動
$ cd ~/yolov3/darknet
- 推定を行う際
$ ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights -c 0
最後の数値0
はUSBカメラに当てられている値.
調べたい場合は,ls /dev/ttyUSB*
と入力.
$ ls /dev/ttyUSB*
※*
はワイルドカード
学習済みモデルでは,データセットはCOCOデータセット,ネットワークのモデルは学習済みのモデルを用いて,推論を行っていました.
ここからは,実際にデータセットを作成し,自作データセットでの学習,推論を行います.
まずは,データセットの作成を行います.
この作業は主にPCで行っていきます.
今回はTurtlebot3の画像を使用してデータセットを作成していきますが,他のものでも構いません.
まずUSBカメラを起動させた状態でbagファイルを取得します.
USBカメラを起動した状態でrosbag record -a
を行います.
※bagファイルの取得はPCからでも,Nanoからでも構いません.
- USBカメラの起動
$ roscore
$ roslaunch usb_cam usb_cam-test.launch
- bagファイルを取得する
全てのトピックを撮る場合(推奨)
$ rosbag record -a
bagファイルの記録が始まったのを確認したら,認識したい物体を撮影します.
できるだけ様々な環境(背景)で,いろいろな角度の物体を撮影しましょう.
- bagファイルから画像を取得
$ roscd image_view
$ rosmake image_view --rosdep-install
$ sudo apt-get install aptitude
※sudo: aptitude: command not found
と出た場合
$ sudo aptitude install mjpegtools
ディレクトリを作ります.
$ mkdir workspace
$ cd workspace
$ source devel/setup.bash
ディレクトリ内でlaunchファイルを作成します.
$ vim export.launch
launchファイルに以下の内容を記述します.
例
<launch>
<node pkg="rosbag" type="play" name="rosbag" args="-d 2 /home/masuko/2022-01-12-16-48-01.bag"/>
<node name="extract" pkg="image_view" type="extract_images" respawn="false" output="screen" cwd="ROS_HOME">
<remap from="image" to="/image_raw"/>
</node>
</launch>
~
※/home/masuko/2022-01-12-16-48-01.bag
の部分は,recordした任意のbagファイルが存在するパスに当てはめてください.
/image_raw
の部分は,rosbag info
で確認できます.
例
$ rosbag info 2022-01-12-16-48-01.bag
中略
topics: /camera_info 838 msgs : sensor_msgs/CameraInfo
/image_raw 838 msgs : sensor_msgs/Image
/image_raw/compressed 838 msgs : sensor_msgs/CompressedImage
/image_raw/compressed/parameter_descriptions 1 msg : dynamic_reconfigure/ConfigDescription
/image_raw/compressed/parameter_updates 1 msg : dynamic_reconfigure/Config
/image_raw/compressedDepth/parameter_descriptions 1 msg : dynamic_reconfigure/ConfigDescription
/image_raw/compressedDepth/parameter_updates 1 msg : dynamic_reconfigure/Config
/image_raw/theora 841 msgs : theora_image_transport/Packet
/image_raw/theora/parameter_descriptions 1 msg : dynamic_reconfigure/ConfigDescription
/image_raw/theora/parameter_updates 1 msg : dynamic_reconfigure/Config
/image_view/output 838 msgs : sensor_msgs/Image
/image_view/parameter_descriptions 1 msg : dynamic_reconfigure/ConfigDescription
/image_view/parameter_updates 1 msg : dynamic_reconfigure/Config
/rosout 852 msgs : rosgraph_msgs/Log (3 connections)
/rosout_agg 838 msgs : rosgraph_msgs/Log
作成したlaunchファイルを実行します.
$ roslaunch export.launch
中略
[rosbag-1] process has finished cleanly
log file: /home/masuko/.ros/log/e7529e8c-737a-11ec-aa06-7c7635a4ab69/rosbag-1*.log
取得した画像は,~/.ros
ディレクトリ内に生成されています.
※500枚程度生成されます.
生成された画像を確認
$ cd ~/.ros
$ ls
frame0000.jpg
...
任意のディレクトリ作成します.
※workspaceは例
$ cd ~/workspace
$ mv ~/.ros/frame*.jpg workspace/
で画像を移動させます.
[参考]:http://wiki.ros.org/ja/rosbag/Tutorials/Exporting%20image%20and%20video%20data
ここでは,labelImgというアノテーションツールを用います.
labelImgはpascalVOC形式,YOLO形式どちらの形式でもアノテーションできるツールです.
Yolo_Labelというツールもありますが,ここではlabelImgでのアノテーション手順を示していきます.
使用するツール:labelImg
https://github.com/tzutalin/labelImg/tree/98e88371adc0203e170a7aa423e1b22df0570589
pip3のインストール
※pip3が入ってない場合
$ sudo apt install python3-pip
- アノテーションツールをインストール
pip3で
$ pip3 install labelImg
※インストールできない場合,こちらのissueを試してください.
url:https://github.com/masuko-shingo/jetson-nano/issues/8
- 前項目でインストールができたら,
labelImg
でツールを起動
$ labelImg
起動時の画面
2. 「ディレクトリを開く」で,生成したjpg画像が格納されているディレクトリを開いてください.
例
-
YOLO形式でアノテーションを行いたいため,「PascalVOC」を選択して「YOLO」と表示された状態にします.
-
「矩形を作成する」を選択して矩形(バウンディングボックス)を作成します.
認識したい物体をドラッグで囲みます.
例
-
ラベル名を設定します.
ここでは例としてtb3とします.
ラベル名を設定後は,
6. 「保存する」もしくは'ctrl+s'でアノテーション結果を保存します.
※「表示」の「自動で保存する」にチェックをいれると手間が省けます.
- 保存したディレクトリにテキストファイルがあるか確認します.
保存できていれば,ラベル名が記述されているclasses.txtと,画像に対応したtxtファイルが生成されています.
例
$ cd test/label
$ ls
classes.txt frame0293.txt
例
# 0 0.373437 0.445833 0.365625 0.562500
最初の数値0は,クラス数を意味している数字であり,0の場合はクラス数が1つ,1の場合はクラス数が2つということになります.
次の4つの数値0.373437 0.445833 0.365625 0.562500は,画像内におけるバウンディングボックスの座標を意味します.
左からx座標,y座標,幅(width),高さ(height)となっています.画像内左上が(x,y)(0,0)になっています.
これで,アノテーション作業は終了です. 次の項目では,学習(トレーニング)に入っていきます.
作成したデータセットで学習させます. これにより,データセットのクラスを認識するモデルが生成されます. まずは,学習を始める準備を行います.
特徴抽出器darknet53.conv74のダウンロードをします.
$ cd ~/yolov3/darknet/build/darknet/x64/
$ wget https://pjreddie.com/media/files/darknet53.conv.74
yolov3.cfgの編集を行います.
- batch,subdivisionsの設定
まず,batch,subdivisionsを# Testing
から# Training
に切り替えます.
文頭のパラメータを編集 (1行〜7行目)
[net]
# Testing
# batch=1
# subdivisions=1
# Training
batch=64
subdivisions=16
...
- max_batchesの設定
次に,max_batchesの値を変更します.
設定する値は,クラス数*2000を目安に変更します.
※訓練画像の枚数以上の値となるようにしてください.
クラス数が1の際(20行目)例:
max_batches = 2000
- stepsの設定
次に,stepsの値を変更します.
設定する値は,max_batchesの0.8倍,0.9倍を目安に変更します.
クラス数が1の際(20行~22行目)例:
max_batches = 2000
policy=steps
steps=1600,1800
- width,heightの設定
次に,width,heightを設定します.
設定する値は,416か,32の倍数に変更します.
(8行,9行目)
width=416
height=416
- [yolo]層のclassesを設定する 3つあるyolo層(推定層)のclassesの値を変更します. クラス数が1の際(610行目)例
[yolo]
mask = 6,7,8
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=1
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
クラス数が1の際(696行目)例
[yolo]
mask = 3,4,5
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=1
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
クラス数が1の際(783行目)例
[yolo]
mask = 0,1,2
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=1
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
- [yolo]層直前の[convolutional]層,filtersを設定する
[yolo]層(推定層)直前にある
編集後
yolov3.cfgと同内容の,yolo-obj.cfgファイルを作成します.
※yolov3.cfgの内容をコピーして,yolo-obj.cfgファイルを作成しても問題ありません.
$ vi yolo-obj.cfg
$ ./darknet detector train build/darknet/x64/data/obj.data cfg/yolo-obj.cfg darknet53.conv.74
最後に,自作データセットで学習させたモデルを用いて画像認識を行っていきます. ここは,学習済みモデルを用いた際と同じ流れになります.
Yolov3論文: https://arxiv.org/abs/1804.02767
Yolov3サイト: https://pjreddie.com/darknet/yolo/
使用するリポジトリ: https://github.com/AlexeyAB/darknet
・はじめに
https://github.com/masuko-shingo/jetson-nano/blob/main/README.md
・Jetson Nano環境構築
https://github.com/masuko-shingo/jetson-nano/wiki/Jetsonnano%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89
・実習:SLAM, Navigation(Turtlebot3)
https://github.com/masuko-shingo/jetson-nano/wiki/%E5%AE%9F%E7%BF%92%EF%BC%9ASLAM,-Navigation(Turtlebot3)