From 78150438aa63d006c7cf0a1e328d88003badf0cc Mon Sep 17 00:00:00 2001 From: yoshikazu Date: Mon, 27 Jul 2026 15:47:33 +0000 Subject: [PATCH] Add threshold calibration record --- docs/calibration.md | 72 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/calibration.md diff --git a/docs/calibration.md b/docs/calibration.md new file mode 100644 index 0000000..35d8111 --- /dev/null +++ b/docs/calibration.md @@ -0,0 +1,72 @@ +# しきい値の実測記録 + +`Sensitivity` のしきい値は当てずっぽうではなく、実写画像で距離を測って決めている。 +判定を変えたくなったらこの手順をなぞって測り直すこと。 + +## 測定に使った素材 + +macOS 内蔵の動画壁紙(実写のタイムラプス)からフレームを切り出したものを元画像とした。 + +| ファイル | 内容 | +|---|---| +| `shotA.jpg` | 元画像(1600×900, JPEG) | +| `A_copy.jpg` | `cp` によるバイト単位の完全コピー | +| `A_half.jpg` | 50% に縮小 | +| `A_quarter.jpg` | 25% に縮小 | +| `A_lowq.jpg` | 同じ寸法で JPEG 品質 25 に再圧縮 | +| `A_crop.jpg` | 中央 1400×900 にトリミング | +| `A_rot90.jpg` | ピクセルごと 90 度回転 | +| `shotA_burst.jpg` | 0.5 秒後のフレーム(連写相当) | +| `shotB.jpg` / `shotC.jpg` | 30 秒後 / 90 秒後のフレーム(同一シーンの別カット) | +| `sonoma.jpg` | まったく別の写真 | + +## 測定結果(Vision の feature print 距離 / dHash のハミング距離) + +`shotA.jpg` を基準にした値。 + +| 相手 | feature print | ハミング | 判定したい? | +|---|---|---|---| +| 完全コピー・再エンコード | 0.000 | 0 | ○(SHA-256 で先に確定) | +| 50% 縮小 | 0.049 | 5 | ○ | +| 低画質 再圧縮 | 0.116 | 1 | ○ | +| 25% 縮小 | 0.162 | 4 | ○ | +| 連写(0.5 秒差) | 0.008 | 0 | ○ | +| 同一シーン 30 秒差 | 0.017 | 6 | ○ | +| 同一シーン 90 秒差 | 0.039 | 14 | ○ | +| トリミング | 0.417 | 11 | 「ゆるい」でのみ | +| 90 度回転 | 0.802 | 28 | ✗(後述) | +| 無関係な写真 | 1.378 | 24 | ✗ | + +## 決めたしきい値 + +| 段階 | feature print | ハミング | 何が拾えるか | +|---|---|---|---| +| 厳しい | 0.20 | 8 | コピー・縮小(25% まで)・再圧縮 | +| 標準 | 0.30 | 12 | 上記+連写・同一シーンの近いカット | +| ゆるい | 0.55 | 20 | 上記+トリミングされた版 | + +「ゆるい」の 0.55 でも無関係な写真の 1.38 とは大きく離れているので、誤検出の余地は小さい。 +当初案の「厳しい = 0.15」では 25% 縮小(0.162)を取りこぼしたため 0.20 に上げた。 + +## 回転の扱い(意図的な仕様) + +dHash も Vision も EXIF の向きを反映してから比較している。つまり **「画面に表示したときの見た目」どうしを比べている**。 + +- 回転がピクセルに焼き込まれた版と、EXIF の向きタグで回している版 → **距離 0.002 で検出できる** + (LINE や AirDrop を経由して向きが焼き込まれた、という現実的なケース) +- 実際に向きが違う写真どうし(元画像 vs 90 度回転) → **距離 0.80 で検出しない** + +後者を拾うには4方向ぶんの特徴量を計算する必要があり、コストが4倍になる割に +写真整理の用途では出番が少ないため、対応していない。 + +## 測り直す手順 + +```bash +ffmpeg -ss 0 -i "/System/Library/Desktop Pictures/.wallpapers/Tahoe Day/Tahoe Day.mov" -frames:v 1 -vf scale=1600:-1 shotA.jpg +sips -Z 800 shotA.jpg --out A_half.jpg +sips -s format jpeg -s formatOptions 25 shotA.jpg --out A_lowq.jpg +sips -c 900 1400 shotA.jpg --out A_crop.jpg +``` + +これらを1つのフォルダに置き、`GenerateImageFeaturePrintRequest`(`cropAndScaleAction = .scaleToFit`)で +総当たりの距離行列を出す。アプリ本体の `FeaturePrinter.compute(for:)` と同じ設定であることを確認すること。