Markdownで表示

データセット形式

このページは、ライブラリ自身のdocs/dataset_schema.mdにあるデータセットファイル規約に対応します。各正規タスクが想定するYAMLキーとディスク上の配置を扱います。

共通YAML

detectsegmentposeobbに適用されます。

キー必須意味
pathデータセットルート
train学習時学習画像
val検証時検証画像
testテスト画像
names必須クラス一覧、または整数キーのマッピング
ncクラス数。存在する場合はnamesと一致する必要がある
downloadダウンロード手順。Pythonスクリプトには明示的な許可が必要
annotationsdetect、segment、obb向けの、splitからネイティブCOCO JSONファイルへのマッピング

trainvaltestには画像ディレクトリ、画像一覧の.txtファイル、またはそれらのリストを指定できます。ラベルパスは1つの置換規則に従います。

images/.../image.jpg -> labels/.../image.txt

ネイティブCOCO JSONデータセットでは、annotationsがsplitをJSONファイルへマッピングし、splitパスが画像ルートを指定します。

yaml
path: dataset
train: images/train
val: images/val
annotations:
  train: annotations/train.json
  val: annotations/val.json

namesが存在する場合、ネイティブCOCO JSONのカテゴリ名はYAMLのクラス名と一致する必要があり、その名前がモデルのラベルIDを定義します。namesがない場合、COCOカテゴリIDを並べ替えて0..N-1へ密にマッピングします。

データセットYAMLはtaskキーを持ちません。明示的なモデルとタスクの選択が優先されます。

すべてのテキストラベルファイルに共通する規則は次のとおりです。

  • 画像ごとに1つの.txtラベルファイル。
  • ラベルファイルがない、または空の場合は物体なし。
  • class_id0..nc-1内の整数。
  • 座標は[0, 1]内の有限な正規化浮動小数点数。
  • 座標は元画像の幅と高さを基準とする。
  • 行は信頼度もトラックIDも持たない。

検出ラベルの1行を解析
from libreyolo.data import parse_yolo_label_line # class_id cx cy w h を [0, 1] に正規化row = parse_yolo_label_line("0 0.5 0.5 0.25 0.5", 640, 480, num_classes=80) # ピクセル単位の (class_id, x1, y1, x2, y2, area)print(row)

detect

各行は正確に5フィールドです。

<class_id> <cx> <cy> <w> <h>

cx cy w hは正規化された軸平行ボックスで、whは正でなければなりません。

segment

ポリゴンの行は次の形式です。

<class_id> <x1> <y1> ... <xN> <yN>

Nは3以上、class_id後の座標数は偶数で、ポリゴンは非縮退でなければなりません。5フィールドの検出行も受け付けられ、長方形セグメントを表します。

pose

YAMLには必須のkpt_shapeを追加します。値は[K, 2]または[K, 3]です。任意のflip_idx0..K-1の整数順列です。

<class_id> <cx> <cy> <w> <h> <k1x> <k1y> [<k1v>] ... <kKx> <kKy> [<kKv>]

フィールド数は正確に5 + K * Dで、Dkpt_shapeの2番目の値です。キーポイント座標は正規化されます。存在する場合、可視性v012のいずれかです。

obb

正確に9フィールドです。

<class_id> <x1> <y1> <x2> <y2> <x3> <y3> <x4> <y4>

4つの点は[0, 1]内の正規化画像座標で、非縮退の回転長方形を形成します。ラベルファイルに角度は格納されません。

正規パーサーはデフォルトで厳密に動作し、範囲外の座標を拒否します。データセットと検証の取り込みでは、それ以外は有効なcrop境界のラベルについて座標を[0, 1]へクリップできますが、その後も縮退ボックスは拒否します。解析はタスクを考慮します。9フィールドはobbモードだけでobbを意味し、segmentモードでは4点ポリゴンとして扱われることがあります。

内部では正規化コーナーを正規xywhrへ変換し、角度はボックス中心を軸とする幅方向の回転をラジアンで表します。公開結果では、OBB検出をxywhr, conf, cls行として公開します。

ネイティブCOCO JSONのOBB読み込みは、次の優先順位でアノテーションを受け付けます。ピクセル空間の8コーナーとしてのobb、角度をラジアンとする[cx, cy, w, h, angle]としてのobb、最小面積長方形へ再フィッティングするCOCO segmentationポリゴンまたはRLE、軸平行として読み取り正規化するCOCO bboxです。

