Skip to content

画像アノテーション

Potatoで、バウンディングボックス、ポリゴン、マスク、ランドマークを使った画像アノテーションを設定します。instance_displayで画像を表示し、COCOまたはYOLOにエクスポートできます。

Potatoは、分類、物体検出、セグメンテーション、キーポイントのタスク向けに画像アノテーションをサポートしています。

画像の表示

画像を表示することとアノテーションを収集することは、別々の設定です。instance_displayはアノテーターが何を見るかを決め、annotation_schemesはアノテーターが何に回答するかを決めます。両者を分けておくことで、どの種類のコンテンツもどの種類の質問とも組み合わせられます。

yaml
instance_display:
  fields:
    - key: image_url          # Field name in your data file
      type: image
      label: "Image to classify"
      display_options:
        max_width: 600
        zoomable: true

image_annotationスキームは画像の上に描画するためのもので、画像を表示するためのものではありません。分類タスクに必要なのは、上の表示フィールドとradioまたはmultiselectスキームだけです。

表示オプション

オプション説明
max_widthレンダリング時の最大幅(ピクセル)
max_heightレンダリング時の最大高さ(ピクセル)
zoomableクリックによるズームを有効にする
object_fit画像が枠をどう埋めるか
alt_textスクリーンリーダー用の代替テキスト

Potatoが認識しないオプション名は、黙って無視されるキーではなく設定エラーになり、エラーメッセージは最も近い実在のオプション名を提示します。

データ形式

データファイルで画像を参照します。

json
{"id": "img_001", "image_url": "https://example.com/photo_001.jpg"}
{"id": "img_002", "image_url": "/static/images/photo_002.png"}

data_filesはパスのリストで、item_propertiesはデータのフィールド名をPotatoが読み取るフィールド名に対応付けます。

yaml
data_files:
  - "data/image_tasks.json"
 
item_properties:
  id_key: id
  text_key: image_url   # The field holding the image URL

画像分類

画像全体を分類します。

yaml
annotation_schemes:
  - annotation_type: radio
    name: category
    description: "What is shown in this image?"
    labels:
      - Cat
      - Dog
      - Bird
      - Other
 
  - annotation_type: multiselect
    name: attributes
    description: "Select all that apply"
    labels:
      - Indoor
      - Outdoor
      - Multiple animals
      - Human present

マルチラベル分類

yaml
annotation_schemes:
  - annotation_type: multiselect
    name: objects
    description: "What objects are visible?"
    labels:
      - Person
      - Car
      - Building
      - Tree
      - Animal
      - Furniture
      - Food
      - Electronic device

画像品質評価

yaml
annotation_schemes:
  - annotation_type: likert
    name: quality
    description: "Overall image quality"
    size: 5
    min_label: "Very poor"
    max_label: "Excellent"
 
  - annotation_type: multiselect
    name: issues
    description: "Select any quality issues"
    labels:
      - Blurry
      - Overexposed
      - Underexposed
      - Noisy
      - Low resolution
      - Watermark visible

画像への描画

image_annotationスキームにはtoolsとlabelsの両方が必要です。各ラベルに色とkey_valueを指定すると行数は増えますが、それだけの価値があります。アノテーターはクリックよりもキー操作のほうがはるかに速くラベルを付けられるからです。

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: object_detection
    description: "Draw boxes around objects"
    tools:
      - bbox
      - polygon
    labels:
      - name: person
        color: "#FF6B6B"
        key_value: "1"
      - name: vehicle
        color: "#4ECDC4"
        key_value: "2"
      - name: animal
        color: "#45B7D1"
        key_value: "3"
    min_annotations: 1
    zoom_enabled: true
    pan_enabled: true

