diff --git a/CLAUDE.md b/CLAUDE.md index fdf20ff..5173ceb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -77,10 +77,7 @@ ### 05_TECH(技術設計・外部要求仕様) -- 定量撮影モード要求仕様(SmTIAS-LightSim 側からの外部要求): docs/05_TECH/TECH_01_定量撮影モード要求仕様.md -- MiniTIAS 引き継ぎ手順(SmTIAS-LightSim 側からのハンドオフ手順): docs/05_TECH/TECH_02_MiniTIAS引き継ぎ手順.md -- 定量モード実装報告と SHADING_MODE 相談(MiniTIAS → SmTIAS-LightSim): docs/05_TECH/TECH_03_定量モード実装報告とSHADING_MODE相談.md -- 上記への回答(SmTIAS-LightSim → MiniTIAS): docs/05_TECH/TECH_04_MiniTIASへの回答.md +- 定量モード設計の経緯と合意(旧 TECH_01/03/04 の往復書簡を統合・要約.現行確定仕様は SPEC_01 参照): docs/05_TECH/TECH_01_定量モード設計の経緯と合意.md ### 06_TEST(テスト・実機検証) diff --git a/README.md b/README.md index 292a1a7..3ee47bc 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ - [要件定義書](docs/03_PLAN/PLAN_01_要件定義書.md) - [開発ステップ](docs/03_PLAN/PLAN_02_開発ステップ.md) - [画面機能仕様書](docs/04_SPEC/SPEC_01_画面機能仕様書.md) -- [定量撮影モード要求仕様(外部要求)](docs/05_TECH/TECH_01_定量撮影モード要求仕様.md) +- [定量モード設計の経緯と合意](docs/05_TECH/TECH_01_定量モード設計の経緯と合意.md) - [開発進捗ログ](docs/PROGRESS.md) - [Git 運用ルール](docs/01_GUIDE/GUIDE_04_Git運用ルール.md) - [コーディング規約](docs/01_GUIDE/GUIDE_06_コーディング規約.md) diff --git "a/docs/04_SPEC/SPEC_01_\347\224\273\351\235\242\346\251\237\350\203\275\344\273\225\346\247\230\346\233\270.md" "b/docs/04_SPEC/SPEC_01_\347\224\273\351\235\242\346\251\237\350\203\275\344\273\225\346\247\230\346\233\270.md" index 0c6931d..5d64ede 100644 --- "a/docs/04_SPEC/SPEC_01_\347\224\273\351\235\242\346\251\237\350\203\275\344\273\225\346\247\230\346\233\270.md" +++ "b/docs/04_SPEC/SPEC_01_\347\224\273\351\235\242\346\251\237\350\203\275\344\273\225\346\247\230\346\233\270.md" @@ -152,7 +152,7 @@ | 画像フォーマット | `RAW_SENSOR`(10-bit BGGR Bayer).`DngCreator` で DNG ファイル出力 | | `CONTROL_MODE` | OFF(マニュアル全制御) | | `CONTROL_AE_MODE` | OFF | -| `SENSOR_EXPOSURE_TIME` | 8,333,333 ns(1/120 s)固定(アタッチメント + LED 環境で線形領域中央狙い.TECH_04 目標 mean G = 400〜600 達成済み) | +| `SENSOR_EXPOSURE_TIME` | 8,333,333 ns(1/120 s)固定(アタッチメント + LED 環境で線形領域中央狙い.定量モード合意の目標 mean G = 400〜600 達成済み.05_TECH 参照) | | `SENSOR_SENSITIVITY` | 40(センサ最低 ISO)固定 | | `SENSOR_FRAME_DURATION` | 33,333,333 ns(30fps 相当) | | `BLACK_LEVEL_LOCK` | true | diff --git "a/docs/05_TECH/TECH_01_\345\256\232\351\207\217\343\203\242\343\203\274\343\203\211\350\250\255\350\250\210\343\201\256\347\265\214\347\267\257\343\201\250\345\220\210\346\204\217.md" "b/docs/05_TECH/TECH_01_\345\256\232\351\207\217\343\203\242\343\203\274\343\203\211\350\250\255\350\250\210\343\201\256\347\265\214\347\267\257\343\201\250\345\220\210\346\204\217.md" new file mode 100644 index 0000000..deec804 --- /dev/null +++ "b/docs/05_TECH/TECH_01_\345\256\232\351\207\217\343\203\242\343\203\274\343\203\211\350\250\255\350\250\210\343\201\256\347\265\214\347\267\257\343\201\250\345\220\210\346\204\217.md" @@ -0,0 +1,78 @@ +# 定量モード 設計の経緯と合意 (Quantitative Mode: Rationale & Agreements) + +本書は SmTIAS-LightSim 側と MiniTIAS 側の**往復書簡(旧 TECH_01 要求仕様 / TECH_03 実装報告・相談 / TECH_04 回答)を統合・要約したアーカイブ**である.定量撮影モードがなぜ・どう決まったかの記録に絞る. + +- **現行の確定仕様** → [SPEC_01 画面機能仕様書](../04_SPEC/SPEC_01_画面機能仕様書.md) +- **実装の経緯・設計判断・失敗パターン** → [PROGRESS.md](../PROGRESS.md) +- **実機能力の生データ** → [camera_diagnostics_20260531_161734.json](../06_TEST/camera_diagnostics_20260531_161734.json) + +> 原文の往復書簡(詳細な検証履歴 TEST_01/03、評価仕様 SPEC_03/04 等への参照を含む)は SmTIAS-LightSim リポジトリ側に残る.本リポジトリには当該ファイルは存在しない. + +## 背景:なぜ定量モードが必要だったか + +SmTIAS-LightSim(Mitsuba 3 による光散乱シミュ)と実機撮影を定量比較する研究で、シミュ vs 実機の残差が縮まらなかった。原因は、MiniTIAS の通常撮影(PNG)が **AE/AWB/NR/EDGE/TONEMAP すべて自動**で、同じシーンを撮っても値が揺らいでいたこと。つまり「比較対象の実機データ自体が定量的に不安定」だった。 + +→ Camera2 API を**完全マニュアル制御**し、ISP 介入を排した **RAW(DNG)**で撮影するモードを追加して固定化する、という方針になった。 + +## 実機能力(AQUOS sense3 / SH-02M フロントカメラ) + +実機診断(`getCameraDiagnostics`)の結果、定量モードに必要な能力をすべて満たすことを確認: + +| 項目 | 値 | +|---|---| +| ハードウェアレベル | **LEVEL_3**(最上位) | +| 能力 | MANUAL_SENSOR / MANUAL_POST_PROCESSING / **RAW** 対応 | +| RAW 出力 | 3264×2448、BGGR、10-bit(white level 1023 / black level 64) | +| 露光時間レンジ | 約 1/12530 s 〜 0.87 s | +| ISO レンジ | 40〜2506 | +| AF | **OFF のみ**(固定焦点。近接ピントはアタッチメント光学系前提) | +| LSC マップサイズ | 13×17(実キャプチャ結果から判明) | + +詳細は camera_diagnostics JSON を参照。 + +## 確定した撮影設定(要点) + +全パラメータは [SPEC_01 §撮影設定](../04_SPEC/SPEC_01_画面機能仕様書.md) に記載。要点のみ: + +- `CONTROL_MODE=OFF` で AE/AWB/AF/NR/EDGE をすべて OFF、TONEMAP は線形 +- 露光 **1/120s**・ISO **40** 固定、`BLACK_LEVEL_LOCK=true` +- フォーマットは **RAW_SENSOR → `DngCreator` で DNG 出力** +- 設定反映を確実にするため **3 枚連続キャプチャして最初の 2 枚を破棄**、3 枚目を採用 +- 撮影モード切替トグル UI は採用せず、**定量モードを既定動作**とした(通常 PNG 経路 `captureFullResolutionPng` はコード温存) + +## SHADING_MODE = HIGH_QUALITY の根拠(重要な合意) + +定量モードの核心的な設計判断。観察と物理的整合性から **HIGH_QUALITY を本流で維持**することで合意した。 + +- 実装中の観察:`SHADING_MODE=OFF` だと LSC マップが**全要素 1.0**(Android 仕様)になり情報が取れない。`HIGH_QUALITY` だと ISP が LSC を適用し、**実ゲインマップ**が取得できる。 +- 物理的整合性:SmTIAS-LightSim の Mitsuba **orthographic 出力**は平行光線サンプリングで cos⁴ falloff を持たず、**「ISP が完璧に LSC 補正できた場合の理想値」相当**。これと **HIGH_QUALITY DNG** を直接比較するのが物理的に最も整合する(残差=「実機 LSC 補正の不完全度+シミュ物理モデル誤差」=まさに評価したい本質)。 +- 逆に `OFF`(生 Bayer)を使うとシミュ側に物理 cos⁴ モデル(絞り径・口径食など)を足す必要があり、**自由度が増えて overfitting リスク**が上がる。 +- 結論:**HIGH_QUALITY 維持。MiniTIAS 側の実装変更は不要**。LSC マップは検証用に meta.json へ温存する。 + +### 将来 SHADING_OFF を追加検証する条件(フォールバック C1–C3) + +次のいずれかが起きたら「同一シーンを HQ と OFF で 1 セット撮影」する追加実装を検討する(現時点では未到達・実装不要): + +- **C1**: シミュ vs HQ DNG の残差が再現的に大きい(CoV/勾配残差 1.5× 以上 + 形が物理的に説明不能) +- **C2**: LSC マップが撮影ごとに大きく変動(中央値の変動 > 5%)→ ISP が AWB 連動で動的計算している証拠 +- **C3**: シミュ側モデル精度を上げても残差が物理的に説明できない + +## 露光・ISO の目安(合意値) + +10-bit DNG(黒レベル 64 除去後)で: + +- 白板中央の **mean = 400〜600**(中央値約 500) +- 飽和回避:**p99 < 900**(除去後 836) + +→ 確定値 **1/120s + ISO 40** で mean G ≈ 461・飽和率 0% を達成(基準測定値は PROGRESS.md 参照)。 + +## 作業フェーズ分け(合意) + +「再現性より先に、そもそもシミュと対応が取れるかを 1 ショットで確認する」二段階方式: + +- **フェーズ A(1 ショット対応検証)**: MiniTIAS 側は ①画素統計を meta.json に追加 ②Hot pixel map 取得 ③白板 1 枚を試し撮りして adb pull 転送。SmTIAS 側が DNG/メタ読み込みを実装し 1 ショット突合 → 残差 2.1× がどう変化するか観察。**①②は実装済み**。 +- **フェーズ B(連射 V1 再現性)**: フェーズ A で対応の見通しが立った場合のみ着手。10 連射 UI(`*_burst{0..9}.dng`)+ 再現性検証(mean CoV < 1%)。 + +## データ転送 + +**`adb pull` 推奨**。MTP は禁止しないが、16 MB 級の DNG でコピー直後にサイズが正しく見えない不整合が確認されているため非推奨。 diff --git "a/docs/05_TECH/TECH_01_\345\256\232\351\207\217\346\222\256\345\275\261\343\203\242\343\203\274\343\203\211\350\246\201\346\261\202\344\273\225\346\247\230.md" "b/docs/05_TECH/TECH_01_\345\256\232\351\207\217\346\222\256\345\275\261\343\203\242\343\203\274\343\203\211\350\246\201\346\261\202\344\273\225\346\247\230.md" deleted file mode 100644 index c4c6e8d..0000000 --- "a/docs/05_TECH/TECH_01_\345\256\232\351\207\217\346\222\256\345\275\261\343\203\242\343\203\274\343\203\211\350\246\201\346\261\202\344\273\225\346\247\230.md" +++ /dev/null @@ -1,267 +0,0 @@ -# 定量撮影モード要求仕様 (Quantitative Capture Mode Specification) - -本ドキュメントは SmTIAS-LightSim プロジェクトから MiniTIAS プロジェクトに対する **撮影モード拡張の要求仕様** である.SmTIAS-LightSim のキャリブレーション作業 (Step 8 系) で判明した「実機 PNG が定量データとして揺らぐ」問題を解消するための撮影アプリ側改修を依頼する. - -## 概要 (Overview) - -MiniTIAS([MiniTias](https://github.com/rintoHasegawa/MiniTias) リポジトリ)の撮影アプリに,現状の通常撮影モードに加えて **「定量撮影モード (Quantitative Capture Mode)」** を追加することを要求する. - -定量撮影モードでは: - -- Camera2 API のオート制御 (AE/AWB/NR/EDGE/TONEMAP) を **すべて固定または OFF** にする. -- ISP が適用した **LSC ゲインマップ** を撮影ごとに同時保存する. -- 可能なら出力フォーマットを **RAW_SENSOR (DNG)** に切り替えられるようにする. - -これにより同じシーンを何度撮影しても再現性のある定量データが得られ,SmTIAS-LightSim 側のシミュレーション結果との突合が安定する. - -## 背景 (Background) - -### SmTIAS-LightSim と MiniTIAS の関係 - -- **MiniTIAS**: スマートフォンアプリ.AQUOS sense3 で白板・舌模型を撮影し PNG として保存する. -- **MiniTias-Evaluation**: PC 側.MiniTIAS が保存した PNG を読み込み照明均一性 (CoV/勾配/C/P 等) を算出する. -- **SmTIAS-LightSim**: PC 側.Mitsuba 3 で同じ筐体・LED 配置を仮想撮影し,MiniTias-Evaluation と同じ指標を計算する. - -→ 3 つのプロジェクトで **同じ評価指標** を出すことで「シミュ vs 実機」を比較する. - -### 現状の問題(Step 8 キャリブで判明) - -Step 8 キャリブレーション ([TEST_01](../06_TEST/TEST_01_キャリブレーション検証履歴.md) 参照) で,シミュと実機の比較を試みた結果,以下の現象が観測された: - -- **形状指標残差 1.6〜1.9 倍** が解消されない(OETF 順方向適用後でも) -- 輝度マップの「形」が実機(中央ピーク楕円)とシミュ(Y 軸単調勾配)で **構造的に違う** ([TEST_03](../06_TEST/TEST_03_輝度マップ形状追跡.md) 参照) -- LED 位置・反射率・配光・センサ方向 ([TEST_01](../06_TEST/TEST_01_キャリブレーション検証履歴.md) Step 8-9/8-10/8-11/8-12 系) すべてを試したが「形」は変わらず - -「形を変える唯一の道」として **LSC (Lens Shading Correction) モデル化** が候補に挙がったが,さらに調査した結果,**より根本的な問題** が判明した: - -- 既存 baseline 画像 (`MiniTIAS_20260408_144434`) は **MiniTIAS の通常撮影モード**で取得されており,**ISP がすべて自動制御**で動作している. -- 具体的には [MiniTIAS/docs/04_SPEC/SPEC_01](../../MiniTIAS/docs/04_SPEC/SPEC_01_画面機能仕様書.md) のとおり: - - AE/AF 安定 1 秒待ち → STILL_CAPTURE → YUV_420_888 取得 → BT.601 で RGB → PNG 保存 - - AE / AWB / NR / EDGE / TONEMAP / SHADING はすべて Camera2 API のデフォルト (オート/ON) のまま -- これは「人間が見て自然な画像」用設定であり,**定量解析向けではない**. -- 撮影ごとに露光・WB・補正量が変動する可能性があり,**同じシーンを 2 回撮っても同じ値にならない可能性** がある. - -つまり「定量比較の対象である実機 PNG 自体が揺らいでいる」状態.まずここを固定化しない限り,シミュ側でいくらモデルを精緻化しても比較できない. - -## 目的 (Objective) - -定量撮影モードの導入により以下を達成する: - -1. **撮影再現性の確保**: 同条件で繰り返し撮影しても mean / std / 形状指標が同じ値になる. -2. **ISP 介入の最小化**: AE/AWB/NR/EDGE/TONEMAP/SHADING を固定/OFF し,センサ出力に近い値を取得する. -3. **メタデータの可視化**: ISP が適用した LSC ゲインマップを取得して別ファイル保存する. -4. **シミュ比較の土台**: SmTIAS-LightSim 側のキャリブレーション・LSC 検証が安定したデータで進められる. - -## 要求仕様 (Requirements) - -### 1. 撮影モード切替 UI - -撮影画面 (S-01) に「定量撮影モード」のトグルスイッチを追加する. - -- デフォルト: OFF(既存通常モード) -- ON 時: 後述の Camera2 API 設定をすべて適用 -- 後方互換: 既存ユーザー・既存撮影ワークフローには影響しない - -### 2. Camera2 API 設定(定量モード ON 時) - -| キー | 値 | 目的 | -| --- | --- | --- | -| `CONTROL_MODE` | `OFF`(マニュアル全制御) | ISP オート制御の完全停止 | -| `CONTROL_AE_MODE` | `OFF` | 自動露光停止 | -| `SENSOR_EXPOSURE_TIME` | 固定値(要キャリブ,例 1/60 s) | 露光時間固定 | -| `SENSOR_SENSITIVITY` | 最低 ISO(端末依存,例 50) | ノイズ最小化 + ゲイン固定 | -| `CONTROL_AWB_MODE` | `OFF` | 自動 WB 停止 | -| `COLOR_CORRECTION_GAINS` | 固定値 (R=G=B=1.0 推奨) | チャネルゲイン固定 | -| `COLOR_CORRECTION_TRANSFORM` | 単位行列 | カラーマトリクス無効化 | -| `NOISE_REDUCTION_MODE` | `OFF` | NR 無効化(アーティファクト排除) | -| `EDGE_MODE` | `OFF` | エッジ強調無効化 | -| `TONEMAP_MODE` | `CONTRAST_CURVE` (線形カーブ) または `PRESET_CURVE` (SRGB) | トーンマッピング固定 | -| `SHADING_MODE` | **`HIGH_QUALITY`** (LSC 補正適用) または **`OFF`** (LSC 無効化) のいずれか選択可 | LSC の挙動制御(次節参照) | -| `STATISTICS_LENS_SHADING_MAP_MODE` | `ON` | LSC ゲインマップ取得有効化 | - -> ※ `SHADING_MODE = OFF` を選んだ場合は cos⁴ falloff が画像に残る.後段のシミュ側で物理 cos⁴ を加える前提なら有用.通常運用では `HIGH_QUALITY` を推奨. - -### 3. LSC ゲインマップの保存 - -撮影成功時に `CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP` から `LensShadingMap` を取得して保存する. - -| 項目 | 仕様 | -| --- | --- | -| 取得 API | `result.get(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP)` | -| データ形状 | 4 × N × M float 配列(4 = R/Geven/Godd/B チャネル,N = 列,M = 行) | -| 値の意味 | ≥ 1.0 のゲイン係数.`corrected = raw × gain` | -| 保存形式 | NPZ(推奨)または JSON.画像ファイル名と同 prefix で `.lsc.npz` 等 | -| 保存先 | 画像と同ディレクトリ | -| マップサイズ | `CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE` から取得 | - -### 4. 撮影メタデータの保存(撮影パラメータの可視化) - -LSC マップに加えて,撮影時の Camera2 API パラメータを JSON で保存する.後段でシミュレーションの境界条件を再現するために必要. - -```json -{ - "capture_timestamp_utc": "2026-05-28T10:00:00Z", - "device_model": "SH-02M", - "android_version": "9", - "camera_id": "1", - "hardware_level": "LIMITED", - "capture_mode": "quantitative", - "settings": { - "control_mode": "OFF", - "ae_mode": "OFF", - "exposure_time_ns": 16666666, - "sensor_sensitivity_iso": 50, - "awb_mode": "OFF", - "color_correction_gains": [1.0, 1.0, 1.0, 1.0], - "color_correction_transform": "identity", - "noise_reduction_mode": "OFF", - "edge_mode": "OFF", - "tonemap_mode": "CONTRAST_CURVE", - "shading_mode": "HIGH_QUALITY", - "statistics_lens_shading_map_mode": "ON" - }, - "image_format": "YUV_420_888", - "image_size": [4000, 3000], - "yuv_to_rgb_matrix": "BT.601" -} -``` - -ファイル名規則: `.meta.json` - -### 5. 推奨出力フォーマット - -優先順位は以下: - -| 優先度 | フォーマット | 説明 | -| --- | --- | --- | -| 第 1 | **`RAW_SENSOR` (DNG)** | ISP 介入ゼロ.センサ出力そのまま.[DNG GainMap 仕様](https://www.adobe.com/content/dam/acom/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf) と整合 | -| 第 2 | **`YUV_420_888` + 上記メタデータ + LSC マップ** | 現状フォーマットに情報追加.後段で逆処理可能 | -| 第 3 | **PNG(現状) + メタデータ + LSC マップ** | 最小実装.BT.601 YUV→RGB 経由のため情報量は最小 | - -第 1 は実機が DNG 出力をサポートしている必要がある(AQUOS sense3 で要確認).サポートしていない場合は第 2 を採用. - -### 6. ハードウェアサポート判定 - -定量モード起動時に `CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL` を取得して以下を判定: - -- `LEGACY`: 定量モード **不可**(マニュアル制御サポートなし)→ ユーザーに警告表示 -- `LIMITED`: 部分サポート.SHADING_MODE と LSC マップ取得が可能か個別確認 -- `FULL` / `LEVEL_3`: **完全サポート** - -必要な能力フラグ: - -- `REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR` (露光・ISO 固定) -- `REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING` (NR/EDGE/TONEMAP/SHADING 固定) -- `REQUEST_AVAILABLE_CAPABILITIES_RAW` (DNG 出力,第 1 優先時のみ必須) - -判定結果は前述メタデータ JSON の `hardware_level` フィールドに記録する. - -## 推奨実装方針 (Recommended Implementation) - -### Flutter / camera パッケージの限界 - -[camera パッケージ](https://pub.dev/packages/camera) は AE/AWB/SHADING_MODE 等の詳細制御を **直接公開していない** ことが多い.定量モードを実現するには以下のいずれかが必要: - -- **Platform Channel で Camera2 API を直接制御**(推奨) - - Android Kotlin/Java 側で Camera2 API を直接叩く - - Flutter 側は MethodChannel で「定量モード撮影」要求を送る -- **camerax_android** など低レベル制御を公開した代替パッケージへの移行 -- **Native Plugin の自作** - -実装規模が大きい場合は段階的に: - -1. **Phase 1**: Camera2 詳細制御の MethodChannel 実装(露光・WB 固定,LSC マップ取得) -2. **Phase 2**: LSC マップ・メタデータ保存ロジック -3. **Phase 3**: 撮影画面 UI に定量モードトグル追加 -4. **Phase 4**: ハードウェアサポート判定とユーザー案内 -5. **Phase 5**: RAW_SENSOR (DNG) 対応(任意) - -### ディレクトリ構成提案 - -MiniTIAS 既存構造に従い: - -```text -android/app/src/main/kotlin// -└── camera/ - └── QuantitativeCameraController.kt # Camera2 直接制御 - -lib/services/ -├── quantitative_camera_service.dart # Platform Channel ラッパ -├── lsc_map_service.dart # LSC マップ NPZ 保存 -└── capture_metadata_service.dart # メタデータ JSON 保存 - -lib/providers/ -└── camera_provider.dart # 定量モード状態追加(既存 Provider 拡張) -``` - -## 期待される効果 (Expected Effects) - -| 項目 | 改善内容 | -| --- | --- | -| 撮影再現性 | 同条件 10 連射で mean / std が ±1% 以内に揃う | -| 色温度ドリフト | AWB 固定により無彩色撮影で色シフト排除 | -| LSC 補正可視化 | ISP が適用したゲインマップが取得でき,シミュ側で逆適用可能 | -| 物理 cos⁴ 検証 | SHADING_MODE = OFF モードで実機 raw 相当を取得し,シミュ + cos⁴ と比較可能 | -| RAW 比較 (任意) | DNG 経路が確立すれば,ISP 完全排除でセンサ生値 vs Mitsuba 直接比較 | -| キャリブ作業の安定化 | SmTIAS-LightSim 側で同じ baseline を繰り返し再撮影しても結果が動かない | - -## 後方互換 (Backward Compatibility) - -- 通常撮影モードは現状仕様のまま維持(既存撮影ワークフローを壊さない) -- 既存 baseline 画像 (`MiniTIAS_20260408_144434`) は **「通常モードで撮影された」** ことを SmTIAS-LightSim 側で明示記録([TEST_03](../06_TEST/TEST_03_輝度マップ形状追跡.md) に追記予定) -- 新規定量モード撮影は別命名規則を推奨: - - 例: `MiniTIAS_QM_YYYYMMDD_HHmmss.png`(QM = Quantitative Mode) - - メタデータ: `MiniTIAS_QM_YYYYMMDD_HHmmss.meta.json` - - LSC マップ: `MiniTIAS_QM_YYYYMMDD_HHmmss.lsc.npz` - -## 検証方法 (Verification) - -定量モード実装完了後,以下を実施して受け入れ判定とする: - -### V1. 再現性検証 - -同条件(光源 ON・同じ白板・三脚固定)で **10 回連続撮影** し,全画像で: - -- mean / std の変動係数 (CoV of means) < 1% -- 形状指標 (CoV/勾配/C/P) の標準偏差 < 0.005 - -### V2. LSC マップ取得検証 - -- 全撮影で `.lsc.npz` が保存されている -- マップサイズが `CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE` と一致 -- ゲイン値がすべて ≥ 1.0 -- 中央 (col=N/2, row=M/2) のゲインが ≈ 1.0 - -### V3. SHADING_MODE 切替検証 - -- `SHADING_MODE = OFF` で撮影した画像が `HIGH_QUALITY` より周辺で明らかに暗い(cos⁴ falloff 可視化) -- `HIGH_QUALITY × (1 / LSC マップ)` ≈ `OFF` の関係性が成立する(数値差 < 5%) - -### V4. SmTIAS-LightSim 側での突合 - -- 定量モード白板撮影 (SHADING_MODE = HIGH_QUALITY) を baseline として再キャリブ -- シミュ vs 実機の残差が現状 2.1× → 1.5× 以下に縮むこと(仮目標) - -## 開放質問 (Open Questions) - -実装着手時に確認が必要な事項: - -| ID | 質問 | 確認方法 | -| --- | --- | --- | -| Q1 | AQUOS sense3 のハードウェアレベルは何か | デバッグビルドで `CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL` を読みログ出力 | -| Q2 | SH-02M のフロントカメラで `REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING` がサポートされているか | 同上.未サポートなら定量モードは部分実装 | -| Q3 | DNG (RAW_SENSOR) 出力は可能か | `REQUEST_AVAILABLE_CAPABILITIES_RAW` を確認 | -| Q4 | LSC マップサイズはどの程度か(例 13×17 等) | 実機でログ出力.データ量設計の参考 | -| Q5 | 露光時間・ISO の最適値(固定値の決定) | 白板撮影で被写体の明るさが適切かを実機で試行錯誤 | -| Q6 | 既存 `MiniTIAS_20260408_144434` を定量モードで再撮影するか | 研究方針との整合(再撮影なら現 baseline は参考扱い) | -| Q7 | 既存 PNG 保存形式 (BT.601 経由) を維持するか YUV/RAW 直接保存に変えるか | SmTIAS-LightSim 側読み込みコストとのトレードオフ | - -## 関連ドキュメント (Related Documents) - -- [TEST_01 キャリブレーション検証履歴](../06_TEST/TEST_01_キャリブレーション検証履歴.md) — Step 8-1〜8-12 で「実機 PNG が定量データとして揺らぐ」を発見した経緯 -- [TEST_03 輝度マップ形状追跡](../06_TEST/TEST_03_輝度マップ形状追跡.md) — 形のずれの定性的記録.LSC モデル化議論の出発点 -- [SPEC_04 評価仕様](../04_SPEC/SPEC_04_評価仕様.md) — sm-evaluate の OETF 適用・mean アンカー処理 -- [SPEC_03 基準設計の物理構成](../04_SPEC/SPEC_03_基準設計の物理構成.md) — シミュ側物理モデル -- [MiniTIAS/docs/04_SPEC/SPEC_01 画面機能仕様書](../../MiniTIAS/docs/04_SPEC/SPEC_01_画面機能仕様書.md) — 現状のカメラ制御仕様(変更前ベースライン) -- [Android Camera2 API LensShadingMap](https://developer.android.com/reference/android/hardware/camera2/params/LensShadingMap) -- [Android Camera2 API CaptureRequest](https://developer.android.com/reference/android/hardware/camera2/CaptureRequest) diff --git "a/docs/05_TECH/TECH_02_MiniTIAS\345\274\225\343\201\215\347\266\231\343\201\216\346\211\213\351\240\206.md" "b/docs/05_TECH/TECH_02_MiniTIAS\345\274\225\343\201\215\347\266\231\343\201\216\346\211\213\351\240\206.md" deleted file mode 100644 index 1770af8..0000000 --- "a/docs/05_TECH/TECH_02_MiniTIAS\345\274\225\343\201\215\347\266\231\343\201\216\346\211\213\351\240\206.md" +++ /dev/null @@ -1,254 +0,0 @@ -# MiniTIAS 引き継ぎ手順 (Hand-off Procedure to MiniTIAS) - -本ドキュメントは [TECH_01 定量撮影モード要求仕様](TECH_01_定量撮影モード要求仕様.md) を MiniTIAS リポジトリで実装する際の **作業着手ガイド** および **データ受け渡し仕様** である.SmTIAS-LightSim と MiniTias の両プロジェクトを Claude Code セッションで作業している前提に最適化している. - -## 想定読者 (Intended Reader) - -- **MiniTias 側 Claude セッション**: 本ドキュメントを最初に開き,次に TECH_01 を読んで実装着手する. -- **人間レビュー (rinto)**: 両セッションを行き来し,質問の橋渡しと完了確認を行う. - -## プロジェクト関係図 (Project Relationship) - -```text -┌─────────────────────────┐ ┌──────────────────────────┐ -│ MiniTias │ │ SmTIAS-LightSim │ -│ (Flutter / Android) │ │ (Python / Mitsuba 3) │ -│ │ │ │ -│ 撮影アプリ │ │ 光散乱シミュレータ │ -│ - インカメラ制御 │ │ - 仮想シーン構築 │ -│ - 撮影モード │ │ - 物理光線追跡 │ -│ - PNG / メタデータ保存 │ ──→ │ - sm-evaluate │ -└─────────────────────────┘ └──────────────────────────┘ - │ - │ 同じ評価指標 - ▼ - ┌──────────────────────────┐ - │ MiniTias-Evaluation │ - │ (Python) │ - │ │ - │ 実機 PNG → 均一性指標 │ - └──────────────────────────┘ -``` - -→ 3 プロジェクトで **同じ評価指標** を出し,シミュ vs 実機を比較する.本作業は MiniTias 側に **「定量撮影モード」** を追加し,定量比較可能な実機データを取得できるようにする. - -## 背景の要約 (Background Digest) - -詳細は SmTIAS-LightSim 側の [TEST_01](../06_TEST/TEST_01_キャリブレーション検証履歴.md) と [TEST_03](../06_TEST/TEST_03_輝度マップ形状追跡.md) を参照.要点のみ抜粋: - -- SmTIAS-LightSim 側で **Step 8-1〜8-12 のキャリブ作業** を実施し,残差 2.1× で頭打ち -- 「形のずれ」を解消するため LSC モデル化を検討していたが,さらに調査した結果,**実機 PNG 自体が定量データとして揺らいでいる**ことが判明 -- 既存 baseline `MiniTIAS_20260408_144434` は MiniTias の通常モード (AE/AWB/NR/EDGE/TONEMAP 全自動) で撮影されており,撮影ごとに値が変動する可能性 -- → **「定量撮影モード」** の追加が必要.詳細は [TECH_01](TECH_01_定量撮影モード要求仕様.md) - -## MiniTias 側 Claude セッションの最初のアクション (First Actions) - -セッション開始時に以下 3 ステップを順に実施することを推奨する. - -### Step A: 実機サポート状況の確認(最優先) - -[TECH_01 開放質問 Q1〜Q4](TECH_01_定量撮影モード要求仕様.md#開放質問-open-questions) は **実装着手前に実機で確認すべき** 項目.まず簡易デバッグビルドで以下を取得: - -```kotlin -// android/app/src/main/kotlin/.../CameraDiagnostics.kt として実装提案 -val characteristics = cameraManager.getCameraCharacteristics(frontCameraId) - -// Q1: ハードウェアレベル -val hwLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) - -// Q2: 能力フラグ -val caps = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) -val hasManualSensor = caps?.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) -val hasManualPP = caps?.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING) -val hasRaw = caps?.contains(REQUEST_AVAILABLE_CAPABILITIES_RAW) - -// Q4: LSC マップサイズ -val mapSize = characteristics.get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE) - -// Q3: DNG 出力可否 -val streamMap = characteristics.get(SCALER_STREAM_CONFIGURATION_MAP) -val rawOutputSizes = streamMap?.getOutputSizes(ImageFormat.RAW_SENSOR) -``` - -これらを Logcat または UI に出力し,結果を MiniTias リポジトリの新規ファイル `docs/06_TEST/TEST_xx_実機サポート判定.md` 等に記録する. - -### Step B: 実装範囲の決定 - -Step A の結果から,**どの Phase まで実装できるか** を決定する: - -| ハードウェアレベル | 実装可能範囲 | 備考 | -| --- | --- | --- | -| `LEGACY` | 定量モード **不可** | ユーザーに警告表示のみ | -| `LIMITED` + `MANUAL_SENSOR` のみ | TECH_01 Phase 1(露光・ISO 固定)まで | NR/EDGE/TONEMAP 制御は ×.SHADING_MODE は個別確認 | -| `LIMITED` + `MANUAL_POST_PROCESSING` あり | TECH_01 Phase 1〜2(露光・WB・NR・EDGE 固定)まで | LSC マップ取得は STATISTICS_LENS_SHADING_MAP_MODE 個別確認 | -| `FULL` / `LEVEL_3` | TECH_01 Phase 1〜5 全実装可能 | DNG 出力も可能なら最高 | - -判定結果と「実装する Phase」を MiniTias 側 docs/ に記録.SmTIAS-LightSim 側にも反映できるよう,後述「結果の共有方法」に従う. - -### Step C: Phase 1 着手 - -[TECH_01 推奨実装方針](TECH_01_定量撮影モード要求仕様.md#推奨実装方針-recommended-implementation) の Phase 1〜5 を順に実装.`/implement` パイプラインで進めることを推奨: - -```text -/implement TECH_01 Phase 1: Camera2 詳細制御の MethodChannel 実装 -``` - -## データ受け渡し仕様 (Data Exchange Specification) - -定量撮影モードで取得したデータを SmTIAS-LightSim 側で使えるようにするための **ファイル配置・命名規則**. - -### ファイル命名規則 - -| 種別 | 命名 | -| --- | --- | -| 画像(PNG/YUV/DNG) | `MiniTIAS_QM_YYYYMMDD_HHmmss.` | -| 撮影メタデータ | `MiniTIAS_QM_YYYYMMDD_HHmmss.meta.json` | -| LSC ゲインマップ | `MiniTIAS_QM_YYYYMMDD_HHmmss.lsc.npz` | - -`QM` = Quantitative Mode.既存通常モードの `MiniTIAS_YYYYMMDD_HHmmss.png` と区別する. - -### 拡張子の選択 - -| 拡張子 | 採用条件 | -| --- | --- | -| `.png` | YUV_420_888 → BT.601 → RGB → PNG 経路(現状継承) | -| `.yuv` または `.yuv.npz` | YUV_420_888 を直接保存(中間処理排除) | -| `.dng` | RAW_SENSOR をサポートしている場合 | - -複数フォーマットを並列保存しても良い(例: 同一撮影で `.png` と `.dng` 両方を保存). - -### 端末から PC への転送 - -MiniTias アプリは端末ローカル `Pictures/MiniTIAS/` に保存する.PC への転送は **USB 接続でユーザーが手動コピー** する想定(既存ワークフローを継承). - -### SmTIAS-LightSim 側の配置先 - -PC 転送後の配置先は: - -```text -SmTIAS-LightSim/ -└── reference_measurement/ # .gitignore 配下(個人ローカル) - ├── MiniTIAS_20260408_144434/ # 既存 baseline(通常モード) - │ └── <画像 / 解析結果> - └── quantitative/ # ← 新規・定量モード用 - ├── MiniTIAS_QM_20260601_120000.png - ├── MiniTIAS_QM_20260601_120000.meta.json - ├── MiniTIAS_QM_20260601_120000.lsc.npz - └── ... -``` - -→ MiniTias 側で撮影 → PC に USB 転送 → `reference_measurement/quantitative/` に配置. - -### メタデータ JSON スキーマ - -[TECH_01 のメタデータ要求](TECH_01_定量撮影モード要求仕様.md#4-撮影メタデータの保存撮影パラメータの可視化) を参照.SmTIAS-LightSim 側の sm-evaluate で読み込み可能な形式とする. - -特に **必須フィールド**: - -- `capture_mode`: `"quantitative"` または `"normal"` -- `device_model`: `"SH-02M"` 等 -- `hardware_level`: Step A で取得した値 -- `settings`: Camera2 API の実適用値 -- `image_format`: `"YUV_420_888"` / `"RAW_SENSOR"` 等 - -これらが揃っていれば SmTIAS-LightSim 側で読み込みロジックを実装可能. - -### LSC マップ NPZ スキーマ - -```python -# NPZ 内のキー -{ - "gain_map": np.ndarray, # shape=(4, N, M), dtype=float32, channels=[R, Geven, Godd, B] - "map_size": np.ndarray, # shape=(2,), dtype=int32, [N=col_count, M=row_count] - "min_gain_factor": 1.0, # MINIMUM_GAIN_FACTOR -} -``` - -または等価な JSON でも可(数値桁数の精度に注意). - -## 既存 baseline 画像へのアクセス (Existing Baseline Access) - -`MiniTIAS_20260408_144434` は SmTIAS-LightSim 側の `reference_measurement/` 配下に存在(.gitignore 対象,個人ローカル).MiniTias 側からは直接参照できない. - -実装中に **「既存撮影時の条件と揃えたい」** という要請が出た場合は,rinto 経由で: - -1. SmTIAS-LightSim リポジトリで該当画像の Exif / メタデータを抽出 -2. 結果を MiniTias 側 docs/ または本リポジトリの本ファイルに追記して共有 - -ただし TECH_01 に書いたとおり,**既存 baseline 自体が「定量データとして揺らいでいる」のが本作業の出発点**なので,定量モード実装後は新規 baseline(定量モードで撮ったもの)に置き換える前提でよい. - -## 質問・調整事項の扱い (Open Issues Handling) - -両プロジェクト Claude セッションでの作業を前提とすると,質問・調整は **ファイルベース** で行うのが追跡性が高い. - -| 状況 | 対応 | -| --- | --- | -| MiniTias 側実装中に Q1〜Q7 の判断が必要になった | MiniTias 側 docs/ に `06_TEST/TEST_xx_実装判断ログ.md` 等で判断と理由を記録.rinto が SmTIAS-LightSim 側にも反映 | -| SmTIAS-LightSim 側仕様 (TECH_01) に追加要求が出た | rinto が SmTIAS-LightSim 側で TECH_01 を更新.MiniTias 側 Claude は `git pull` 相当で再読 | -| データ受け渡し仕様(ファイル命名・スキーマ)の変更要求 | rinto が SmTIAS-LightSim 側で本ファイル (TECH_02) を更新.両セッションで共有 | -| 実機 (AQUOS sense3) で予期せぬ動作 | MiniTias 側 docs/ に記録.必要なら本ファイルの「既知の制約」セクションに追記(後日反映) | - -## 完了判定の方法 (Completion Criteria) - -[TECH_01 検証方法 V1〜V4](TECH_01_定量撮影モード要求仕様.md#検証方法-verification) を実機で実施. - -### MiniTias 側で完了とする条件 - -- V1(再現性 10 連射 CoV < 1%),V2(LSC マップ取得検証),V3(SHADING_MODE 切替検証)の結果ログが MiniTias 側 docs/06_TEST/ 等に残っている -- 定量モードで白板を撮影したサンプルファイル(PNG + meta.json + LSC マップ)が 1 セット以上 PC 側 `reference_measurement/quantitative/` に存在する - -### SmTIAS-LightSim 側の受け入れトリガー - -`reference_measurement/quantitative/` 配下にサンプルファイルが配置された時点で,SmTIAS-LightSim 側 Claude セッションは以下の受け入れ作業に着手できる: - -- メタデータ JSON 読み込み I/F の実装(sm-evaluate 拡張) -- LSC マップ読み込み I/F の実装(sm-evaluate の LSC 順方向適用機能) -- 既存 baseline と新規定量モード baseline の **並列キャリブ**(両者の比較) -- TEST_01 に新規 Step(例: Step 8-13)として追加 - -### V4 の達成判定 - -V4(残差 2.1× → 1.5×)は両プロジェクトの連携でのみ達成可能: - -- MiniTias 側で V1〜V3 完了 -- SmTIAS-LightSim 側で sm-evaluate に定量モード対応実装完了 -- 新規 baseline でキャリブ実施 -- 結果を SmTIAS-LightSim 側 TEST_01 に追記 - -V4 達成は本ハンドオフのスコープ外(後続キャリブ作業の成果として位置付ける). - -## 後続作業 (Follow-up Work on SmTIAS-LightSim Side) - -MiniTias 側完了後,SmTIAS-LightSim 側で以下を実施予定(参考情報): - -1. **`sm-evaluate` に LSC 順方向適用機能を追加**: 新規 `evaluation/lsc.py` モジュール.LSC マップを画像に掛けて補正済み画像を再現 -2. **メタデータ JSON 読み込み機能**: `evaluation/metadata.py` で撮影パラメータを取得 -3. **新規 baseline 設定の追加**: `configs/eval_baseline_quantitative.yaml` 等.既存 baseline と並列保持 -4. **TEST_01 に Step 8-13 を追加**: 「定量モード baseline での再キャリブ」として記録 -5. **TEST_03 の比較パネル更新**: 新規 baseline を含む形で再生成 - -これらは MiniTias 側完了後に着手するため,TECH_01 の検証 V4 とともに「本ハンドオフのスコープ外」として位置付ける. - -## チェックリスト(MiniTias 側 Claude 用) (Checklist) - -セッション内で以下を順に確認すると進めやすい: - -- [ ] 本ファイル (TECH_02) を読了 -- [ ] TECH_01 を読了 -- [ ] [MiniTIAS/docs/04_SPEC/SPEC_01 画面機能仕様書](../../MiniTIAS/docs/04_SPEC/SPEC_01_画面機能仕様書.md) を読了(現状仕様) -- [ ] Step A: 実機サポート状況確認 → 結果記録 -- [ ] Step B: 実装範囲決定 → 記録 -- [ ] Step C: Phase 1 着手(`/implement` パイプライン) -- [ ] Phase 2 以降を順次実装 -- [ ] V1〜V3 実機検証 → 結果ログを docs/06_TEST/ に残す -- [ ] 定量モード撮影サンプルを `Pictures/MiniTIAS/` に作成 → rinto が PC 転送 - -## 関連ドキュメント (Related Documents) - -- [TECH_01 定量撮影モード要求仕様](TECH_01_定量撮影モード要求仕様.md) — 本作業の要求書(What/Why) -- [TEST_01 キャリブレーション検証履歴](../06_TEST/TEST_01_キャリブレーション検証履歴.md) — 「形のずれ」発見の経緯 -- [TEST_03 輝度マップ形状追跡](../06_TEST/TEST_03_輝度マップ形状追跡.md) — シミュ vs 実機の構造的差異 -- [SPEC_04 評価仕様](../04_SPEC/SPEC_04_評価仕様.md) — sm-evaluate の評価パイプライン -- [MiniTIAS/docs/04_SPEC/SPEC_01 画面機能仕様書](../../MiniTIAS/docs/04_SPEC/SPEC_01_画面機能仕様書.md) — 現状の MiniTias 撮影仕様(変更前ベースライン) -- [Android Camera2 API LensShadingMap](https://developer.android.com/reference/android/hardware/camera2/params/LensShadingMap) -- [Android Camera2 API CaptureRequest](https://developer.android.com/reference/android/hardware/camera2/CaptureRequest) diff --git "a/docs/05_TECH/TECH_03_\345\256\232\351\207\217\343\203\242\343\203\274\343\203\211\345\256\237\350\243\205\345\240\261\345\221\212\343\201\250SHADING_MODE\347\233\270\350\253\207.md" "b/docs/05_TECH/TECH_03_\345\256\232\351\207\217\343\203\242\343\203\274\343\203\211\345\256\237\350\243\205\345\240\261\345\221\212\343\201\250SHADING_MODE\347\233\270\350\253\207.md" deleted file mode 100644 index f1559fa..0000000 --- "a/docs/05_TECH/TECH_03_\345\256\232\351\207\217\343\203\242\343\203\274\343\203\211\345\256\237\350\243\205\345\240\261\345\221\212\343\201\250SHADING_MODE\347\233\270\350\253\207.md" +++ /dev/null @@ -1,336 +0,0 @@ -# 定量モード実装報告と SHADING_MODE 相談 (Implementation Report & SHADING_MODE Consultation) - -本ドキュメントは [TECH_01 定量撮影モード要求仕様](TECH_01_定量撮影モード要求仕様.md) を MiniTIAS リポジトリで実装した結果の **MiniTIAS 側からの報告書** であり,併せて **SmTIAS-LightSim 側との方針確認・相談事項** をまとめたものである. - -## 想定読者 (Intended Reader) - -- **SmTIAS-LightSim 側 Claude セッション**: 本ドキュメントを読んで MiniTIAS 側の実装状況を把握し,未確定事項に対する判断・指示を返す -- **人間レビュー (rinto)**: 両セッションを橋渡しし,研究方針に照らして判断する - -## 概要 (Overview) - -MiniTIAS 側で TECH_01 の要求仕様に基づいた **定量撮影モード(DNG 経路)** の実装が完了した([MiniTias リポジトリ master ブランチ](https://github.com/rintoHasegawa/MiniTIAS) に取り込み済み).本ドキュメントの目的は以下の 2 点: - -1. **実装結果の報告**:TECH_01 の各 Phase に対して何を実装したか,AQUOS sense3 (SH-02M) で何が確認できたかを共有する -2. **SHADING_MODE の扱いの相談**:定量モードのキー設定である `SHADING_MODE` を MiniTIAS 側でどう選んだか,研究上どのような含意があるか,SmTIAS-LightSim 側の解析パイプラインとの整合を確認したい - -## TECH_01 要求に対する実装状況 (Implementation Status) - -| Phase | 要求 | 実装状況 | -| --- | --- | --- | -| Phase 1 | Camera2 詳細制御の MethodChannel 実装(露光・WB 固定,LSC マップ取得) | ✅ 完了 | -| Phase 2 | LSC マップ・メタデータ保存ロジック | ✅ 完了 | -| Phase 3 | 撮影画面 UI に定量モードトグル追加 | ⚠️ 仕様変更(後述).**トグル UI は追加せず通常モードを置換** | -| Phase 4 | ハードウェアサポート判定とユーザー案内 | ✅ 診断機能を `DiagnosticsProvider` として実装(UI 非表示.裏で再利用可能) | -| Phase 5 | RAW_SENSOR (DNG) 対応(任意) | ✅ 完了.第 1 優先経路として採用 | - -### Phase 3 の変更点 - -TECH_01 では「撮影モード切替トグル」で通常モードと定量モードを並存させる想定だったが,MiniTIAS 側の運用判断として **通常モード(PNG 経路)を temporarily に無効化し,シャッターは常に定量モードを呼ぶ**構成にした.既存の `captureFullResolutionPng` コードは温存している. - -理由: - -- MiniTIAS の運用上の存在意義は SmTIAS-LightSim との定量比較のみ -- トグル UI を残すと「誤って通常モードで撮影してしまい後で気付く」事故が起きる -- 研究フェーズ完了後にトグル追加 or 通常モード復活は容易 - -## 実装した撮影設定 (Camera2 CaptureRequest) - -| キー | 設定値 | 備考 | -| --- | --- | --- | -| `CONTROL_MODE` | `OFF` | マニュアル全制御 | -| `CONTROL_AE_MODE` | `OFF` | 自動露光停止 | -| `SENSOR_EXPOSURE_TIME` | `16,666,666 ns`(= 1/60 s) | **ハードコード**.後段で半自動キャリブ機能の追加を検討中 | -| `SENSOR_SENSITIVITY` | `40`(センサ最低 ISO) | 診断で確認したセンサのレンジ最低値 | -| `SENSOR_FRAME_DURATION` | `33,333,333 ns`(30fps 相当) | 露光時間 ≤ frame duration を満たす任意値 | -| `BLACK_LEVEL_LOCK` | `true` | フレーム間で黒レベルのドリフトを抑える | -| `CONTROL_AWB_MODE` | `OFF` | 自動 WB 停止 | -| `COLOR_CORRECTION_MODE` | `TRANSFORM_MATRIX` | マニュアル制御モード | -| `COLOR_CORRECTION_GAINS` | `RggbChannelVector(1.0, 1.0, 1.0, 1.0)` | RAW 出力では Bayer 値に効かないが request 値として明示 | -| `COLOR_CORRECTION_TRANSFORM` | 単位行列(`ColorSpaceTransform`) | 同上 | -| `NOISE_REDUCTION_MODE` | `OFF` | NR による画素値の改変を防ぐ | -| `EDGE_MODE` | `OFF` | エッジ強調を防ぐ | -| `TONEMAP_MODE` | `CONTRAST_CURVE` | カーブは R/G/B すべて線形 `[(0,0),(1,1)]` | -| **`SHADING_MODE`** | **`HIGH_QUALITY`** | ★後述の相談対象.OFF も技術的に可能 | -| `STATISTICS_LENS_SHADING_MAP_MODE` | `ON` | LSC マップを CaptureResult に含める | -| `CONTROL_AF_MODE` | `OFF` | **AQUOS sense3 のフロントカメラは固定焦点で OFF のみサポート** | -| `FLASH_MODE` | `OFF` | LED はアタッチメント側で制御 | -| `CONTROL_VIDEO_STABILIZATION_MODE` | `OFF` | 手ブレ補正による画像ずれを防ぐ | - -## 撮影フロー (Capture Flow) - -```text -シャッター押下 - │ - ▼ -プレビュー停止(camera パッケージの CameraController.dispose) - │ - ▼ -baseName 生成(MiniTIAS_QM_YYYYMMDD_HHmmss.同秒重複時 _1, _2 ...) - │ - ▼ -Camera2 API でフロントカメラを開く -ImageReader(RAW_SENSOR, 3264×2448, maxImages=3) - │ - ▼ -上記マニュアル制御パラメータを CaptureRequest に適用 - │ - ▼ -連続 3 枚キャプチャ -(設定反映確実化のため最初の 2 枚は破棄.3 枚目を本番とする) - │ - ▼ -DngCreator で DNG ファイルを直接書き込み -(FileOutputStream → ${dir}/${baseName}.dng) - │ - ▼ -LSC マップ取得(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP) -メタデータ Map 構築(settings / actual / sensorCharacteristics / lscMap) - │ - ▼ -Dart 側でメタデータ JSON 保存 -(${dir}/${baseName}.meta.json) - │ - ▼ -シャッター瞬間に取得済みのライブプレビュースナップショット JPEG を保存 -(${dir}/${baseName}.preview.jpg.アプリ内目視確認用.解析対象外) - │ - ▼ -MediaStore 通知 → Camera2 解放 → プレビュー再開 -``` - -**従来の「1 秒 AE/AF 安定待ち」は省略**した.AE/AWB/AF 全部 OFF のため安定待ちの意味がないことと,「3 枚連続キャプチャの 2 枚破棄」で設定反映の不確実性を吸収する設計にした. - -## AQUOS sense3 (SH-02M) 実機検証結果 (Device Verification) - -TECH_01 の開放質問 Q1〜Q4 に対する実機での確認結果.診断機能(`getCameraDiagnostics`)の出力は MiniTIAS リポジトリの [`docs/06_TEST/camera_diagnostics_20260531_161734.json`](../06_TEST/camera_diagnostics_20260531_161734.json) に保存している. - -### 主要項目 - -| 項目 | 値 | -| --- | --- | -| `INFO_SUPPORTED_HARDWARE_LEVEL` | **`LEVEL_3`**(最上位) | -| `REQUEST_AVAILABLE_CAPABILITIES` | `BACKWARD_COMPATIBLE`, **`MANUAL_SENSOR`**, **`MANUAL_POST_PROCESSING`**, **`RAW`**, `READ_SENSOR_SETTINGS`, `BURST_CAPTURE`, `PRIVATE_REPROCESSING`, `YUV_REPROCESSING` | -| `SENSOR_INFO_EXPOSURE_TIME_RANGE` | `79,806 ns 〜 871,614,530 ns`(≈ 1/12530 s 〜 0.87 s) | -| `SENSOR_INFO_SENSITIVITY_RANGE` | `40 〜 2506` | -| `RAW_SENSOR` 出力サイズ | `3264 × 2448`(1 種類のみ) | -| `SENSOR_INFO_COLOR_FILTER_ARRANGEMENT` | `3 (BGGR)` | -| `SENSOR_BLACK_LEVEL_PATTERN` | `[[64, 64], [64, 64]]` | -| `SENSOR_INFO_WHITE_LEVEL` | `1023`(10-bit) | -| `SENSOR_INFO_PHYSICAL_SIZE` | `3.558 mm × 2.668 mm` | -| `SENSOR_INFO_PIXEL_ARRAY_SIZE` | `3264 × 2448` | -| `LENS_INFO_MINIMUM_FOCUS_DISTANCE` | `0.0`(無限遠固定) | -| `LENS_INFO_HYPERFOCAL_DISTANCE` | `0.8189`(≈ 1.22 m) | -| `STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES` | `[OFF (0), ON (1)]` | -| `CONTROL_AF_AVAILABLE_MODES` | **`[OFF (0)] のみ`**(AF 機能なし) | -| `SHADING_AVAILABLE_MODES` | `[OFF, FAST, HIGH_QUALITY]` | - -### 注目点 - -- **TECH_01 の Phase 1〜5 すべてが実装可能**な能力構成だった -- **AF は OFF のみ**.レンズは固定焦点(無限遠固定)でアタッチメント光学系で近接被写体にピントを合わせている前提 -- LSC マップサイズは実キャプチャ結果から **13 × 17** と判明(特性からは hidden API のため取得不可だった) - -## 保存ファイル仕様 (Output File Specification) - -### ファイル命名規則 - -撮影 1 回で 3 ファイルを生成.basename は共通. - -| 種別 | ファイル名 | 概要 | -| --- | --- | --- | -| RAW 画像 | `MiniTIAS_QM_YYYYMMDD_HHmmss.dng` | 解析の本体(約 16 MB) | -| メタデータ | `MiniTIAS_QM_YYYYMMDD_HHmmss.meta.json` | 撮影設定 + 実適用値 + LSC マップ + センサ特性(約 24 KB) | -| プレビュー | `MiniTIAS_QM_YYYYMMDD_HHmmss.preview.jpg` | アプリ内表示・確認用.解析対象外 | - -`QM` = Quantitative Mode.同秒重複時は `_1`, `_2` ... と連番を付与. - -### DNG (RAW_SENSOR) - -- フォーマット: TIFF/EP ベースの Adobe DNG(`DngCreator` 経由) -- データ: 10-bit BGGR Bayer,3264×2448 -- Exif メタ: DngCreator が `CameraCharacteristics` から自動で埋め込み(`ColorMatrix1/2`, `ForwardMatrix1/2`, `AsShotNeutral`, `NoiseProfile`, `BlackLevelPattern` 等) - -### meta.json の構造(実例抜粋) - -[`MiniTIAS_QM_20260531_172612.meta.json`](https://github.com/rintoHasegawa/MiniTIAS) から抜粋(白板を SHADING_MODE = HIGH_QUALITY で撮影したもの): - -```json -{ - "captureTimestampUtc": "2026-05-31T08:26:13.235Z", - "deviceModel": "SH-02M", - "androidVersion": "9", - "cameraId": "1", - "hardwareLevel": 3, - "captureMode": "quantitative", - "imageFormat": "RAW_SENSOR", - "imageSize": [3264, 2448], - - "settings": { - "control_mode": "OFF", - "ae_mode": "OFF", - "exposure_time_ns": 16666666, - "sensor_sensitivity_iso": 40, - "frame_duration_ns": 33333333, - "awb_mode": "OFF", - "color_correction_gains": [1.0, 1.0, 1.0, 1.0], - "color_correction_transform": "identity", - "noise_reduction_mode": "OFF", - "edge_mode": "OFF", - "tonemap_mode": "CONTRAST_CURVE_LINEAR", - "shading_mode": "HIGH_QUALITY", - "statistics_lens_shading_map_mode": "ON", - "af_mode": "OFF", - "black_level_lock": true - }, - - "actual": { - "exposure_time_ns": 16653365, - "sensor_sensitivity": 40, - "frame_duration_ns": 33333333, - "sensor_timestamp": 4894940190334, - "dynamic_black_level": null, - "dynamic_white_level": 1023, - "neutral_color_point": ["1/1", "1/1", "1/1"], - "color_gains": [1.0, 1.0, 1.0, 1.0], - "color_transform": [ - ["1/1", "0/1", "0/1"], - ["0/1", "1/1", "0/1"], - ["0/1", "0/1", "1/1"] - ] - }, - - "sensorCharacteristics": { - "color_filter_arrangement": 3, - "black_level_pattern": "BlackLevelPattern([64, 64], [64, 64])", - "white_level": 1023, - "physical_size": [3.557760, 2.668320], - "pixel_array_size": [3264, 2448], - "active_array_size": "Rect(0, 0 - 3264, 2448)" - }, - - "lscMap": [ - [5.105, 4.232, 4.111, 3.847, 4.982, 3.966, 3.916, 3.744, 4.459, 3.503, 3.502, 3.369, 3.860, 3.025, 2.995, 2.905, 3.367, 2.647, 2.595, 2.522, 2.995, 2.393, 2.349, 2.285, 2.765, 2.235, 2.199, 2.133, 2.613, 2.130, 2.093, 2.032, 2.577, 2.087, 2.051, 1.991, 2.610, 2.125, 2.093, 2.022, 2.728, 2.214, 2.187, 2.110, 2.950, 2.365, 2.359, 2.251, 3.294, 2.614, 2.637, 2.500, 3.846, 3.006, 3.042, 2.868, 4.426, 3.456, ...], - ...(行 1〜行 12 続く) - ], - "lscMapRowCount": 13, - "lscMapColumnCount": 17 -} -``` - -#### `actual` フィールドについての注意 - -- `actual` は CaptureResult から読み戻した**実適用値**.Request 値(`settings`)と微妙に異なる場合がある(例:露光時間 16,666,666 → 16,653,365 でセンサが量子化) -- `dynamic_black_level` は `null` で返ることがある(端末依存).代わりに `sensorCharacteristics.black_level_pattern` の静的値を参照可 -- `neutral_color_point` と `color_transform` が単位行列なのは AWB OFF + identity gains 設定の結果 - -#### LSC マップ - -- 形状: 4 ch × N rows × M cols(4 = R / G_even / G_odd / B)の各チャネルゲイン -- 本実装の保存形式: **1 行を 4 × M 個の float が並んだフラット配列**として `lscMap[row]` に格納.行数・列数は `lscMapRowCount` / `lscMapColumnCount` で別途記録 -- 値の意味: `corrected = raw × gain`.中央 ≈ 1.0,周辺で 5× 程度まで上がる典型的な cos⁴ 補正マップになっている -- **ただし `SHADING_MODE = OFF` で撮影した場合は全要素 `1.0` の単位マップが返ってくることを確認済み**(次節で詳述) - -### preview.jpg - -シャッター瞬間のライブプレビュー JPEG をそのまま保存(Camera2 ISP がフル稼働した状態の画像).**解析対象ではない**.撮影者がアプリ内で「撮れた」を判断するためだけのもの.解像度はプレビューストリーム依存(おそらく 1280×720 程度). - -## SHADING_MODE の扱い(★相談事項) (Consultation on SHADING_MODE) - -### 経緯 - -実装初期は **TECH_01 の表に明記されていた `HIGH_QUALITY` を採用**した.しかし実装途中で MiniTIAS 側は以下を観察した: - -1. `SHADING_MODE = OFF` で撮影すると **LSC マップが全要素 `1.0`** になる(Android 仕様:「補正は適用しない + 単位マップを返す」) -2. `SHADING_MODE = HIGH_QUALITY` で撮影すると LSC が **画像に適用された状態**で DNG に保存される.LSC マップは ISP が適用したゲインの実値 - -結果:**HIGH_QUALITY を採用した**現状の DNG は,ISP によって cos⁴ 由来のシェーディングが既に補正された状態のデータになっている. - -### 研究上の含意 - -SmTIAS-LightSim 側の Mitsuba 3 シミュレーションは「物理的な cos⁴ 落ち + LED 配光 + 鏡面反射」を再現するものと理解している.この物理シミュレーション結果と直接比較したいデータは: - -- (A) **LSC 適用済み画像(現状の DNG)**: ISP が「メーカー校正の LSC マップ」を掛けて平坦化したもの.物理的な cos⁴ がほぼ取り除かれている -- (B) **LSC 適用前の生 Bayer**: 物理的 cos⁴ がそのまま残っている.Mitsuba 出力と同じ前提 - -(A) と Mitsuba を直接比較すると **比較対象に LSC マップ分のずれが系統的に乗る**ことになる.これが [TEST_01](../06_TEST/TEST_01_キャリブレーション検証履歴.md) で残差 2.1× が解消しなかった一因の可能性もある(推測). - -### 取りうる選択肢 - -研究の整合のために考えられる方向性を以下に列挙する.**MiniTIAS 側からの判断はせず**,SmTIAS-LightSim 側で解析パイプラインを構築する立場からの選択肢として提示する: - -| 選択肢 | MiniTIAS 側の対応 | SmTIAS-LightSim 側の対応 | データの性質 | -| --- | --- | --- | --- | -| (1) 現状維持(HQ) | 変更なし | `DNG ÷ LSC マップ` を計算して LSC 適用前相当に戻す処理を実装 | DNG は LSC 適用済み.逆適用で物理生 Bayer を再構成 | -| (2) OFF に切替 | `SHADING_MODE = OFF` に変更 | そのまま Mitsuba 出力と比較 | DNG は物理生 Bayer.LSC マップは情報なし(全 1.0) | -| (3) 両方撮影 | 1 シーンに対し HQ と OFF の 2 枚を連続撮影 | 比較・検証で使い分け | 情報量最大.ただし撮影時間と保存容量が 2 倍 | - -#### MiniTIAS 側で対応する場合のコスト感 - -- (1): コスト 0(現状).SmTIAS-LightSim 側で逆適用ロジックが必要 -- (2): Kotlin 側 CaptureRequest を 1 行変更.連動して meta.json の `settings.shading_mode` も `"OFF"` に.約 30 分 -- (3): キャプチャ処理を 2 連続化.ファイル名規則の拡張(例:`*_hq.dng` / `*_off.dng`).約 1 時間 - -### MiniTIAS 側から確認したい事項 - -- SmTIAS-LightSim 側の解析パイプラインで「LSC マップを使った逆適用」は実装済み or 実装可能か? -- 物理シミュレーション(Mitsuba)の出力は「LSC 適用前の生 Bayer 相当」で間違いないか? -- 既存 baseline `MiniTIAS_20260408_144434`(通常モード PNG)との互換性をどう扱うか?(既に方針として「定量モード以降は新規 baseline」となっていれば問題なし) - -選択肢 (1)〜(3) のうちどれを採用するか,または別案があるか,**SmTIAS-LightSim 側の判断を求めたい**.本相談への返答を受けて MiniTIAS 側で必要な実装変更を行う. - -## その他の未確認事項 (Other Open Issues) - -### 露光時間 / ISO の運用 - -現状 `1/60 s + ISO 40` ハードコードで撮影している.照明条件(アタッチメント装着時の LED 強度),被写体(白板 / 舌模型 / 実舌)によって最適値は異なるはず. - -- 白板:飽和しない範囲で最大露光(SN 比最大) -- 舌模型:白板用設定だと暗すぎる可能性 - -MiniTIAS 側で検討中の対応: - -- (a) 半自動キャリブ機能(AE を 1 回走らせて値を読み,以降固定) -- (b) 白板用・舌模型用の 2 プリセット -- (c) ハードコード変更(撮影前に手動で設定) - -SmTIAS-LightSim 側で「白板撮影時の理想的なセンサ平均値」(例:10-bit のうち 500 前後)の目安があれば共有してほしい. - -### V1 連射再現性検証の担当 - -TECH_01 検証 V1(10 連射 CoV < 1%)を実施するには: - -- MiniTIAS 側:連射 UI(10 ショットを連続保存)の実装が必要 -- 解析:DNG を読み込んで mean / std / CoV を計算する Python スクリプトが必要 - -連射機能は MiniTIAS 側で実装予定.解析スクリプトは MiniTIAS 内に `scripts/verify_repeatability.py` 等で置くか,SmTIAS-LightSim 側の sm-evaluate に統合するか方針を相談したい. - -### MTP 経由ファイル転送の注意点 - -DNG が 16 MB 級のため MTP コピー直後にファイルサイズが正しく見えないケースを実装中に確認した.**`adb pull` の使用を推奨**.SmTIAS-LightSim 側のデータ受け取り手順としてもこれを前提にすると安全. - -## MiniTIAS 側で検討中の改善案 (Planned Improvements) - -SmTIAS-LightSim 側との打ち合わせ事項と並行して,以下を MiniTIAS 側で進める予定.優先度は内部判断による: - -| 優先度 | 項目 | 概要 | -| --- | --- | --- | -| 高 | 画素統計を meta.json に追加 | 飽和・露光不足の自動判定用.`mean_per_channel`, `max_per_channel`, `p99`, `saturated_pixel_ratio` 等 | -| 高 | Hot pixel map 取得 | `STATISTICS_HOT_PIXEL_MAP_MODE = ON` で常時光る画素一覧を meta に記録.PC 側でマスク可能に | -| 高 | 連射機能(V1 検証用) | 10 連射 UI.`MiniTIAS_QM_*_burst{N}.dng` 等で連番保存 | -| 中 | 露光時間・ISO の半自動キャリブ機能 | 白板で AE 1 ショット → 値を読んで固定 | -| 中 | レンズ・センサ校正値を meta に追加 | `LENS_INTRINSIC_CALIBRATION`, `LENS_DISTORTION`, `SENSOR_REFERENCE_ILLUMINANT1/2`, `SENSOR_COLOR_TRANSFORM1/2` 等 | -| 低 | Dark frame / Flat field キャリブ機能 | `(対象 − Dark) / (Flat − Dark)` 補正のための基準フレーム撮影 | - -これらは SmTIAS-LightSim 側からの要望順位とすり合わせて優先度を確定したい. - -## 関連ドキュメント (Related Documents) - -- [TECH_01 定量撮影モード要求仕様](TECH_01_定量撮影モード要求仕様.md) — 本実装の原始要求 -- [TECH_02 MiniTIAS 引き継ぎ手順](TECH_02_MiniTIAS引き継ぎ手順.md) — 引き継ぎ時の作業ガイド -- [`docs/06_TEST/camera_diagnostics_20260531_161734.json`](../06_TEST/camera_diagnostics_20260531_161734.json) — AQUOS sense3 (SH-02M) の能力診断結果(フル) -- [SPEC_01 画面機能仕様書](../04_SPEC/SPEC_01_画面機能仕様書.md) — MiniTIAS 側の撮影仕様(定量モード反映済み) -- [PLAN_01 要件定義書](../03_PLAN/PLAN_01_要件定義書.md) — ファイル管理仕様 -- [PROGRESS.md](../PROGRESS.md) — 実装の進捗ログと設計判断・失敗パターン -- [Android Camera2 API SHADING_MODE](https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#SHADING_MODE) -- [Android Camera2 API STATISTICS_LENS_SHADING_CORRECTION_MAP](https://developer.android.com/reference/android/hardware/camera2/CaptureResult#STATISTICS_LENS_SHADING_CORRECTION_MAP) diff --git "a/docs/05_TECH/TECH_04_MiniTIAS\343\201\270\343\201\256\345\233\236\347\255\224.md" "b/docs/05_TECH/TECH_04_MiniTIAS\343\201\270\343\201\256\345\233\236\347\255\224.md" deleted file mode 100644 index fdbfcdd..0000000 --- "a/docs/05_TECH/TECH_04_MiniTIAS\343\201\270\343\201\256\345\233\236\347\255\224.md" +++ /dev/null @@ -1,333 +0,0 @@ -# MiniTIAS への回答 (Response to MiniTIAS) - -本ドキュメントは [TECH_03 定量モード実装報告と SHADING_MODE 相談](TECH_03_定量モード実装報告とSHADING_MODE相談.md) に対する **SmTIAS-LightSim 側からの回答書** である.MiniTIAS 側の実装結果評価・SHADING_MODE 判断・物理解釈の修正・運用上の合意事項を明文化する. - -## 想定読者 (Intended Reader) - -- **MiniTIAS 側 Claude セッション**: 本ドキュメントを読んで,SmTIAS-LightSim 側の判断と次フェーズの依頼内容を把握する. -- **人間レビュー (rinto)**: 両セッションの判断整合を確認する. - -## サマリ (Summary) - -| 項目 | SmTIAS-LightSim 側の判断 | -| --- | --- | -| **SHADING_MODE** | **`HIGH_QUALITY` を本流で維持**.OFF への切替は条件付き将来オプション(後述).MiniTIAS 側の実装変更は **不要** | -| Mitsuba 出力の物理解釈 | 「LSC 適用前の生 Bayer 相当」ではなく **「ISP が完璧に LSC 補正できた場合の理想値」相当**.HIGH_QUALITY DNG と直接比較するのが物理的に整合 | -| LSC 逆適用機能 | SmTIAS-LightSim 側で **検証用ツール**として将来実装.本流の比較では使わない | -| 既存 baseline 互換性 | TECH_02 既決:**新規 baseline で再キャリブ**.既存 `MiniTIAS_20260408_144434` は参考扱い | -| 露光・ISO 目安 | **10-bit のうち中央値 500 前後**(飽和回避のため p99 < 900).現状 1/60s + ISO40 で適切か実機で要確認 | -| **作業フェーズ分け** | **フェーズ A(直近): 1 ショット撮影でシミュとの対応を先に検証** → **フェーズ B(後続): 対応が取れたら連射 UI 実装と V1 再現性検証** | -| V1 連射再現性検証 | **フェーズ B に後回し**.フェーズ A で対応の見通しが立ってから着手.解析は SmTIAS-LightSim 側 sm-evaluate に統合,MiniTIAS 側は連射 UI のみ実装(フェーズ B 時点) | -| データ転送 | **`adb pull` 推奨**.MTP 経由は禁止しないが大容量 DNG で不整合リスクあり | -| 改善案優先度 | フェーズ A 用: **画素統計・Hot pixel map** を高優先で同意.連射 UI は **フェーズ B に後回し**.他はキャリブ進捗を見て判断 | - -→ **フェーズ A** で MiniTIAS 側に追加で依頼するのは **画素統計・Hot pixel map** の 2 件と **白板 1 ショット試し撮り**のみ.連射機能はフェーズ B まで保留. - -## SHADING_MODE 判断の詳細 (SHADING_MODE Decision Rationale) - -### 結論 - -**選択肢 (1) `HIGH_QUALITY` を本流で維持**.MiniTIAS 側の現状実装をそのまま継続する. - -### 物理的整合性の説明 - -TECH_03 §SHADING_MODE 経緯では「Mitsuba 出力は LSC 適用前の生 Bayer 相当か?」という確認があったが,**実はそうではない**.Mitsuba 3 の orthographic sensor は次の特性を持つ: - -| データ | 物理的意味 | cos⁴ falloff | -| --- | --- | --- | -| Mitsuba orthographic 出力 | 各画素位置の **平行光線が交差した点からの放射輝度 L (W/m²/sr)** | **無し**(全画素平行光線のため) | -| 実機センサ生 (SHADING_OFF) | レンズ通過後のセンサ受光量 | **有り**(実物理 cos⁴ で周辺暗) | -| 実機 HIGH_QUALITY DNG | センサ生 × LSC マップ(≥1.0,周辺で大きい) | **理想的にはほぼ補正済み**(残差あり) | - -つまり: - -- **Mitsuba 出力 ≒ 「ISP が完璧に LSC 補正できた場合の理想値」相当** -- これと **HIGH_QUALITY DNG** を直接比較するのが **物理的に最も整合** -- 両者の残差 = 「実機 LSC 補正の不完全度 + シミュ物理モデルの誤差」となり,**これがまさに評価したい本質** - -逆に SHADING_OFF DNG と Mitsuba 出力を直接比較するには Mitsuba 側に物理 cos⁴ falloff を別途モデル化する必要があり,新たな自由度(絞り径・焦点距離・口径食モデル)が入る.**自由度が増えれば overfitting リスクも増える**.現状の方針(HIGH_QUALITY 維持)は overfitting 回避の観点でも妥当. - -### LSC マップの位置付け - -実装した LSC マップ取得機構 (`STATISTICS_LENS_SHADING_MAP_MODE = ON`) は本流の比較では直接使わないが,**以下の検証用途で価値が高い**: - -| 用途 | 説明 | -| --- | --- | -| 個体差検証 | 実機ごと・撮影ごとに LSC マップが変動するか確認.固定なら端末校正値,変動なら AWB 連動の動的計算 | -| 補正残差の可視化 | LSC マップが実画像のずれを完全に説明するか,残差がどの程度残るかを定量化 | -| 物理 cos⁴ との比較 | LSC マップ ≒ 物理 cos⁴ の逆数か検証.モデル化検討の物理動機として使える | -| SHADING_OFF へのフォールバック | 後述「フォールバック条件」発動時に,OFF データへの逆適用ロジックの正当性検証に使える | - -→ メタデータ JSON に LSC マップを保存し続ける現実装は **そのまま維持を依頼**. - -### 将来 SHADING_OFF 切替のフォールバック条件 - -「もし問題があったら OFF にした時の差を確認する」という運用方針を踏まえ,以下のいずれかが発生した時に SHADING_OFF 撮影の追加検証を依頼する: - -| 発動条件 | 検証目的 | -| --- | --- | -| **C1**: Mitsuba シミュ vs HIGH_QUALITY DNG の残差が **同じ条件で 10 回撮っても再現的に大きい**(CoV/勾配残差 1.5× 以上 + 形が物理的に説明できない) | LSC 補正残差が大きすぎる可能性.OFF と比較して「物理 cos⁴」と「ISP 補正残差」を切り分ける | -| **C2**: LSC マップが **撮影ごとに大きく変動**する(中央値の variation > 5% 等) | ISP が AWB と連動して動的計算している証拠.補正後 DNG の解析時にこの動的性を考慮する必要 | -| **C3**: シミュ側の Mitsuba モデル精度向上後も残差が物理的に説明できない | LSC 由来でない別要因の存在.OFF 比較で物理 cos⁴ の影響度を独立に評価 | - -これらの条件が発動した時は,MiniTIAS 側に「同一シーンを HIGH_QUALITY と OFF で 1 セット連続撮影するオプション」の追加実装を依頼する.コスト見積もり:Kotlin 側 1〜2 時間,ファイル命名規則拡張(`*_hq.dng` / `*_off.dng`). - -**現時点では発動条件未到達**.実装は不要. - -## Mitsuba 出力の物理解釈の補足 (Physical Interpretation Note) - -TECH_03 §SHADING_MODE 経緯で混乱の元になった「Mitsuba 出力 = 生 Bayer 相当か?」について,SmTIAS-LightSim 側の正式な物理モデルを整理する. - -### 現状の Mitsuba シーン構成 - -- **emitter**: LED 配置から 18 個の area emitter(位置は Fusion 360 設計 STL から抽出,[Step 8-9 参照](../06_TEST/TEST_01_キャリブレーション検証履歴.md)) -- **bsdf**: Lambertian(反射率 0.85,校正は [Step 8-6 参照](../06_TEST/TEST_01_キャリブレーション検証履歴.md)) -- **integrator**: `path` tracer(多重反射,max_depth=8) -- **sensor**: **orthographic**(平行投影,cos⁴ falloff なし) - -→ シミュ luminance.npy は「**評価板表面の物理放射輝度 L** を orthographic 平行光線でサンプリングした値」.これは「実カメラで perspective sensor + 完璧な LSC 補正が掛かった時の出力」に最も近い. - -### 厳密に言えば足りないもの - -物理的に Mitsuba 出力と HIGH_QUALITY DNG が完全一致しない理由: - -| 要因 | 影響度 | 現状の処理 | -| --- | --- | --- | -| **実機 LSC の補正残差** | 中(残差 1.6〜1.9× の主因候補) | 未モデル化.本回答で「測定して見る」方針 | -| **実機センサのキャリブレーション残差**(ホットピクセル,黒レベル変動) | 小 | TECH_03 改善案の Hot pixel map で対応予定 | -| **Mitsuba 側 Lambertian 近似の限界** | 中(実機内壁は完全 Lambertian ではない) | [Step 8-2 反射率スイープ](../06_TEST/TEST_01_キャリブレーション検証履歴.md) で限界確認済 | -| **LED 配光の Lambertian 近似** | 小〜中 | [Step 8-10/8-11 spot emitter 試行](../06_TEST/TEST_01_キャリブレーション検証履歴.md) でデータシート整合まで詰めた | -| **メッシュ離散化** | 小 | path bake 高サンプル化([TEST_04 Speed-2](../06_TEST/TEST_04_シミュレーション速度最適化履歴.md) )で評価可能だが現在は中断 | -| **sRGB OETF の有無** | 大(過去対応済) | sm-evaluate で順方向適用([Step 8-3](../06_TEST/TEST_01_キャリブレーション検証履歴.md)) | - -→ MiniTIAS 側 DNG (HIGH_QUALITY) は **10-bit linear** で sRGB OETF 未適用のはず.SmTIAS-LightSim 側で DNG 読み込み時に linear 域で評価し,比較時には Mitsuba 側も linear のまま使う(または両者に同じ OETF を適用する). - -## 作業フェーズ分け (Work Phase Strategy) - -本回答時点での研究上の優先順位として,**「シミュ vs 実機の対応がそもそも取れるか」を 1 ショットで先に確認してから連射に進む** 二段階方式を採用する. - -### 方針の根拠 - -- **連射再現性が確保できても,シミュとの対応自体が取れなければ意味が薄い** -- 1 ショット分析でフェーズ A の対応が取れない場合: - - 物理モデルの根本見直し(Mitsuba 側の物性・配光・反射特性) - - SHADING_MODE フォールバック条件 C1〜C3 の発動判断 - - シミュ側の自由度パラメータの再キャリブ -- これらは **どれも 1 ショット分析で判断できる** ことで,連射機能の有無に依らない -- 連射機能を先に実装すると「結局使わないかもしれない実装」のコストがかかるリスクがある - -### フェーズ A(直近・1 ショット対応検証) - -**目的**: 1 枚の定量モード DNG とシミュ Mitsuba 出力の対応そのものを評価する. - -**MiniTIAS 側の作業**: - -1. **白板で 1 ショット試し撮り**(現状実装で OK,追加実装なし) - - 1/60s + ISO 40 で mean が 10-bit 中央値 500 前後に収まるか確認 - - 範囲外なら露光時間 or ISO を 1〜2 通り試行 - - 確定した撮影条件と DNG + meta.json を SmTIAS-LightSim 側に共有 - -2. **画素統計を meta.json に追加**(高優先) - - mean_per_channel / max_per_channel / p99 / saturated_pixel_ratio - - 撮影直後に飽和判定したい.撮り直しの即時判定にも使える - -3. **Hot pixel map 取得**(高優先) - - `STATISTICS_HOT_PIXEL_MAP_MODE = ON` - - meta.json に座標リストを記録.SmTIAS-LightSim 側の解析でマスク - -**SmTIAS-LightSim 側の作業**: - -1. **DNG (RAW_SENSOR) 読み込み I/F の実装** (`evaluation/dng_loader.py` 想定) - - `rawpy` 等で 10-bit BGGR Bayer を展開 - - 黒レベル除去 + デモザイク - -2. **メタデータ JSON 読み込み I/F の実装** (`evaluation/metadata.py` 想定) - - `settings` / `actual` / `sensorCharacteristics` / `lscMap` の読み取り - - hot pixel マスク適用機能 - -3. **新規 baseline config の作成** (`configs/eval_baseline_quantitative.yaml`) - - 既存 baseline と並列保持 - -4. **1 ショット シミュ vs 実機 突合** - - sm-evaluate に DNG 入力経路を追加 - - 既存メトリクス(CoV / 勾配 / C/P / max-min)を 1 ショット定量モード DNG に適用 - - [TEST_01](../06_TEST/TEST_01_キャリブレーション検証履歴.md) に Step 8-13 として記録 - -**フェーズ A 完了の判定**: - -- 1 ショット定量モード DNG(10-bit linear,HIGH_QUALITY,hot pixel マスク済)と Mitsuba シミュ luminance.npy の評価指標を直接比較 -- 既存 baseline(通常モード PNG)での残差 2.1× が **どう変化するか** を観察 -- 結果次第で以下を判断: - - **残差が縮む(≤ 1.5×)**: 撮影モード変更が効いた.フェーズ B に進む - - **残差変わらず**: SHADING_MODE フォールバック条件 C1 の検討・物理モデル見直し - - **残差が増える**: 解析パイプラインの不整合(DNG 読み込み・黒レベル・デモザイク)を疑う - -### フェーズ B(後続・連射再現性検証) - -**フェーズ A で対応の見通しが立った場合のみ**着手.目的は TECH_01 検証 V1(10 連射 mean CoV < 1%)の達成. - -**MiniTIAS 側の作業**(フェーズ B 時点): - -- **連射 UI 実装**: ボタンタップ → 10 連射 → 全保存 - - ファイル命名: `MiniTIAS_QM_YYYYMMDD_HHmmss_burst{0..9}.dng` - - 連射間隔は端末性能依存.インターバル指定は不要 - - meta.json は撮影ごとに保存(10 個生成).プレビュー JPEG は 1 枚で十分 - -**SmTIAS-LightSim 側の作業**(フェーズ B 時点): - -- **再現性検証スクリプト** `scripts/verify_repeatability.py` - - 10 ショット間で mean / std / CoV / 形状指標を集計 - - V1 合格判定(mean CoV < 1%,形状指標 std < 0.005) - -役割分担の根拠:SmTIAS-LightSim 側に既存の解析基盤([`uniformity.py`](../../src/sm_tias_lightsim/uniformity.py), `evaluation/*.py`)があるので,再現性検証もそこに統合する方が将来のキャリブ作業との整合性が高い. - -### フェーズ B 着手の条件 - -- フェーズ A で「シミュ vs 実機」の対応が一定程度取れた(残差 ≤ 1.5× 程度) -- もしくはフェーズ A の結果から「連射で SN 比改善 / 平均値安定化が必要」と判断された -- いずれもフェーズ A 完了後に判断する - -## 露光時間・ISO 運用の目安 (Exposure & ISO Guideline) - -TECH_03 「露光時間 / ISO の運用」への回答: - -### 白板撮影の理想値 - -10-bit DNG (値域 0〜1023) で: - -| 指標 | 目安 | -| --- | --- | -| 黒レベル | 64(`SENSOR_BLACK_LEVEL_PATTERN`).差し引き後の値で評価 | -| **白板中央の mean**(黒レベル除去後) | **400〜600**(中央値約 500) | -| 飽和回避 | **p99 < 900**(黒レベル除去後 836) | -| SN 比 | 最大露光(飽和回避内)で改善.ただしホット画素も顕在化 | - -現状の **1/60s + ISO 40** が適切かは **実機で 1 度白板撮影して mean を確認**する必要がある.mean が 400 を下回るなら露光時間を倍にする(1/30s)または ISO を上げる.mean が 600 を超えるなら露光時間を半分(1/120s)に. - -### MiniTIAS 側の半自動キャリブ機能(TECH_03 「検討中の対応 (a)」)について - -提案された「AE を 1 回走らせて値を読み,以降固定」は **歓迎**.実装すれば以下の利点: - -- 環境光(部屋の明るさ)の影響を吸収して撮影条件を一定化 -- 白板用・舌模型用で個別校正値を保持できる -- meta.json の `settings.exposure_time_ns` / `settings.sensor_sensitivity_iso` に校正済み値を記録 - -ただし優先度は **中**(現状の手動ハードコードでも研究は進められる).連射 UI と画素統計が先. - -## 改善案優先度のフィードバック (Improvement Priority Feedback) - -TECH_03 「検討中の改善案」に対する SmTIAS-LightSim 側の優先度評価.本回答ではフェーズ A/B 分けにより **連射 UI を高優先 → フェーズ B(中優先)に降格**する点が当初提案からの修正. - -| MiniTIAS 側優先度 | 項目 | SmTIAS-LightSim 側評価 | フェーズ | 理由 | -| --- | --- | --- | --- | --- | -| 高 | 画素統計を meta.json に追加(mean/max/p99/saturated_ratio) | **同意,高** | **A** | 飽和判定がないと「定量データの有効性」が事後判断になる.撮影時に即判定したい.1 ショット分析でも必須 | -| 高 | Hot pixel map 取得 (`STATISTICS_HOT_PIXEL_MAP_MODE = ON`) | **同意,高** | **A** | 10-bit のホット画素は max/std 指標に大きく影響.マスク必須 | -| 高 | 連射機能(V1 検証用) | **降格.フェーズ A 結果次第で再評価** | **B(保留)** | 1 ショットで対応が取れることを先に確認すべき.対応が取れないなら連射しても無意味 | -| 中 | 露光時間・ISO の半自動キャリブ | **同意,中** | B 以降 | 手動ハードコードでも進められる.運用が定着した後でよい | -| 中 | レンズ・センサ校正値を meta に追加 | **同意,中** | B 以降 | DNG Exif に既に埋め込まれている分は重複.未埋め込み値のみ追加で十分 | -| 低 | Dark frame / Flat field キャリブ機能 | **同意,低** | C 以降 | 実物理 cos⁴ の独立測定として理想的だが,現状の HIGH_QUALITY 経路では LSC マップで代替可能 | - -→ **フェーズ A で MiniTIAS 側に依頼するのは「画素統計・Hot pixel map」の 2 件のみ**.連射 UI と他項目はフェーズ A 完了後に再評価. - -## データ受け渡し細部の追補 (Data Exchange Refinements) - -[TECH_02 データ受け渡し仕様](TECH_02_MiniTIAS引き継ぎ手順.md#データ受け渡し仕様-data-exchange-specification) を以下で補足する. - -### ファイル転送経路 - -- **推奨**: `adb pull /sdcard/Pictures/MiniTIAS/ ` -- **非推奨**: Windows エクスプローラ経由 MTP コピー(DNG サイズ 16MB で不整合報告あり) - -### 配置先(既存仕様の確認) - -```text -SmTIAS-LightSim/ -└── reference_measurement/ - └── quantitative/ - ├── MiniTIAS_QM_YYYYMMDD_HHmmss.dng - ├── MiniTIAS_QM_YYYYMMDD_HHmmss.meta.json - ├── MiniTIAS_QM_YYYYMMDD_HHmmss.preview.jpg # 解析対象外(任意配置) - └── MiniTIAS_QM_YYYYMMDD_HHmmss_burst{0..9}.dng # 連射時 -``` - -`reference_measurement/` は `.gitignore` 対象(個人ローカル).preview.jpg は解析不要なので配置任意. - -### 既存 baseline の参照 - -`MiniTIAS_20260408_144434.png`(通常モード)は SmTIAS-LightSim/`reference_measurement/MiniTIAS_20260408_144434/` 配下に保持.**新規定量モード baseline 取得後は参考扱い**で,本流キャリブから外す. - -## 次のフェーズの作業範囲 (Next Phase Scope) - -本回答に基づく次フェーズの作業を整理.**フェーズ A 完了後にフェーズ B への移行を判断**する. - -### フェーズ A(直近・1 ショット対応検証) - -#### MiniTIAS 側(実装依頼) - -1. **画素統計を meta.json に追加**(高優先・フェーズ A 必須) - - mean_per_channel / max_per_channel / p99 / saturated_pixel_ratio -2. **Hot pixel map 取得・meta.json に保存**(高優先・フェーズ A 必須) - - `STATISTICS_HOT_PIXEL_MAP_MODE = ON` -3. **白板で 1 ショット試し撮り → mean 確認**(露光/ISO の妥当性確認) - - mean が 400〜600(10-bit 黒レベル除去後)なら現状の 1/60s + ISO 40 で運用 - - 範囲外なら設定を調整 -4. 確定した撮影条件で **白板を 1 枚撮影** → `reference_measurement/quantitative/` へ adb pull 転送 - -> **連射 UI は不要**.本フェーズでは 1 ショット分析を優先. - -#### SmTIAS-LightSim 側(受け入れ実装) - -1. **DNG (RAW_SENSOR) 読み込み I/F の実装**(`evaluation/dng_loader.py` 新規想定) -2. **メタデータ JSON 読み込み I/F の実装**(`evaluation/metadata.py` 新規想定) -3. **LSC マップ読み込み I/F の実装**(検証用,本流では使わない) -4. **新規定量モード baseline 設定** `configs/eval_baseline_quantitative.yaml` の作成 -5. **1 ショット シミュ vs 実機の突合** - - 既存メトリクス(CoV / 勾配 / C/P / max-min)を 1 ショット DNG に適用 - - 既存通常モード baseline 残差 2.1× が定量モードで **どう変化するか** を観察 -6. [TEST_01](../06_TEST/TEST_01_キャリブレーション検証履歴.md) に **Step 8-13: 定量モード 1 ショット対応検証** として記録 - -### フェーズ A 完了判定とフェーズ B 移行条件 - -フェーズ A 完了後,1 ショット突合の結果から以下を判断: - -| 結果 | 判断 | 次の動き | -| --- | --- | --- | -| 残差が縮む(≤ 1.5×) | 撮影モード変更が効いた | フェーズ B(連射 V1 検証)に進む.連射 UI 実装依頼 | -| 残差変わらず(≈ 2.1×) | 撮影モード変更だけでは足りない | SHADING_MODE フォールバック条件 C1 検討.物理モデル見直し(LSC モデル化/反射特性/emitter 配光) | -| 残差が増える | 解析パイプラインに不整合 | DNG 読み込み・黒レベル・デモザイク・カラーマトリクスを疑う.デバッグ | - -### フェーズ B(後続・連射 V1 検証) - -**フェーズ A で対応の見通しが立った場合のみ**着手. - -#### MiniTIAS 側(フェーズ B 時点) - -- 10 連射 UI 実装(V1 検証前提) -- 連射機能で 10 ショット baseline 撮影 → `reference_measurement/quantitative/` へ転送 - -#### SmTIAS-LightSim 側(フェーズ B 時点) - -- **再現性検証スクリプト** `scripts/verify_repeatability.py` の実装 -- V1 検証実施 -- 必要に応じてキャリブ自由度(反射率・emitter 強度等)を再調整 - -## 未確定事項 (Pending Items) - -以下は本回答時点では判断保留.後続作業の進捗に応じて追加判断する: - -| ID | 内容 | 判断時期 | -| --- | --- | --- | -| P1 | DNG 内 Bayer データから RGB への展開方法(rawpy 等使用) | sm-evaluate DNG 読み込み実装時 | -| P2 | 黒レベル除去の有無(meta.json `sensorCharacteristics.black_level_pattern` で対応) | 同上 | -| P3 | デモザイク手法(最近傍 / バイリニア / AHD) | 同上.評価指標への影響を実測比較 | -| P4 | カラーマトリクス適用の有無 | 無彩色シーンでは影響軽微.本流は無適用で進める | -| P5 | 連射時の物理的振動・温度ドリフトの扱い | V1 結果次第.問題があれば連射間隔の延長等を検討 | - -## 関連ドキュメント (Related Documents) - -- [TECH_01 定量撮影モード要求仕様](TECH_01_定量撮影モード要求仕様.md) — MiniTIAS 側への原始要求 -- [TECH_02 MiniTIAS 引き継ぎ手順](TECH_02_MiniTIAS引き継ぎ手順.md) — 引き継ぎ作業ガイド -- [TECH_03 定量モード実装報告と SHADING_MODE 相談](TECH_03_定量モード実装報告とSHADING_MODE相談.md) — MiniTIAS 側からの実装報告(本回答の対象) -- [TEST_01 キャリブレーション検証履歴](../06_TEST/TEST_01_キャリブレーション検証履歴.md) — Step 8 系の経緯 -- [TEST_03 輝度マップ形状追跡](../06_TEST/TEST_03_輝度マップ形状追跡.md) — 形のずれ議論.LSC モデル化の物理動機 -- [SPEC_04 評価仕様](../04_SPEC/SPEC_04_評価仕様.md) — sm-evaluate パイプライン