Newer
Older
SmTIAS-Capture / docs / 05_TECH / TECH_03_定量モード実装報告とSHADING_MODE相談.md

定量モード実装報告と SHADING_MODE 相談 (Implementation Report & SHADING_MODE Consultation)

本ドキュメントは TECH_01 定量撮影モード要求仕様 を MiniTIAS リポジトリで実装した結果の MiniTIAS 側からの報告書 であり,併せて SmTIAS-LightSim 側との方針確認・相談事項 をまとめたものである.

想定読者 (Intended Reader)

  • SmTIAS-LightSim 側 Claude セッション: 本ドキュメントを読んで MiniTIAS 側の実装状況を把握し,未確定事項に対する判断・指示を返す
  • 人間レビュー (rinto): 両セッションを橋渡しし,研究方針に照らして判断する

概要 (Overview)

MiniTIAS 側で TECH_01 の要求仕様に基づいた 定量撮影モード(DNG 経路) の実装が完了した(MiniTias リポジトリ master ブランチ に取り込み済み).本ドキュメントの目的は以下の 2 点:

  1. 実装結果の報告:TECH_01 の各 Phase に対して何を実装したか,AQUOS sense3 (SH-02M) で何が確認できたかを共有する
  2. SHADING_MODE の扱いの相談:定量モードのキー設定である SHADING_MODE を MiniTIAS 側でどう選んだか,研究上どのような含意があるか,SmTIAS-LightSim 側の解析パイプラインとの整合を確認したい

TECH_01 要求に対する実装状況 (Implementation Status)

Phase要求実装状況
Phase 1Camera2 詳細制御の MethodChannel 実装(露光・WB 固定,LSC マップ取得)✅ 完了
Phase 2LSC マップ・メタデータ保存ロジック✅ 完了
Phase 3撮影画面 UI に定量モードトグル追加⚠️ 仕様変更(後述).トグル UI は追加せず通常モードを置換
Phase 4ハードウェアサポート判定とユーザー案内✅ 診断機能を DiagnosticsProvider として実装(UI 非表示.裏で再利用可能)
Phase 5RAW_SENSOR (DNG) 対応(任意)✅ 完了.第 1 優先経路として採用

Phase 3 の変更点

TECH_01 では「撮影モード切替トグル」で通常モードと定量モードを並存させる想定だったが,MiniTIAS 側の運用判断として 通常モード(PNG 経路)を temporarily に無効化し,シャッターは常に定量モードを呼ぶ構成にした.既存の captureFullResolutionPng コードは温存している.

理由:

  • MiniTIAS の運用上の存在意義は SmTIAS-LightSim との定量比較のみ
  • トグル UI を残すと「誤って通常モードで撮影してしまい後で気付く」事故が起きる
  • 研究フェーズ完了後にトグル追加 or 通常モード復活は容易

実装した撮影設定 (Camera2 CaptureRequest)

キー設定値備考
CONTROL_MODEOFFマニュアル全制御
CONTROL_AE_MODEOFF自動露光停止
SENSOR_EXPOSURE_TIME16,666,666 ns(= 1/60 s)ハードコード.後段で半自動キャリブ機能の追加を検討中
SENSOR_SENSITIVITY40(センサ最低 ISO)診断で確認したセンサのレンジ最低値
SENSOR_FRAME_DURATION33,333,333 ns(30fps 相当)露光時間 ≤ frame duration を満たす任意値
BLACK_LEVEL_LOCKtrueフレーム間で黒レベルのドリフトを抑える
CONTROL_AWB_MODEOFF自動 WB 停止
COLOR_CORRECTION_MODETRANSFORM_MATRIXマニュアル制御モード
COLOR_CORRECTION_GAINSRggbChannelVector(1.0, 1.0, 1.0, 1.0)RAW 出力では Bayer 値に効かないが request 値として明示
COLOR_CORRECTION_TRANSFORM単位行列(ColorSpaceTransform同上
NOISE_REDUCTION_MODEOFFNR による画素値の改変を防ぐ
EDGE_MODEOFFエッジ強調を防ぐ
TONEMAP_MODECONTRAST_CURVEカーブは R/G/B すべて線形 [(0,0),(1,1)]
SHADING_MODEHIGH_QUALITY★後述の相談対象.OFF も技術的に可能
STATISTICS_LENS_SHADING_MAP_MODEONLSC マップを CaptureResult に含める
CONTROL_AF_MODEOFFAQUOS sense3 のフロントカメラは固定焦点で OFF のみサポート
FLASH_MODEOFFLED はアタッチメント側で制御
CONTROL_VIDEO_STABILIZATION_MODEOFF手ブレ補正による画像ずれを防ぐ

撮影フロー (Capture Flow)

シャッター押下
   │
   ▼
プレビュー停止(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 に保存している.

主要項目

項目
INFO_SUPPORTED_HARDWARE_LEVELLEVEL_3(最上位)
REQUEST_AVAILABLE_CAPABILITIESBACKWARD_COMPATIBLE, MANUAL_SENSOR, MANUAL_POST_PROCESSING, RAW, READ_SENSOR_SETTINGS, BURST_CAPTURE, PRIVATE_REPROCESSING, YUV_REPROCESSING
SENSOR_INFO_EXPOSURE_TIME_RANGE79,806 ns 〜 871,614,530 ns(≈ 1/12530 s 〜 0.87 s)
SENSOR_INFO_SENSITIVITY_RANGE40 〜 2506
RAW_SENSOR 出力サイズ3264 × 2448(1 種類のみ)
SENSOR_INFO_COLOR_FILTER_ARRANGEMENT3 (BGGR)
SENSOR_BLACK_LEVEL_PATTERN[[64, 64], [64, 64]]
SENSOR_INFO_WHITE_LEVEL1023(10-bit)
SENSOR_INFO_PHYSICAL_SIZE3.558 mm × 2.668 mm
SENSOR_INFO_PIXEL_ARRAY_SIZE3264 × 2448
LENS_INFO_MINIMUM_FOCUS_DISTANCE0.0(無限遠固定)
LENS_INFO_HYPERFOCAL_DISTANCE0.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 から抜粋(白板を SHADING_MODE = HIGH_QUALITY で撮影したもの):

{
  "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_levelnull で返ることがある(端末依存).代わりに sensorCharacteristics.black_level_pattern の静的値を参照可
  • neutral_color_pointcolor_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 で残差 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 側からの要望順位とすり合わせて優先度を確定したい.