diff --git a/CLAUDE.md b/CLAUDE.md index a401972..80b1c2d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ ## 開発進捗 -最新: 白板撮影モード(照明均一性評価用・DEBUG 限定)を DFK 23UX249 向けに実装(校正なしの素 RGB 撮影+飽和統計 JSON) +最新: 白板撮影モードにフルフレーム(クロップなし)保存を追加(ビネット確認用・ROI と 2 枚保存・DFK 23UX249) ※ 本欄は**最新ステップ 1 行のみ上書き更新**.詳細な進捗履歴(動機・設計判断・失敗パターン)は [docs/PROGRESS.md](docs/PROGRESS.md) に追記する.運用ルールは GUIDE_05「進捗記録の運用ルール(CLAUDE.md / PROGRESS.md)」を参照. ## 必須ルール(コード実装時) diff --git a/TIASshot/Cameras/IScam.cs b/TIASshot/Cameras/IScam.cs index 1a45bf6..c775b41 100644 --- a/TIASshot/Cameras/IScam.cs +++ b/TIASshot/Cameras/IScam.cs @@ -18,6 +18,7 @@ // Color Enhancement プロパティの GUID(DFK23UX249.xml に記載) private static readonly Guid ColorEnhancementGuid = new Guid("{3A3A8F77-6440-46CC-940A-8752B02E6C29}"); + ICImagingControl _ic; VCDRangeProperty _brightness; VCDRangeProperty _gain; @@ -233,6 +234,8 @@ snapRef.SnapSingle(TimeSpan.FromSeconds(5)); var statsList = new List(); + int fullWidth = 0; + int fullHeight = 0; for (int i = 0; i < numImages; i++) { _form.ShowMessage($"白板撮影 {i + 1} / {numImages} 枚目"); @@ -246,16 +249,24 @@ MatType.CV_8UC3, buffer.GetIntPtr())) { using (Mat imgt_full = img.T()) { + // フルフレーム(クロップなし)を保存(ビネット確認用) + var fullFilename = $"WhiteBoard_full_{i + 1:0000}.png"; + Cv2.ImWrite(Path.Combine(saveFolder, fullFilename), imgt_full); + + // フルフレームサイズを記録(全フレームで同値) + fullWidth = imgt_full.Width; + fullHeight = imgt_full.Height; + // ROI 切り出し(通常撮影と同様) roiFrame = new Mat(imgt_full, _roi).Clone(); } } - // RGB 画像(PNG)として保存(sRGB 変換なし) + // ROI 画像(PNG)として保存(sRGB 変換なし) var filename = $"WhiteBoard_{i + 1:0000}.png"; Cv2.ImWrite(Path.Combine(saveFolder, filename), roiFrame); - // 飽和統計の算出 + // 飽和統計の算出(ROI のみ) var stats = ImageStats.Calc(roiFrame); statsList.Add(stats); @@ -268,7 +279,7 @@ } // JSON サイドカー出力 - var jsonMeta = BuildWhiteBoardMeta(colorEnhancementDisabled, numImages); + var jsonMeta = BuildWhiteBoardMeta(colorEnhancementDisabled, numImages, fullWidth, fullHeight); var jsonStr = ImageStats.BuildJson(jsonMeta, statsList); File.WriteAllText( Path.Combine(saveFolder, "whiteboard_meta.json"), @@ -318,7 +329,11 @@ /// /// JSON サイドカー用の撮影条件メタ辞書を構築する. /// - private Dictionary BuildWhiteBoardMeta(bool colorEnhancementOff, int numImages) { + /// Color Enhancement を無効化した場合は true + /// 撮影枚数 + /// フルフレーム(転置後)の幅(未取得時は 0 を渡す) + /// フルフレーム(転置後)の高さ(未取得時は 0 を渡す) + private Dictionary BuildWhiteBoardMeta(bool colorEnhancementOff, int numImages, int fullWidth, int fullHeight) { var meta = new Dictionary(); meta["capture_datetime"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); meta["device_name"] = DeviceName ?? "Unknown"; @@ -328,6 +343,11 @@ meta["roi_width"] = _roi.Width; meta["roi_height"] = _roi.Height; meta["num_frames"] = numImages; + meta["full_frame_saved"] = true; + if (fullWidth > 0) + meta["full_width"] = fullWidth; + if (fullHeight > 0) + meta["full_height"] = fullHeight; // カメラプロパティ(デバイス状態ファイルの固定値を読み取り) if (_exposure != null) diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 8142a70..23b819a 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -57,4 +57,6 @@ - [x] **白板撮影モード(照明均一性評価用・DEBUG 限定)** (2026-06-07): SmTIAS との装置間比較(照明均一性評価)用に、ImagingSource DFK 23UX249 を対象とした白板撮影機能を追加。`#if DEBUG` 限定で配布版には出さない。 - 動機: SmTIAS-Evaluation 側と「TIAS の白板撮影が線形・無加工・固定設定で行えるか」を確認した回答(手元の参照資料 TECH_02/SPEC_03)に基づく実装。色を合わせるのが目的でないため**校正(チャート検出・WB 自動調整・TCC 色補正)を一切行わず素の RGB を保存**する独立撮影パスとした(既存の舌診撮影フローは不変)。 - 設計判断: 撮影前に DFK23 の Color Enhancement を OFF(非線形の色強調を排除)。飽和統計(飽和率・p99・ch別 mean/max)と撮影条件を JSON サイドカーで併置。統計算出と JSON 生成はピュアロジック(`Utils/ImageStats`)に分離し自動テスト(GUIDE_08)。実機で 10 枚撮影・Color Enhancement OFF・飽和率0・p99=181(露出適正)を確認。 + - 追加(フルフレーム保存): ビネット(周辺減光)は ROI で切り出すと四隅が消えて見えないため、フレームごとに ROI 画像(`WhiteBoard_*`)に加え**クロップなしのフルフレーム**(`WhiteBoard_full_*`)も保存。飽和統計は ROI のみ(白板領域の露出チェックが目的)。実機で full=1200×1920・ROI=1136×1528 が設定どおりと確認。 + - LSC 調査結果: DFK 23UX249 は産業用カメラで**在カメラのレンズシェーディング補正を持たない**(device-state の全プロパティに項目なし+公式仕様にも記載なし)。補正データも付加されない。→ ビネット除去は SmTIAS 推奨の「独立な一様光源でのフラットフィールド」一択(在カメラ補正は不可と確定)。 - 保留・後段: LSC/ビネット補正は未実装(JSON に「未補正」と状態記録のみ)。フラットフィールド/ダークフレーム撮影・Lucam 対応は未対応。白板撮影後に Color Enhancement が OFF のまま戻らない(同一セッションで通常撮影に戻る場合は要再起動。`finally` での状態復元は今後の検討事項)。JSON の固定状態文字列(gamma_setting 等)は device-state 由来の決め打ちで動的読取ではない。