# 実機変更とシミュ側対応の整合マッピング (Device Setup Changes & Simulation-side Correspondence)

本ドキュメントは MiniTias 撮影アプリの定量モード導入に伴う **実機側撮影条件の変更**に対して，SmTIAS-LightSim 側で **どこを変える必要があったか／不要だったか** を網羅的にマッピングしたものである．Step 8-13 で残差 2.63× が判明した際に「シミュ側の対応漏れではないか」を切り分けるために整理した結果である．

## 結論（先に） (Conclusion First)

**実機側で 8 項目の設定変更を行ったが，シミュ側で実際に対応が必要だったのは「sm-evaluate の評価 config レベルでの OETF 無効化と mean アンカー調整」のみ**．他の 7 項目はシミュ側に対応物が存在しない（Mitsuba は物理量を直接計算するため）か，既に等価ドメインに到達している．

| 観点 | 結論 |
| --- | --- |
| **シミュ側対応漏れ** | **なし**（10 項目以上で網羅チェック済み） |
| **対応が必要だった項目** | **1 項目のみ**: ガンマ補正（OETF）→ Step C' で対応済 |
| **対応不要だった項目** | **7 項目**: AWB / AE / NR / EDGE / LSC / 黒レベル / ビット深度 |
| **Step 8-13 残差 2.63× の解釈** | ISP 関連の対応漏れではなく，**シミュ物理モデル誤差**が主因 |

## 背景・経緯 (Background)

実機側変更の経緯は別ドキュメントに記録済み：

| 段階 | 内容 | ドキュメント |
| --- | --- | --- |
| 1 | MiniTias アプリに定量撮影モード追加（PNG → DNG，ISP オート → マニュアル制御） | [TECH_01](TECH_01_定量撮影モード要求仕様.md) |
| 2 | MiniTias 側で実装完了．AQUOS sense3 は LEVEL_3 で全機能サポート | [TECH_03](TECH_03_定量モード実装報告とSHADING_MODE相談.md) |
| 3 | SHADING_MODE = HIGH_QUALITY 維持を決定 | [TECH_04](TECH_04_MiniTIASへの回答.md) |
| 4 | MiniTias-Evaluation 側で DNG 読み込み + LSC 順方向適用を実装 | [TECH_05](TECH_05_MiniTiasEvaluation_DNG対応要求仕様.md) / [TECH_06](TECH_06_MiniTias-Evaluation引き継ぎ受領.md) |
| 5 | LSC 取り扱いの設計判断を明文化 | [TECH_07](TECH_07_LSC取り扱い方針.md) |
| **6** | **実機側変更全般に対するシミュ側対応の整合確認（本ドキュメント）** | TECH_08（本ファイル） |

## 実機側 8 項目の変更一覧 (Device-Side Changes)

MiniTias 定量撮影モードで実機側に施した設定変更：

| # | 設定 | 過去（通常モード） | 新規（定量モード） | 目的 |
| --- | --- | --- | --- | --- |
| 1 | **画像フォーマット** | PNG (8-bit sRGB) | DNG (10-bit RAW_SENSOR linear) | 量子化誤差・ガンマ非線形性の排除 |
| 2 | **AWB**（自動 WB） | ON | OFF（gains=[1,1,1,1], identity matrix） | 色温度ドリフトの排除 |
| 3 | **AE**（自動露光） | ON | OFF（露光 1/60s 固定，ISO 40 固定） | 撮影ごとの露光変動の排除 |
| 4 | **ガンマ補正** | sRGB OETF 適用 | CONTRAST_CURVE 線形（OETF なし） | 入射光量との比例性確保 |
| 5 | **NR**（ノイズ削減） | デフォルト（多分 FAST） | OFF | アーティファクト排除 |
| 6 | **EDGE**（エッジ強調） | デフォルト（多分 FAST） | OFF | 偽エッジ排除 |
| 7 | **LSC**（レンズシェーディング補正） | デフォルト | HIGH_QUALITY 維持 + lscMap 取得 | 後段で順方向適用するため取得 |
| 8 | **LSC 順方向適用** | （ISP 内で完結） | MiniTias-Evaluation 側で適用 | レンズビネット除去 → 照明ムラのみ評価 |

