fullseye は inspection_dataset / optscene_instances / optscene_defect_mask で
画素完全な真値を吐ける。だが真値は、学習フレームワークが読める形に変換して初めて
使える。この文書は op の説明ではなく、その受け皿側 —— 座標規約・面積の定義・
評価指標の癖・分割の作り方 —— を書く教材である。
optics/guides/mv_*.md(2-D 撮像系)、3d/guides/depth_sensors.md(3-D 撮像系)と
同じ位置づけで、こちらは出口にあたる。
ここが事故の 8 割。同じ矩形が 4 通りの数字で書ける。
| 形式 | 並び | 原点 | 単位 |
|---|---|---|---|
| COCO | [x, y, width, height] |
左上、0 始まり | 絶対 px |
| YOLO(Ultralytics) | class x_center y_center width height |
左上、0 始まり | 画像幅・高さで正規化(0–1) |
| Pascal VOC(XML) | xmin ymin xmax ymax |
左上 | 絶対 px、1 始まりとして扱うのが通例(MATLAB 由来)。変換コードによって −1 する / しないが割れているので、他人のスクリプトを信じない |
fullseye optscene_instances |
(x0, y0, x1, y1) |
左上、0 始まり | 絶対 px、右下を含む(inclusive) |
optscene_instances の bbox は右下を含むので、幅は x1 − x0 ではなく
x1 − x0 + 1 である。変換式:
w = x1 - x0 + 1
h = y1 - y0 + 1
coco = [x0, y0, w, h] # 絶対 px
yolo = [(x0 + w / 2) / W, (y0 + h / 2) / H, w / W, h / H] # 0-1 正規化
1 画素の取り違えは小さな欠陥ほど致命的になる(§4)。
bbox は絶対座標の (x, y, width, height) ——
detectron2 の BoxMode.XYWH_ABS がこれにあたる(対して XYXY_ABS は (x1,y1,x2,y2))。segmentation は 3 形態を取り、pycocotools はこれを見分けて処理する:
list)—— 連結成分ごとに [x1, y1, ..., xn, yn]counts が list の dict){"size": [h, w], "counts": ...}、LEB128 可変長)pycocotools.mask の仕様がそう決めている。
numpy の既定は行優先なので、np.asarray(mask, order="F") を忘れると
転置でも反転でもない、意味不明な形に崩れる。これは静かに壊れるので気づきにくい。M=[0 0 1 1 1 0 1]
→ counts=[2 3 1 1])。先頭が 1 で始まるマスクは counts が 0 から始まる。area は マスク(またはポリゴン)の面積であって bbox の面積ではない。
細長い傷では bbox 面積の数分の一になる。§3 の small/medium/large 判定はこの
area を使うので、ここを bbox 面積で埋めると評価が別物になる。iscrowd=1 は「群れとして 1 つ」を意味し、評価時に当たっても外れても罰しない
特別扱いを受ける。意味が分からないなら付けない(detectron2 の助言もそうなっている)。category_id は [0, num_categories-1](detectron2 の規約)。COCO 公式データ自体は
1 始まりで欠番もあるので、素の COCO をそのまま添字にすると 1 つずれる。mAP を鵜呑みにしない)pycocotools の既定値(cocoeval.Params):
| パラメータ | 値 |
|---|---|
| IoU 閾値 | 0.50, 0.55, ..., 0.95(10 段) |
| Recall 閾値 | 0.00 … 1.00(101 段) |
| 面積区分 | all = [0, 1e10] / small = area < 32² = 1024 px² / medium = 32²–96² / large > 96² |
| maxDets | 1, 10, 100 |
外観検査でここが効く:
small の閾値 1024 px² は絶対値である。32×32 px 未満はすべて small に落ちる。
検査系の微小欠陥はほぼ全部ここに入るので、報告するなら AP_small を見ないと意味がない。maxDets=100 —— 1 枚に 100 個を超える欠陥(粉状の異物、打痕の群れ)があると、
それだけで recall の上限が切られる。粒を数える用途では既定のままでは測れない。IoU 0.5 が小物体では厳しすぎる。 同じ絶対誤差でも小さい箱ほど IoU が崩れる:
| 箱の大きさ | 1 px ずれ | 2 px | 3 px | 4 px |
|---|---|---|---|---|
| 10 × 10 px | 0.82 | 0.67 | 0.54 | 0.43(不合格) |
| 100 × 100 px | 0.98 | 0.96 | 0.94 | 0.92 |
10 px の欠陥は 4 px ずれただけで「検出漏れ」に数えられる。位置精度の問題が 検出率の問題に化けるので、微小欠陥では IoU 閾値を下げるか、中心距離や 画素 IoU(segm)で測るほうが実態に合う。指標を変えずに「検出率が低い」と 結論づけない。
inspection_dataset の seed と
欠陥ラベルでグループを作り、グループ単位で分割する(画像単位で分けない)。meta を捨てない。 inspection_dataset は照明種別・露光・ゆらぎ量・欠陥ラベルを
meta に返す。これは学習には要らないが、失敗の切り分けには要る
(「暗視野のときだけ落ちる」は meta が無いと分からない)。| 欲しいもの | fullseye の出どころ | 変換 |
|---|---|---|
| 画像 | inspection_dataset(...)["image"] |
そのまま(量子化済み) |
| bbox | optscene_instances(...)["bbox"](inclusive) |
§1 の式で COCO / YOLO へ |
| クラス | 同 ["kind"] |
category_id に写す。0 始まりに揃える |
| インスタンスマスク | 同 ["mask"](H×W bool) |
RLE 化は列優先で(§2) |
| 面積 | 同 ["area_px"] |
COCO の area に入れる(bbox 面積ではない) |
| 意味的マスク | optscene_defect_mask |
セグメンテーション学習用 |
| 深度真値 | inspection_dataset(...)["depth_mm"] |
単位 mm。スケールを一緒に運ぶ |
| 再現情報 | 同 ["meta"] |
データセットの info / 独自フィールドに残す |
| 症状 | まず疑う | 確かめ方 |
|---|---|---|
| 良品を一枚も学習していない気配 | 空アノテーションの画像がローダで落ちている | 学習ログの枚数と生成枚数を突き合わせる |
| 画素 accuracy 99.99% なのに何も出ない | クラス不均衡 | 欠陥画素の再現率と誤検出数を別々に出す |
| val の成績が良すぎる | 分割の漏れ(同じ seed・同じ欠陥配置が両側にいる) | seed と欠陥ラベルでグループを作り、グループ単位で分け直して再学習 |
| 小さい欠陥だけ AP が低い | IoU 0.5 が小箱に厳しい(§3 の表) | 中心距離、または画素 IoU(segm)で測り直す |
| 箱が全部 1 px ずれている/全滅する | inclusive と exclusive の取り違え、VOC の 1 始まり | 変換後の bbox を画像に描いて目で確認する(数字だけ見ない) |
| マスクが意味不明な形に崩れる | RLE を行優先で作った | order="F" で作り直す(§2) |
| 1 枚に大量の欠陥があると再現率が頭打ち | maxDets=100 |
maxDets を上げて再評価 |
| 合成では良いのに実データで誤検出だらけ | ラベルの質の差(真値が完璧すぎる) | 実データの GT を数枚引き直し、境界の揺れ幅を測って合成側に反映する |
| クラス番号が 1 つずれる | COCO 素データの category_id は 1 始まり・欠番あり |
カテゴリ一覧を出力し、連番に写す辞書を明示的に作る |
pycocotools/mask.py module docstring(RLE の定義、列優先、encode/decode/merge/area/toBbox/iou/frPyObjects) — https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/mask.pypycocotools/cocoeval.py Params(iouThrs / recThrs / areaRng / areaRngLbl / maxDets、iscrowd の特別扱い) — https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/cocoeval.pypycocotools/coco.py annToRLE(segmentation の 3 形態の判定) — https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/coco.pyBoxMode.XYWH_ABS / XYXY_ABS、segmentation の polygon と圧縮 RLE、category_id は 0 始まり、iscrowd の助言) — https://detectron2.readthedocs.io/en/latest/tutorials/datasets.html