ROS Noeticでdarknet_rosを使ってYOLOv3を動かす


# 動作環境

|    |    |
| ---- | ---- |
|  OS  |  ubuntu20.04.2LTS  |
|  ROS  |  Noetic   |
|  OpenCV  |   4.2.0  |
|  GPU  |  GTX1660Ti  |
|  CUDA  |  11.2.0   |

# darknet_rosのインストール

ワークスペースの作成

```bash
$ mkdir -p ~/darknet_ws/src
$ cd ~/darknet_ws
$ catkin_make
```

darknet_rosのインストール

```bash
$ cd ~/darknet_ws/src
$ git clone --recursive https://github.com/leggedrobotics/darknet_ros.git
$ cd ~/darknet_ws
$ catkin_make
```

以下のようなエラーが出たらCMakeLists.txtを編集

```bash
nvcc fatal   : Unsupported gpu architecture 'compute_30'
CMake Error at darknet_ros_lib_generated_col2im_kernels.cu.o.cmake:220 (message):
  Error generating
```

darknet_ros/darknet_ros/CMakeLists.txtの24~26行目あたりのcompute_30に対応する行を削除

```txt
-   -gencode arch=compute_30,code=sm_30
```

修正したら再度`catkin_make`

# USBカメラの画像で実行

usb cameraを使うノードをインストール

```bash
$ sudo apt install ros-noetic-usb-cam
```

darknet_ros/darknet_ros/config/ros.yamlを編集
4行目　subscribers: camera_reading: topic: を入力するRGB画像のトピック名にする
（デフォルトは/camera/rgb/image_raw）

```yaml:ros.yaml
subscribers:

  camera_reading:
    topic: /usb_cam/image_raw
    queue_size: 1
```


cameraノードの実行

```bash
$ roslaunch usb_cam usb_cam-test.launch 
```


別のターミナルを開いてdarknet_ros(YOLOv3)を実行

```bash
$ source darknet_ws/devel/setup.bash
$ roslaunch darknet_ros yolo_v3.launch
```

# YOLOv3-tinyを使う

darknet_rosデフォルトで使えるYOLOは以下の3つ
1. yolov2
2. yolov2-tiny
3. yolov3

YOLOv3-tinyは使えないので学習済みのweightをダウンロードして使えるようにする

## 学習済みweightsのダウンロード

darknet_ros/yolo_network_config/weights/ディレクトリにCOCO Datasetで学習済みのweightsファイルをダウンロード

```bash
$ source darknet_ws/devel/setup.bash
$ roscd darknet_ros/yolo_network_config/weights/
$ wget https://pjreddie.com/media/files/yolov3-tiny.weights
``` 

## cfgファイルの作成

darknet/cfgにある`yolov3-tiny.cfg`をdarknet_ros/yolo_network_config/cfg/にコピー

```bash
$ cd ~/darknet_ws/src/darknet_ros/darknet/cfg
$ cp yolov3-tiny.cfg ../../darknet_ros/yolo_network_config/cfg/
```

## yamlファイルの作成

darknet_ros/config以下にROSパラメータの設定ファイル`yolov3-tiny.yaml`ファイルを作成

```yaml:yolov3-tiny.yaml
yolo_model:

  config_file:
    name: yolov3-tiny.cfg
  weight_file:
    name: yolov3-tiny.weights
  threshold:
    value: 0.3
  detection_classes:
    names:
      - person
      - bicycle
      - car
      - motorbike
      - aeroplane
      - bus
      - train
      - truck
      - boat
      - traffic light
      - fire hydrant
      - stop sign
      - parking meter
      - bench
      - bird
      - cat
      - dog
      - horse
      - sheep
      - cow
      - elephant
      - bear
      - zebra
      - giraffe
      - backpack
      - umbrella
      - handbag
      - tie
      - suitcase
      - frisbee
      - skis
      - snowboard
      - sports ball
      - kite
      - baseball bat
      - baseball glove
      - skateboard
      - surfboard
      - tennis racket
      - bottle
      - wine glass
      - cup
      - fork
      - knife
      - spoon
      - bowl
      - banana
      - apple
      - sandwich
      - orange
      - broccoli
      - carrot
      - hot dog
      - pizza
      - donut
      - cake
      - chair
      - sofa
      - pottedplant
      - bed
      - diningtable
      - toilet
      - tvmonitor
      - laptop
      - mouse
      - remote
      - keyboard
      - cell phone
      - microwave
      - oven
      - toaster
      - sink
      - refrigerator
      - book
      - clock
      - vase
      - scissors
      - teddy bear
      - hair drier
      - toothbrush
```


## launchファイルの作成

darknet_ros/launch以下にyolov3-tiny用のlaunchファイルを作成
`network_param_file`引数に先程作成したyamlファイルのパスを設定

```xml:yolov3-tiny.launch
<?xml version="1.0" encoding="utf-8"?>
<launch>
  
  <!-- Use YOLOv3-Tiny -->
  <arg name="network_param_file"         default="$(find darknet_ros)/config/yolov3-tiny.yaml"/>
  <arg name="image" default="camera/rgb/image_raw" />


  <!-- Include main launch file -->
  <include file="$(find darknet_ros)/launch/darknet_ros.launch">
    <arg name="network_param_file"    value="$(arg network_param_file)"/>
    <arg name="image" value="$(arg image)" />
  </include>

</launch>
```
## 実行
USBカメラを起動

```bash
$ roslaunch usb_cam usb_cam-test.launch 
```
darknet_rosを起動

```bash
$ source darknet_ws/devel/setup.bash
$ roslaunch darknet_ros yolov3-tiny.launch
```

# 参考

https://github.com/leggedrobotics/darknet_ros


https://ar-ray.hatenablog.com/entry/2021/05/07/180000

https://github.com/leggedrobotics/darknet_ros/issues/290

YOLOv3-tinyで学習してみた１（パソコン作業、アノテーションまで）

https://akifukka.hatenablog.com/entry/YOLOv3-tiny_train1