コーナーを考慮したOBBデータ拡張が存在するまで、OBB学習ではmosaicとmixupが無効です。

正規行パーサーはlibreyolo.data.parse_yolo_obb_label_lineです。

semantic

各画像は.txtファイルではなく、通常はPNGのロスレス形式の密な単一チャンネルマスクと対になります。

images/.../image.jpg -> <masks_dir>/.../image.png

マスクは単一チャンネルで、パレットモードPNGはパレットインデックスとして読み取られます。各ピクセル値は0..nc-1内のクラスIDで、ピクセル値255は無視を意味し、損失とメトリクスから除外されます。マスク解像度は画像解像度と一致する必要があります。

共通規約に2つの任意YAMLキーを追加できます。masks_dirは各画像パス内のimagesを置き換えるマスクディレクトリ名で、デフォルトはmasksです。label_mappingは読み込み時にマスクのピクセル値へ適用する{source_id: train_id}再マッピングです。マッピングされないソース値は無視となり、学習IDは0..nc-1内でなければなりません。

masks_dirを省略すると、imagesからlabelsへの規則で解決されるsegmentポリゴンラベルを読み込み時にラスタライズし、物体クラスの後にbackgroundクラスを追加するため、ncが1増えます。

正規ローダーはlibreyolo.data.SemanticDatasetです。

panoptic

LibreYOLOはCOCO-panoptic形式(Kirillovほか、CVPR 2019)をそのまま採用します。LibreYOLO固有のpanoptic形式はありません。

画像ごとに画像解像度のRGB PNGを1つ用意し、各ピクセルのセグメントIDを色でエンコードします。

segment_id = R + 256 * G + 256 * 256 * B

各ピクセルは正確に1つのセグメントに属し、セグメントは重なりません。セグメントID 0、RGBの黒はvoidです。ラベルなしのピクセルとしてメトリクスから除外されます。

json
{
  "images":      [{"id": 139, "file_name": "000000000139.jpg"}],
  "annotations": [{"image_id": 139, "file_name": "000000000139.png",
                   "segments_info": [
                     {"id": 3226956, "category_id": 1, "area": 2840,
                      "bbox": [413, 158, 53, 138], "iscrowd": 0}]}],
  "categories":  [{"id": 1, "name": "person", "isthing": 1, "supercategory": "person"}]
}

annotations[].file_namepanoptic_dir内のセグメントID PNGを示し、segments_info[].idはそのPNG内の値と一致します。iscrowdはグループ領域を示します。これらはfalse negativeにはならず、大部分を覆う予測も検出照合でfalse positiveにはなりません。

thingとstuffの区別はカテゴリごとの属性です。isthingcategoriesにあり、segments_infoにはありません。

COCO-panopticのcategory_id値はデータセットの未加工IDで、通常は連続していません。モデルは連続した0..nc-1を予測するため、未加工IDはカテゴリ名に基づいてYAMLのnamesを通じて再マッピングされます。これはネイティブCOCO JSON検出ローダーと同じ規則です。namesにないJSONカテゴリは暗黙に削除せず、エラーになります。そうしなければ常にfalse negativeとして評価されるためです。

yaml
path: coco
val: images/val2017
annotations:
  val: annotations/panoptic_val2017.json
panoptic_dir:
  val: annotations/panoptic_val2017
names: {0: person, 1: bicycle, 132: rug-merged}

annotationspanoptic_dirは単一パスまたはsplitごとのマッピングを受け付けます。

検証は正解データの解像度で計算し、出現するカテゴリで平均したPanoptic Qualityを報告し、さらにPQ_thingsPQ_stuffへ分けます。照合は一意です。同じカテゴリの予測セグメントと正解セグメントは、IoUが0.5を超えると一致します。

正規ローダーはlibreyolo.data.PanopticDatasetです。

depth

各画像は密な単一チャンネル深度マップと対になります。

images/.../image.jpg -> <depths_dir>/.../image.png

マップは画像解像度の単一チャンネルPNGまたはTIF、あるいは.npyファイルです。値はデータセット内で一貫した単位による通常の深度です。ゼロ、負、NaN、無限の値は無効ピクセルを示し、損失とメトリクスから除外されます。

