アノテーションツール「CVAT version2.4.2」試してみた(インストール方法)

# 0. はじめに

以前に、CVAT v1.0が出た際に、インストール方法をまとめていましたが、v2.x.xになって仕様がガラッと変わったため、v2対応として記事にします。

https://qiita.com/wakaba130/items/22903ee28b0f4297516c

なお、CVATのインストールオプションは非常に(闇が深く)機能が多く、すべての機能を試すことができなかったため、以下の２つのみ設定しました。

+ [Semi Auto Annotation](https://opencv.github.io/cvat/docs/administration/advanced/installation_automatic_annotation/)
+ [Share Path](https://opencv.github.io/cvat/docs/administration/basics/installation/#share-path)

## ソフトウェアバージョン

|ソフトウェア| Version |
|:----:|:----:|
| Host OS | Ubuntu 22.04.2 LTS |
| docker |  24.0.1     |
| cvat   | 2.4.2  |

# 1. Install

CVATのReleaseからリリースされたソースコードをダウンロードして、解凍します。
git cloneで行う場合は、必ず**タグを指定する**ようにしてください。
メインのブランチがdevelopブランチになっているためです。

```bash
$ wget https://github.com/opencv/cvat/archive/refs/tags/v2.4.2.zip
$ unzip v2.4.2.zip 
$ rm v2.4.2.zip
$ cd cvat-2.4.2
```

## 1.1. SemiAutoAnnotation設定

SemiAutoAnnotationのための、[nuclio](https://github.com/nuclio/nuclio/releases)をインストールして設定します。

```bash
$ wget https://github.com/nuclio/nuclio/releases/download/1.11.17/nuctl-1.11.17-linux-amd64
$ sudo mv nuctl-1.11.17-linux-amd64 /usr/local/bin/nuctl
$ sudo chmod +x /usr/local/bin/nuctl
$ nuctl --help
Nuclio command-line interface

Usage:
  nuctl [command]

Available Commands:
  beta        A beta version of nuctl as a Nuclio api cli client
  build       Build a function
  completion  Generate the autocompletion script for the specified shell
  create      Create resources
  delete      Delete resources
  deploy      Build and deploy a function, or deploy from an existing image
  export      Export functions or projects
  get         Display resource information
  help        Help about any command
  import      Import functions or projects
  invoke      Invoke a function
  update      Update resources
  version     Display the version number of the nuctl CLI

Flags:
  -h, --help                help for nuctl
  -k, --kubeconfig string   Path to a Kubernetes configuration file (admin.conf)
  -n, --namespace string    Namespace
      --platform string     Platform identifier - "kube", "local", or "auto" (default "auto")
  -v, --verbose             Verbose output

Use "nuctl [command] --help" for more information about a command.
```

cvatで使用できるように設定します。CVATの手順書そのままでは動かなかったので、若干書き換えています。
`--base-image`をコマンドで設定しないほうが動きました。`--path`に設定されている`function-gpu.yaml`または`function.yaml`内に`baseImage`の設定があるので、そちらのイメージを読み込むほうがいいのかもしれません。

### 1.1.1. Tensorflow-MaskRCNN

```bash
$ nuctl create project cvat
$ nuctl deploy --project-name cvat \
  --path serverless/tensorflow/matterport/mask_rcnn/nuclio \
  --platform local \
  --desc "GPU based implementation of Mask RCNN on Python 3, Keras, and TensorFlow." \
  --image cvat/tf.matterport.mask_rcnn_gpu \
  --triggers '{"myHttpTrigger": {"maxWorkers": 1}}' \
  --resource-limit nvidia.com/gpu=1
```

### 1.1.2. ONNX-YOLOv7

```bash
$ nuctl deploy --project-name cvat \
  --path serverless/onnx/WongKinYiu/yolov7/nuclio \
  --platform local \
  --triggers '{"myHttpTrigger": {"maxWorkers": 1}}' \
  --resource-limit nvidia.com/gpu=1
```

### 1.1.3. 動作確認

上記のコマンドが終了したら、ちゃんと実行できるようになっているか確認します。
STATEがreadyになっていたら、準備完了です。

```
$ nuctl get function
 NAMESPACE | NAME                    | PROJECT | STATE | REPLICAS | NODE PORT 
 nuclio    | onnx-yolov7             | cvat    | ready | 1/1      | 32768     
 nuclio    | tf-matterport-mask-rcnn | cvat    | ready | 1/1      | 32769
```

## 2.1. Share path

`docker-compose.override.yml`を作成して、以下の設定を書き込みます。

```bash
$ cd cvat-2.4.2
$ touch docker-compose.override.yml
$ gedit docker-compose.override.yml
```

```yaml:docker-compose.override.yml
services:
  cvat_server:
    volumes:
      - cvat_share:/home/django/share:ro
  cvat_worker_import:
    volumes:
      - cvat_share:/home/django/share:ro
  cvat_worker_annotation:
    volumes:
      - cvat_share:/home/django/share:ro
  cvat_worker_export:
    volumes:
      - cvat_share:/home/django/share:ro

volumes:
  cvat_share:
    driver_opts:
      type: none
      device: /mnt/share #この部分のパスを変更する
      o: bind
```

例えば、`/home/ubuntu/dataset`をシェアするとすると、以下のように書き換えます。

```yaml:docker-compose.override.yml
services:
  cvat_server:
    volumes:
      - cvat_share:/home/django/share:ro
  cvat_worker_import:
    volumes:
      - cvat_share:/home/django/share:ro
  cvat_worker_annotation:
    volumes:
      - cvat_share:/home/django/share:ro
  cvat_worker_export:
    volumes:
      - cvat_share:/home/django/share:ro

volumes:
  cvat_share:
    driver_opts:
      type: none
      device: /home/ubuntu/dataset
      o: bind
```

# 2. 実行と設定

以下のコマンドでCVATを実行します。
※以下の実行は手順を書くための２回目の実行なので、初回の実行時とは表示が若干異なる可能性があります。

```bash
$ docker compose -f docker-compose.yml \
  -f components/serverless/docker-compose.serverless.yml \
  -f docker-compose.override.yml up -d
[+] Building 0.0s (0/0)                                                                     
[+] Running 16/16
 ✔ Network cvat-242_cvat             Created                                                    0.1s 
 ✔ Container cvat_redis              Started                                                    0.6s 
 ✔ Container traefik                 Started                                                    1.0s 
 ✔ Container cvat_db                 Started                                                    0.5s 
 ✔ Container cvat_clickhouse         Started                                                    0.6s 
 ✔ Container cvat_opa                Started                                                    0.5s 
 ✔ Container nuclio                  Started                                                    1.0s 
 ✔ Container cvat_grafana            Started                                                    1.0s 
 ✔ Container cvat_vector             Started                                                    1.3s 
 ✔ Container cvat_worker_webhooks    Started                                                    1.0s 
 ✔ Container cvat_server             Started                                                    1.5s 
 ✔ Container cvat_worker_export      Started                                                    1.2s 
 ✔ Container cvat_worker_annotation  Started                                                    1.4s 
 ✔ Container cvat_worker_import      Started                                                    1.4s 
 ✔ Container cvat_utils              Started                                                    1.3s 
 ✔ Container cvat_ui                 Started                                                    1.7s
```

## User Setting

スーパーユーザ（管理者）のアカウントを作成します。
以下のコマンドを実行すると、ユーザ名、メールアドレス、パスワードを設定します。
パスワードの設定が８文字以上を設定する必要があります。

```bash
$ docker exec -it cvat_server bash -ic 'python3 ~/manage.py createsuperuser'
Username (leave blank to use 'django'): # cvatで使用するユーザ名
Email address:                          # ユーザのメールアドレス
Password:
Password (again): 　　　　　　　　　　　　　　　　　　　
```

# 3. 使い方

ブラウザのアドレスバーに`http://localhost:8080/`を入力するとCVATのログイン画面が表示されます。

![Screenshot from 2023-05-21 23-58-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/8b42b278-cb25-1a97-afe9-e941080010f3.png)

スーパーユーザの設定で設定したアカウントとパスワードを入力してログインすると以下の画面になります。

![Screenshot from 2023-05-21 23-56-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/e5b0f407-16a1-2956-2188-57fb89b6fddd.png)

ブラウザの左上にタブがいくつか表示されます。

+ Project … Datasetの管理・表示をするタブ
+ Tasks … Dataset内の各アノテーションタスクを管理・表示するタブ
+ Jobs … ワーカーごとに割り振ったタスクを管理・表示するタブ
+ Cloud Storages … ？？？
+ Models … マウントしたモデルの管理タブ
+ Analytics … CVATのログなどが観られるタブ（？）

## 3.1. Projectの作成

![Screenshot from 2023-05-22 00-19-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/52e41e37-07a2-c809-399d-5f6d45c56c8a.png)

`Projects`タブの右上にある水色の「＋」ボタンをクリックすると、`Create a new project`と`Create from backup`のボタンが現れます。
今回は、新規作成なので`Create a new prohject`をクリックします。
クリックすると、以下の画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/17555576-0c5a-f62a-2159-c7295717963a.png)

`Name`の欄にプロジェクトの名前を記載します。
下の`Label`で、このプロジェクト内で使用する共通のラベルを作成できます。
そのため、途中でラベルが追加されてしまったり、TrainとTestでラベルが異なるなどのミスを防げます。
※細かくなるのでラベルの設定については割愛します。
ラベルの登録完了後に`Submit & Open`を押して、プロジェクト作成完了です。

## 3.2 Taskの作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/021afad7-0e82-0caf-0116-50d064efe80c.png)

プロジェクトのページを開き、右下の「＋」ボタンをクリックし、`Create a new task`をクリックします。
クリックするとタスクを作成するページが開きます。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/765a5518-e74f-de07-bca6-ab20339db603.png">

`Name`にタスク名を記入します。`Select files`にアノテーションする画像を追加していきます。
`My Computer`は画像をドラッグ＆ドロップで貼り付けられます。
'Connected file share'のタブを開くと、インストール時に`Share Path`で指定したディレクトリがリンクされていますので、その中のディレクトリを指定することも可能です。

次に、一番下の`Advanced configuration`を設定します。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/8ed9510b-316a-bb6f-4188-13ea10561e39.png">

`Advanced configuration`を開くと、データを軽くするために圧縮処理がかけられることがわかります。
もし、画質を下げたくないアノテーション(細かいものやエッジが複雑なもの)である場合は`Image quality`を100％にしましょう。
また、アノテーションのデフォルトのフォーマットがCVATのVideoアノテーションフォーマットになっています。
もし、画像サイズが異なる別シーンの画像をアノテーションする場合は、`CVAT for Images`のフォーマットを指定することをおすすめします。
設定が終わったら、`Submit & Open`でタスクを保存して開きます。

## 3.3 アノテーション画面

<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/40ec7351-27a7-4046-bb9f-e38e775a6638.png">

Taskの作成が終わると`Jobs`のリストの中に先程作成したタスクが生成されます。`Job #*`のリンクをクリックするとアノテーション画面に移動します。

<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/1bea736c-4298-b2de-5578-00d75acbb37a.png">

上記のようにアノテーション画面が開くので、あとは、好きなようにアノテーションしましょう。
ただし、大きい画像を開いたあとに小さい画像に移動すると、前の画像サイズが引き継がれて開かれるので、画像がどこか端に飛んでしまうことがあります。そのため、次の画像を開くと、画像が開けていないような画面が表示されることがあります。

<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104675/57cf7169-0ea1-6da4-dda7-4da57ce47a05.png">

その際は、右上の自分の名前をクリックして、`Settings`を開き、その中の`Reset Zoom`をクリックします。
これにより、次の画像に移動した際に、画像サイズの設定がリセットされて、画像が端に飛ぶことがなくなります。

### 3.4 Automatic annotation

自動アノテーションの使い方は、以下のページにあります。

https://opencv.github.io/cvat/docs/manual/advanced/automatic-annotation/


以上が簡単なCVATの使い方になります。

# 4. 小ネタ

起動したときにどのymlファイルを読み込んだか忘れて、downするときに戸惑うことが多かったので、起動が成功した段階でcvatの直下に以下のようなスクリプトを組んで、`up`と`down`の入力で起動と終了ができるようにしておいたほうが便利です。

```
$ cd cvat-2.4.2
$ gedit updown_script.sh
```

```bash:updown_script.sh
#!/bin/bash

if test $1 = "up"; then
  com="up -d"
elif test $1 = "down"; then
  com="down"
fi

docker compose -f docker-compose.yml \
 -f components/serverless/docker-compose.serverless.yml \
 -f docker-compose.override.yml $com
```

## 4.1. 使い方

```bash
# 起動
$ updown_script.sh up 
# 終了
$ updown_script.sh down
```


# 参考

https://peislab.com/programming/deeplearning/cvat-with-wsl2/

https://github.com/opencv/cvat/issues/3547