Files
photochk/docs/calibration.md
T

73 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# しきい値の実測記録
`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:)` と同じ設定であることを確認すること。