キーデフォルト意味
depths_dirdepthsimagesを置き換える深度ディレクトリ
depth_stem_suffix画像stemに追加するサフィックス。省略時は同じstemと_depthサフィックスの両方を試行
depth_mask_suffix_mask有効性マスクのサフィックス。ゼロ以下、NaN、無限のマスク値は深度ピクセルを無効化
depth_scale256.0整数型深度マップの除数。一般的な16ビットPNG規約

浮動小数点の.npyマップはそのまま使われ、depth_scaleは適用されません。

正規ローダーはlibreyolo.data.DepthDatasetです。

edge

各RGB画像は同じstemの単一チャンネルロスレスマップと、任意の有効性マスクに対応します。

images/val/scene.jpg -> edges/val/scene.png
                     -> masks/val/scene.png

マップはRGB表示画像ではなく、画像解像度の単一チャンネルPNGまたはTIFです。整数マップはdtypeの最大値で除算され、浮動小数点マップはすでに有限で[0, 1]内でなければなりません。0は非エッジ、1はエッジを意味します。任意マスクではゼロでないピクセルが有効です。リサイズではターゲットとマスクにnearest-neighbor補間を使い、パディングされたピクセルは無効で検証に寄与しません。

キーデフォルト意味
edges_diredgesimagesを置き換えるエッジマップディレクトリ
edge_stem_suffix画像stemに追加するサフィックス
edge_extension.pngロスレスなターゲット拡張子
edge_invertソースマップが白地に黒いエッジを格納する場合にtrueを設定
masks_dirmasks任意の有効性マスクディレクトリ
yaml
path: edge-dataset
train: images/train
val: images/val
edges_dir: edges
masks_dir: masks
nc: 1
names: {0: edge}

検証は4方向の勾配NMSで連続予測を細線化し、設定可能なしきい値走査にわたるODSとOISのF値を報告します。予測ピクセルと正解ピクセルはedge_max_dist * image_diagonal内で1対1に照合され、デフォルトの正規化許容値は0.0075です。

正規ローダーはlibreyolo.data.EdgeDatasetです。ローダーは形式だけを扱い、ベンチマークデータをダウンロードまたは再配布しません。

normal

各画像は同じstemの3チャンネル16ビットPNGと、任意の同じstemの有効性マスクに対応します。

images/val/room.jpg -> normals/val/room.png
                    -> masks/val/room.png

PNGは画像解像度で、チャンネルをRGBとして格納した正確に3チャンネルのuint16です。n = png / 65535 * 2 - 1でデコードし、各ベクトルを再正規化します。デコード済みベクトルはOpenCVカメラ座標系を使い、+xは右、+yは下、+zはシーンの奥を向き、カメラに正対します。任意マスクは単一チャンネルPNGで、ゼロでない値が有効です。マスクがない場合、有限でゼロでないデコード済みベクトルがすべて有効です。無効またはパディングされたターゲットピクセルは、内部で(0, 0, 0)として表されます。リサイズでは3成分をbilinear補間してから再正規化し、有効性マスクにはnearest-neighbor補間を使います。水平反転ではx成分の符号も反転します。

キーデフォルト意味
normals_dirnormalsimagesを置き換える法線マップディレクトリ
masks_dirmasks任意の有効性マスクディレクトリ

検証は角度誤差の平均値と中央値(度)、および11.25度、22.5度、30度以内にある有効ピクセルの割合を報告します。

正規ローダーはlibreyolo.data.NormalDatasetです。

restore

各劣化入力画像はきれいなRGBターゲットと対になります。

inputs/.../image.jpg -> targets/.../image.jpg

入力とターゲットはRGB互換の画像ファイルで、解像度が正確に一致する必要があります。検証はネイティブ解像度を維持し、バッチに積み重ねるために必要な分だけパディングします。メトリクスは元画像のキャンバス上で計算されます。学習では入力とターゲットの組に連動したcropと水平反転を適用します。

キーデフォルト意味
input_dirinputssplitパスで使う劣化入力ディレクトリ
target_dirtargetsinput_dirを置き換えるきれいなターゲットディレクトリ
target_stem_suffixターゲット検索前に入力stemへ追加するサフィックス
target_stem_suffixestarget_stem_suffixのリスト形式
degradationdeblurdenoiseなどのメタデータラベル
datasetデータセットまたは出所ラベル