→ 撮影段階 (#1〜#7) + 評価段階 (#8) の合計 8 項目．詳細は各 TECH ドキュメント参照．

## シミュ側の「3 層」構造 (Simulation 3-Layer Structure)

シミュ側を 3 層に分けると，各層がどの実機側変更に対応するかが明確になる：

| 層 | 場所 | 役割 | 物理的意味 |
| --- | --- | --- | --- |
| **(α) Mitsuba シーン定義** | `configs/scene_*.yaml`, `src/sm_tias_lightsim/scene/` | シーン構築・光線追跡 | 物理量 (放射輝度 L, W/m²/sr) を計算 |
| **(β) sm-render CLI** | `src/sm_tias_lightsim/cli/render.py` | Mitsuba 実行 + luminance.npy 出力 | 物理量を float32 配列として保存 |
| **(γ) sm-evaluate CLI** | `src/sm_tias_lightsim/cli/evaluate.py` + `configs/eval_*.yaml` | 評価指標算出 + ドメイン整合 | 実機との比較ドメインを合わせる |

## 対応マッピング表 (Correspondence Table)

実機側 8 項目に対して，シミュ側 3 層 (α/β/γ) で何をしたかを網羅：

| # | 実機側変更 | (α) シーン定義 | (β) sm-render | (γ) sm-evaluate | 状態 |
| --- | --- | --- | --- | --- | --- |
| 1 | PNG → DNG（量子化） | 概念なし | float32 出力（量子化なし） | DNG 直接読みは MiniTias-Evaluation の責務 | **対応不要** |
| 2 | AWB OFF | per-channel 独立計算（AWB 概念なし） | — | — | **対応不要** |
| 3 | AE OFF | 露光時間概念なし | — | **mean アンカーで実機 mean=207.82 にスケール調整**（既存 normalization 機能で対応） | **対応済 (γ)** |
| 4 | **ガンマ補正なし** | linear radiance を計算 | linear のまま保存 | **OETF セクションを config に書かない**（[Step C'](#step-c-での対応) で対応） | **対応済 (γ)** |
| 5 | NR OFF | NR をかけない | — | — | **対応不要** |
| 6 | EDGE OFF | エッジ強調しない | — | — | **対応不要** |
| 7 | LSC HIGH_QUALITY 維持 | orthographic で cos⁴ falloff を持たない（[TECH_07](TECH_07_LSC取り扱い方針.md) §物理的根拠 参照） | — | — | **対応不要**（構造的に等価） |
| 8 | LSC 順方向適用（実機側で実施） | — | — | — | **対応不要**（実機側で完結） |

→ シミュ側で実際に対応した項目は **#3 と #4 のみ**．いずれも **sm-evaluate の config レベル**で完結．Mitsuba シーン定義 (α) も sm-render (β) も **無変更**．

## 各項目の詳細解説 (Per-Item Details)

### #1 PNG → DNG (量子化・ビット深度)

**実機**: PNG (8-bit sRGB, 0-255) → DNG (10-bit linear, 0-1023, 黒レベル 64 で実効 0-959)
**シミュ**: Mitsuba は float32 で放射輝度 L (W/m²/sr) を出力．量子化なし．
**理由**: Mitsuba の物理計算は連続値．量子化はそもそも持ち込まないので「対応不要」．

> なお，DNG の直接読み込みは MiniTias-Evaluation の責務（[TECH_07](TECH_07_LSC取り扱い方針.md) §役割分担 参照）．sm-evaluate にも `dng_loader.py` をコピーで持っているが（S2 で実装），これは将来の検証用ツールであり，本流評価では使わない．

### #2 AWB OFF

**実機**: gains=[1,1,1,1] + identity color matrix．ISP の AWB 補正を無効化．
**シミュ**: Mitsuba の `path` integrator は per-channel 独立で物理量を計算．R/G/B チャネル間の混合はそもそも行わない．AWB の概念がない．
**理由**: シミュは最初から「AWB OFF 相当」．「対応不要」．

### #3 AE OFF（露光時間 / ISO 固定）

**実機**: 露光時間 1/60s + ISO 40 固定．mean = 207.82（白板撮影）．
**シミュ**: Mitsuba は露光時間の概念を持たない．物理量 (W/m²/sr) を直接出力．絶対値スケールは実機と直接比較できない．
**対応**: `evaluation/normalize.py` の `apply_mean_anchor()` で mean アンカー正規化．`configs/eval_baseline_dng_target.yaml` で `normalization.target_mean: 207.82` を指定．**線形ゲインなので形状指標 (CoV/勾配/中心-周辺/動径 min/max) は厳密に不変**．→ **(γ) で対応済**．

> 既存 `evaluation/normalize.py` は Step 8-8 で実装済み．新規 config で値を 207.82 に設定するだけで対応完了．

### #4 ガンマ補正なし（最重要対応項目） {#step-c-での対応}

**実機**: TONEMAP_MODE = CONTRAST_CURVE 線形．sRGB OETF (γ ≈ 2.2) を適用しない．画像値は入射光量に比例 (linear)．
**シミュ**: Mitsuba は元から linear radiance を出力．

**過去の問題（Step 8-3 当時）**: 実機 PNG が sRGB ドメイン，シミュが linear ドメインで **ドメイン不一致**．これを揃えるため sm-evaluate に **OETF 順方向適用ステップ**を追加した（`evaluation/oetf.py`）．

**現在の対応**: 実機 DNG が linear になった今，シミュ側でも OETF を適用すると逆にドメイン不一致になる．したがって **OETF を sm-evaluate で適用しない**よう新規 config を作成．具体的には `configs/eval_baseline_dng_target.yaml` で `oetf:` セクションを **意図的に書かない**（既定で無効）．

| Config | OETF | 用途 |
| --- | --- | --- |
| `configs/eval_baseline.yaml` | **有効** (`oetf.enabled: true`) | 過去 Step 8-1〜8-7 の sRGB 比較用（歴史的設定として保持） |
| `configs/eval_baseline_linear.yaml` | 無効 | Step 8-8〜8-12 の linear 比較用（target_mean=146.71） |
| **`configs/eval_baseline_dng_target.yaml`** | **無効** | **Step 8-13 以降の新方針（target_mean=207.82）** |
| `configs/eval_real.yaml` | 無効 | 実機 PNG 評価用（過去再現） |

→ **(γ) で対応済**．既存 OETF 機能は無効にして使うだけ．コード変更なし．

### #5 NR OFF

**実機**: Camera2 API の NOISE_REDUCTION_MODE = OFF．センサ raw に近い値を保持．
**シミュ**: Mitsuba の path tracer は物理計算のみで NR をかけない．
**理由**: シミュは最初から「NR OFF 相当」．「対応不要」．

### #6 EDGE OFF

**実機**: Camera2 API の EDGE_MODE = OFF．エッジ強調による偽の高周波成分を排除．
**シミュ**: Mitsuba はエッジ強調しない．
**理由**: 「対応不要」．

### #7 LSC HIGH_QUALITY 維持

**実機**: SHADING_MODE = HIGH_QUALITY（ISP の LSC 補正が有効）．ただし DNG (RAW_SENSOR) は LSC 未補正で出力され，lscMap が meta.json に保存される．
**シミュ**: Mitsuba orthographic sensor は全画素平行光線で，物理 cos⁴ falloff を **そもそも持たない**．「ISP が完璧に LSC 補正できた場合の理想値」と構造的に等価．

詳細は [TECH_07](TECH_07_LSC取り扱い方針.md) §物理的根拠 参照．**対応不要**（構造的に等価）．

### #8 LSC 順方向適用（実機側で実施）

**実機側 (MiniTias-Evaluation)**: DNG 読み込み後に lscMap を画像解像度にバイリニア補間して順方向乗算．レンズビネット除去．
**シミュ**: 上記 #7 の通り，シミュは cos⁴ falloff を持たないので適用不要．
**理由**: 実機側で完結．「対応不要」．

## 追加チェック項目 (Additional Items)

念のため，議論に出ていない実機側設定でもシミュ側影響を確認した：

| 実機側設定 | シミュ側影響 | 対応要否 |
| --- | --- | --- |
| CONTROL_MODE: OFF（マニュアル全制御） | Mitsuba は ISP 概念なし | **不要** |
| SENSOR_FRAME_DURATION: 30fps 相当 | Mitsuba はフレームレート概念なし | **不要** |
| BLACK_LEVEL_LOCK: true | DNG 読み込み時に黒レベル除去（rawpy が自動） | **不要**（読み込み側で対応） |
| COLOR_CORRECTION_GAINS: [1,1,1,1] | per-channel 独立計算 | **不要** |
| COLOR_CORRECTION_TRANSFORM: identity | 同上 | **不要** |
| CONTROL_AF_MODE: OFF（固定焦点） | Mitsuba orthographic は焦点概念なし（無限遠相当） | **不要** |
| CONTROL_VIDEO_STABILIZATION_MODE: OFF | シミュに振動概念なし | **不要** |

→ **追加で 7 項目チェックしたが，すべて対応不要**．計 15 項目以上で網羅チェック済み．

## 動作確認の根拠 (Verification Evidence)

Step C' 完了時の動作確認（`uv run sm-evaluate --image output/baseline/luminance.npy --config configs/eval_baseline_dng_target.yaml`）で以下を確認：

| 確認項目 | 結果 |
| --- | --- |
| 新 config が正しく読み込まれる | ✓ |
| mean アンカー正規化が動作（`alpha=1.36257`, シミュ mean を 152.52 → 207.82 に揃え） | ✓ |
| OETF が適用されない（linear のまま） | ✓（コンソール出力に OETF 関連メッセージなし） |
| 動径 min/max 比が出力される | ✓（`radial min/max : 0.6151`） |
| 既存 569 + 新規 39 = 608 テスト全通過 | ✓（Step D 完了時に確認済） |

→ シミュ側 (γ) の対応が **正常動作**することを確認．

## Step 8-13 残差 2.63× の解釈（再確認） (Residual 2.63× Interpretation)

実機側 8 項目の変更に **すべて整合させた上で** Step 8-13 を計測した結果：

| 指標 | 実機 (DNG+LSC) | シミュ (Step 8-13) | 残差 |
| --- | --- | --- | --- |
| CoV | 0.0695 | 0.1826 | **2.63×** |
| 勾配 % | 8.35 | 24.65 | 2.95× |
| 中心/周辺 | 1.091 | 1.327 | 絶対差 0.236 |
| 動径 min/max | 0.860 | 0.615 | 絶対差 0.245 |

この残差は **以下のいずれでもない**：

| 残差候補 | 解消状況 |
| --- | --- |
| ガンマ補正のズレ | ✓ 解消済（両者 linear） |
| AWB のズレ | ✓ 解消済（実機 identity, シミュ per-channel 独立） |
| AE のズレ（絶対値スケール） | ✓ 解消済（mean アンカーで揃え） |
| NR/EDGE のアーティファクト | ✓ 解消済（実機 OFF） |
| LSC のズレ | ✓ 解消済（実機側で順方向適用） |
| ガンマ圧縮による過小評価 | ✓ 解消済（DNG linear で正直な値） |

→ **残差 2.63× は ISP 関連の対応漏れではなく，シミュ側の物理モデル誤差**が主因と推定．候補：

| 物理モデル要素 | 想定される影響 |
| --- | --- |
| 反射率の精度（現状 R=0.85） | 多重反射量の精度 → 形状指標に直接影響 |
| LED 配光モデル（現状 Lambertian） | 評価板への直接照射パターン → 中心/周辺比に影響 |
| メッシュ幾何精度（mm 精度） | 多重反射経路の集積 → 全体的なムラ |
| LED 位置の精度 | 過去 Step 8-9 で Fusion 360 STL から抽出済（ほぼ十分） |
| その他（センサ位置・FOV 等） | 過去 Step 8 で網羅試行済（影響軽微） |

詳細な切り分けは別タスク（Step 8-14 以降の物理モデル精緻化）として残す．

## 関連ドキュメント (Related Documents)

### TECH 系（設計判断）

- [TECH_01 定量撮影モード要求仕様](TECH_01_定量撮影モード要求仕様.md) — 実機側 8 項目変更の要求書
- [TECH_03 定量モード実装報告と SHADING_MODE 相談](TECH_03_定量モード実装報告とSHADING_MODE相談.md) — MiniTias 側実装報告
- [TECH_04 MiniTIAS への回答](TECH_04_MiniTIASへの回答.md) — SHADING_MODE 判断
- [TECH_05 MiniTias-Evaluation DNG 対応要求仕様](TECH_05_MiniTiasEvaluation_DNG対応要求仕様.md) — Evaluation 側 DNG 対応
- [TECH_06 MiniTias-Evaluation 引き継ぎ受領](TECH_06_MiniTias-Evaluation引き継ぎ受領.md) — DNG ローダ受領．LSC 順方向適用判明
- [TECH_07 LSC 取り扱い方針](TECH_07_LSC取り扱い方針.md) — LSC の設計判断詳細

### TEST 系（試行検証）

- [TEST_01 キャリブレーション検証履歴](../06_TEST/TEST_01_キャリブレーション検証履歴.md) — Step 8-1〜8-12 全イテレーション．Step 8-13 で本ドキュメントの内容を反映
- [TEST_03 輝度マップ形状追跡](../06_TEST/TEST_03_輝度マップ形状追跡.md) — 「形のずれ」議論．finding 4 の前提変更
- [TEST_05 PNG/DNG 評価比較](../06_TEST/TEST_05_PNG_DNG評価比較.md) — ガンマ補正の影響を数値実証
- [TEST_06 外乱光影響評価](../06_TEST/TEST_06_外乱光影響評価.md) — 外乱光ロバスト性

### SPEC 系（仕様）

- [SPEC_04 評価仕様](../04_SPEC/SPEC_04_評価仕様.md) — sm-evaluate パイプライン．OETF / normalization の正規仕様