colorは16進数(#rgb、#rrggbb、#rrggbbaa)で指定する必要があります。CSSの色名やrgb()は読み取られません。図形は正しく見えますが、マスクはピクセル単位で塗られるため、赤にフォールバックします。

利用可能なツール

ツール説明
bbox矩形のバウンディングボックス
polygon複数の点からなる閉じたポリゴン
polyline複数の点からなる開いたパス。車線区分線、血管、ひび割れ、海岸線向け
ellipse楕円と円。細胞、細胞核、車輪、顔向け
keypoint_set順序付きのスケルトン。人や動物の姿勢、顔のランドマーク向け
cuboid_2d画像に投影した3Dボックス(KITTI形式)
samマジックワンド:物体をクリックするとモデルがセグメンテーションする
freeformフリーハンド描画
landmark単一点のマーカー
brushピクセル単位のマスク用セグメンテーションブラシ
eraserマスク領域を消去する
fill閉じた領域の塗りつぶし

ポリゴンは閉じていて面積を囲みます。ポリラインは開いていて、長さはあっても内部を持ちません。この違いはエクスポート時に意味を持ち、ポリラインはarea: 0で書き出され、領域として扱われることはありません。

ポリゴンアノテーション

矩形でない領域向け:

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: regions
    description: "Outline regions of interest"
    tools:
      - polygon
    labels:
      - name: Building
      - name: Road
      - name: Vegetation
      - name: Water

セグメンテーションマスク

ピクセル単位の作業には、ペイントツールを有効にします。マスクはピクセルごとの配列ではなくランレングス符号化で保存されるため、画像全体のマスクでもサイズが小さく保たれます。

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: segmentation
    description: "Paint regions using the brush tool"
    tools:
      - brush
      - eraser
      - fill
    labels:
      - name: road
        color: "#45B7D1"
      - name: sidewalk
        color: "#96CEB4"
    brush_size: 20
    mask_opacity: 0.5
    mask_mode: semantic

mask_mode: semanticは、同じクラスのすべてのストロークを1つの領域にまとめます。同じクラスの2つの物体を区別したままにする必要がある場合はinstanceを使います。

出力形式

アノテーションはフラットなJSON配列として保存され、すべての図形とマスクが同じリストに入ります。座標は画像に対して0から1の範囲に正規化されるため、画像が別のサイズで配信されてもアノテーションは正しいままです。

json
[
  {
    "type": "bbox",
    "label": "person",
    "color": "#FF6B6B",
    "coordinates": {"x": 0.125, "y": 0.104, "width": 0.3125, "height": 0.625}
  },
  {
    "type": "polygon",
    "label": "vehicle",
    "color": "#4ECDC4",
    "coordinates": [
      {"x": 0.02, "y": 0.04}, {"x": 0.20, "y": 0.04},
      {"x": 0.20, "y": 0.21}, {"x": 0.02, "y": 0.21}
    ]
  },
  {
    "type": "mask",
    "label": "road",
    "color": "#45B7D1",
    "rle": {"counts": [12, 40, 8], "size": [480, 640]}
  }
]

ジオメトリのキーは種類によって異なります。

種類ジオメトリのキー形状
bboxcoordinates{x, y, width, height}、正規化済み
polygoncoordinates{x, y}のリスト、正規化済み
landmarkcoordinates{x, y}、正規化済み
freeformcoordinates{path, left, top, scaleX, scaleY}
maskrle{counts: [ints], size: [height, width]}

rle.sizeは[height, width]の順です。Pythonでこれらの形式との相互変換を行うときは、フィールドを直接読むのではなく、potato.export.cv_utilsのnormalize_annotation_object()とto_client_object()を使ってください。

図形の出所

保存された後は、モデルの検出結果を受け入れたものと手で描いたボックスは他の点で区別がつかないため、各図形は自身の出所を記録します。これがなければ、モデルで事前ラベル付けを行うプロジェクトは、自分のデータから自分の受け入れ率を報告できません。

json
{
  "type": "bbox",
  "label": "person",
  "coordinates": {"x": 0.125, "y": 0.104, "width": 0.3125, "height": 0.625},
  "source": "ai",
  "ai_model": "yolov8n",
  "confidence": 0.82,
  "edited": true
}
キー意味
sourcehuman(ブラウザで描画)、ai(モデルが提案しアノテーターが受け入れた)、import(データと一緒に取り込まれた)
ai_modelどのモデルか(エンドポイントが報告する場合)
confidenceこの図形に対する検出器自身のスコア
editedアノテーターが、自分のものではない図形を後から移動、リサイズ、またはラベル変更した
carried_overこの画像で作成したのではなく、前の画像から引き継いでコピーした

editedがあることで、ボックスをそのまま受け入れた場合と、受け入れた後に修正した場合を区別できます。モデルとの一致といえるのは前者だけです。

既存アノテーションのレビュー

既存の図形をレビューするには、データフィールドに追加するのではなくインポートします。potato importはCOCOファイルを実行可能なプロジェクトに変換し、各図形にsource: importを付けます。

bash
potato import --input instances_val2017.json \
    --image-dir /data/val2017 \
    --image-url-prefix /files \
    --output-dir my-project/ \
    --schema-name object_detection
 
potato start my-project/config.yaml -p 8000

その後アノテーターはインポートされた図形をその場で修正し、エクスポートは往復を通じて人間とモデルの区別を保持します。

画像比較

pairwiseスキームで2枚の画像を比較します。items_keyはペアを保持するデータフィールドの名前を指定します。

yaml
annotation_schemes:
  - annotation_type: pairwise
    name: preference
    description: "Which image looks better?"
    mode: binary
    items_key: images
    show_labels: true
    labels:
      - "Original"
      - "Edited"
    allow_tie: true
    tie_label: "About the same"

画像キャプショニング

yaml
annotation_schemes:
  - annotation_type: text
    name: caption
    description: "Write a caption for this image"
    rows: 4
    placeholder: "Describe what you see..."

キャプション品質レビュー

画像と生成されたキャプションを並べて表示し、キャプションを評価します。

yaml
instance_display:
  fields:
    - key: image_url
      type: image
      label: "Image"
    - key: generated_caption
      type: text
      label: "Generated caption"
 
annotation_schemes:
  - annotation_type: likert
    name: accuracy
    description: "How accurate is this caption?"
    size: 5
    min_label: "Very inaccurate"
    max_label: "Very accurate"
 
  - annotation_type: likert
    name: fluency
    description: "How natural is the language?"
    size: 5
    min_label: "Very awkward"
    max_label: "Very natural"
 
  - annotation_type: text
    name: improved_caption
    description: "Suggest a better caption (optional)"
    rows: 4
    label_requirement:
      required: false

コンテンツモデレーション

yaml
annotation_schemes:
  - annotation_type: radio
    name: safe_for_work
    description: "Is this image safe for work?"
    labels:
      - Safe
      - Questionable
      - Not Safe
 
  - annotation_type: multiselect
    name: violation_types
    description: "Select all violations (if any)"
    labels:
      - Violence
      - Adult content
      - Hate symbols
      - Graphic content
      - Spam/advertisement

交換形式

PotatoはCOCO JSONを、すべてのセグメンテーション符号化とcrowd領域も含めて読み込み、COCO、YOLO、Pascal VOC、ラベルごとのマスクPNGを書き出します。

bash
python -m potato.export -c my-project/config.yaml -f coco -o ./export/

YOLOとPascal VOCはバウンディングボックスしか保持しないため、それ以外の図形は外接ボックスに変換されます。

完全な例:物体検出レビュー

yaml
annotation_task_name: "Object Detection Verification"
task_dir: "."
 
data_files:
  - "data/detections.json"
 
item_properties:
  id_key: id
  text_key: image_url
 
instance_display:
  fields:
    - key: image_url
      type: image
      label: "Image"
      display_options:
        max_width: 1000
        zoomable: true
 
annotation_schemes:
  # Correct the boxes
  - annotation_type: image_annotation
    name: objects
    description: "Verify and correct object boxes"
    tools:
      - bbox
    labels:
      - name: Person
        key_value: "1"
      - name: Vehicle
        key_value: "2"
      - name: Animal
        key_value: "3"
      - name: Object
        key_value: "4"
    zoom_enabled: true
    pan_enabled: true
 
  # Overall assessment
  - annotation_type: radio
    name: prediction_quality
    description: "How accurate were the predictions?"
    labels:
      - All correct
      - Minor corrections needed
      - Major corrections needed
      - Mostly incorrect
 
  - annotation_type: number
    name: missed_objects
    description: "How many objects were missed?"
    min: 0
    max: 50
 
  - annotation_type: text
    name: notes
    description: "Any issues or comments?"
    rows: 4
    label_requirement:
      required: false
 
output_annotation_dir: "output/"
export_annotation_format: jsonl
 
user_config:
  allow_all_users: true

サーバーを起動します。

bash
potato start config.yaml -p 8000

パフォーマンスのヒント

  1. アノテーション前にリサイズする:大きな元画像はアノテーションの質を上げることなく読み込みを遅くする
  2. 写真にはJPEGを使う:ファイルが小さく、読み込みが速い
  3. グラフィックにはPNGを使う:図やスクリーンショットの画質が良い
  4. 表示サイズに上限を設ける:max_widthを設定し、ブラウザがインスタンスごとに巨大な画像を縮小しなくて済むようにする
  5. 一貫して前処理する:データセット全体でサイズと形式を揃える