クラス相当のYAMLフィールドはスキーマのプレースホルダーです。nc: 1names: {0: image}を使ってください。復元モデルは検出ではなくResults.restoredを公開します。

正規ローダーはlibreyolo.data.RestoreDatasetです。

matte

各RGB画像は、同じstemを共有する単一チャンネルの正解matteと対になります。0が背景、255が前景です。

images/subject.jpg -> mattes/subject.png

2つの配置を受け付けます。1つ目はimages/とmatteディレクトリを含むディレクトリルートをdata=として渡す形式で、matteディレクトリはmattes/matte/gt/masks/mask/alpha/から自動検出されます。2つ目はpathとsplitごとのval_imagesval_mattes、任意のtrain_imagestrain_mattesを持つYAMLで、各値はpathからの相対パスまたは絶対パスです。

matteはグレースケールで[0, 1]内の不透明度として読み取られ、形状が異なる場合はbilinear補間で予測キャンバスへリサイズされます。メトリクスは元画像キャンバス上のMAEとS-measure(Fanほか、ICCV 2017)で、S-measureが最良チェックポイントの適合度です。

クラス相当のYAMLフィールドはスキーマのプレースホルダーです。nc: 1names: {0: matte}を使ってください。matteモデルはResults.matteを公開します。

このバージョンの検証は推論専用です。正規ペアリゾルバーはlibreyolo.data.matte_dataset.resolve_matte_pairsです。

ocr

ラベルはsplitごとに1つのJSONLファイルで、画像ごとに1つのJSONオブジェクトを記述します。

images/val/receipt.jpg -> labels/val.jsonl
json
{"image": "receipt.jpg", "regions": [{"polygon": [[10, 12], [118, 14], [117, 40], [9, 38]], "text": "TOTAL 12.50"}]}

polygonは絶対ピクセル座標の4点四角形で、左上、右上、右下、左下の順です。読み取れないテキストを含む領域では、ICDARの評価対象外規約である"text": "###"を使います。これらは認識評価から除外され、重なる予測も検出照合でペナルティを受けず無視されます。

メトリクスは、IoU 0.5を超える1対1ポリゴン照合による検出hmean、IoUが0.5を超え、NFKC正規化と空白除去後の転記テキストが大文字と小文字を区別して完全一致することを求めるエンドツーエンドF1、照合済みペアの1-NEDです。最良チェックポイントの適合度はエンドツーエンドF1です。

2つの配置を受け付けます。1つ目はimages/<split>/labels/<split>.jsonlを含むディレクトリルートをdata=として渡す形式です。2つ目はpathと任意のimagesおよびlabelsディレクトリ名を持つYAMLです。

クラス相当のYAMLフィールドはスキーマのプレースホルダーです。nc: 1names: {0: text}を使ってください。OCRモデルはResults.ocrを公開します。

このバージョンの検証は推論専用です。正規サンプルリゾルバーはlibreyolo.data.ocr_dataset.resolve_ocr_samplesです。

classify

ラベルファイルではなく、ImageFolder形式のディレクトリツリーを使います。

dataset_root/
  train/
    class_a/*.jpg
    class_b/*.jpg
  val/
    class_a/*.jpg
    class_b/*.jpg

学習にはtrain/が必要で、並べ替えたフォルダー名によりクラスからインデックスへのマッピングを定義します。検証にはval/が必要です。test/も置けますが、デフォルトの学習と検証コマンドは使用しません。学習以外のsplitは、想定される学習またはチェックポイントのクラス集合と同じクラスフォルダー名を含む必要があります。対応する画像拡張子はlibreyolo.data.classify_dataset.IMAGE_EXTENSIONSで定義されます。

gazeとpoint

gazeには学習または検証用データセットファイル規約が実装されていません。

pointはデータセットラベルスキーマではなくモデル出力タスクです。pointファミリーは、ボックス行から物体中心を導出するなど、既存ラベルを内部で適応させることがありますが、point専用のテキストラベル形式は定義されていません。

libreyoloリポジトリv1.5.0のdocs/dataset_schema.mdに対応し、ローダー名はlibreyolo/data/に照らして確認しました。