はじめに
こんにちは!yukkyです。今回はCVATを使ってみて、少し仕様を理解できたので、メモ代わりに投稿します。この記事は、以下のようなユースケースに基づいており、他のCVAT関連記事よりも実用的な内容になっていると思います。
- データはSSH先のリモートサーバーにあり、ローカルにダウンロードしない
- アノテーションの付与のみローカルPCから行う
- 既に付与されたアノテーションを編集・修正・削除する
CVATの使い方
CVATのセットアップ方法については、こちらの記事を参考にしてください。基本的には、Gitでリポジトリをクローンし、docker-compose
コマンドを実行するだけでWebサーバーが立ち上がります。そのサーバーにアクセスして作業を開始します。
リモートサーバー上で立ち上げたWebサーバーにアクセスするには、以下のコマンドを実行してください。
ssh -L 8080:localhost:8080 username@remote_server_ip
さらに、リモートサーバー上のデータ(画像データ)をCVATに認識させるには、以下の内容でdocker-compose.override.yml
ファイルを作成し、クローンしたCVATディレクトリに配置します。
services:
cvat_server:
volumes:
- cvat_share:/home/django/share:ro
cvat_worker_import:
volumes:
- cvat_share:/home/django/share:ro
cvat_worker_export:
volumes:
- cvat_share:/home/django/share:ro
cvat_worker_annotation:
volumes:
- cvat_share:/home/django/share:ro
cvat_worker_chunks:
volumes:
- cvat_share:/home/django/share:ro
volumes:
cvat_share:
driver_opts:
type: none
device: 認識させたいimgがあるディレクトリ
o: bind
その後、先ほどの記事を参考に、Create a new task
画面でデータセットを選択する際、My computer
ではなくConnected file share
を選択すると、リモートサーバー上に配置した画像データを直接利用できます。
アノテーションのインポート時の注意点
ここで一つ注意点があります(私がハマったポイントです…)。Connected file share
を選択すると、そのディレクトリ構造がそのまま保持されます。例えば、docker-compose.override.yml
のdevice
フィールドに/datas
を指定し、以下のようなディレクトリ構造だったとします(YOLO形式を想定)。
/datas
├── images
│ ├── train
│ │ ├── image1.jpg
│ │ ├── image2.jpg
│ │ └── ...
├── labels
│ ├── train
│ │ ├── image1.txt
│ │ ├── image2.txt
│ │ └── ...
├── train.txt
└── data.yaml
この場合、image1.jpg
やimage2.jpg
をアノテーションしようとすると、CVAT上では以下のようなディレクトリ構造として認識されます。
data
├── images/train/images/train
│ ├── image1.jpg
│ ├── image2.jpg
│ └── ...
├── labels/train/images/train
│ ├── image1.txt
│ ├── image2.txt
│ └── ...
├── train.txt
└── data.yaml
なぜこのような構造になるかというと、CVATは現在/datas
でマウントされているため、各画像をimages/train/image1.jpg
のように認識します。しかし、YOLO形式の構造であるimages/train
と重なることで、結果的にimages/train/images/train/image1.jpg
のように認識されます。
このため、labels
ディレクトリも同様の構造を求められるため、train.txt
も上記のように修正する必要があります。あるいは、画像が直下にあるディレクトリをマウントするよう設定を変更することで、より簡単に対応できます(個人的には後者の方法がおすすめです)。
まとめ
CVATを使ったアノテーション作業では、リモートサーバー上のデータを直接利用することで、効率的なワークフローを実現できます。ただし、ディレクトリ構造の扱いには注意が必要で、特にYOLO形式のデータセットを使用する場合には、適切な設定や構造変更が求められることがあります。
この記事では、私が実際にハマったポイントや解決方法を共有しました。同じようなユースケースに直面している方の助けになれば幸いです!