diff --git "a/docs/02_ENV/ENV_01_\351\226\213\347\231\272\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.md" "b/docs/02_ENV/ENV_01_\351\226\213\347\231\272\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.md" new file mode 100644 index 0000000..ff098cb --- /dev/null +++ "b/docs/02_ENV/ENV_01_\351\226\213\347\231\272\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.md" @@ -0,0 +1,114 @@ +# 開発環境構築手順 (Development Environment Setup) + +## 1. セットアップ方法の選択 (Setup Method) + +### 1-1. 自動セットアップ(推奨) + +リポジトリルートの `setup.ps1` を使用することで,Visual Studio のインストール,データフォルダの作成,NuGet パッケージの復元を自動化できる. + +**実行手順** + +1. PowerShell を管理者権限で開く. +2. リポジトリのルートに移動する. + + ```powershell + cd [リポジトリのパス] + ``` + +3. スクリプトの実行ポリシーを一時的に変更する. + + ```powershell + Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass + ``` + +4. セットアップスクリプトを実行する. + + ```powershell + .\setup.ps1 + ``` + +5. スクリプト完了後,IC Imaging Control SDK を手動でインストールする. + - 詳細は「2-2. IC Imaging Control SDK」を参照する. + +**自動化される内容** + +- Visual Studio 2022 のインストール(未インストール時のみ) + - `.vsconfig` により「.NET デスクトップ開発」ワークロードが自動で設定される. +- `C:\TIAS_Data` フォルダの作成(未作成時のみ) +- NuGet パッケージの復元 + +**自動化されない内容(手動対応が必要)** + +- IC Imaging Control SDK のインストール +- 実行時設定ファイルの配置(config.xml,カメラ設定 XML,CSV) + +### 1-2. 手動セットアップ + +スクリプトを使用しない場合は,以下のセクション 2〜4 の手順に従って手動で構築する. + +## 2. 必要なソフトウェア (Required Software) + +### 2-1. Visual Studio 2022 + +- 公式サイトからインストーラをダウンロードしてインストールする. +- ワークロード選択で「.NET デスクトップ開発」を有効にする. +- リポジトリルートの `.vsconfig` をインストーラで読み込むと,必要なワークロードが自動で提案される. + +### 2-2. IC Imaging Control SDK + +- The Imaging Source が提供するカメラ制御ライブラリ. +- ImagingSource 製カメラ(DFK33UX178,DFK23UX249)の使用に必要. +- インストール後,参照 DLL が Visual Studio から認識されることを確認する. + +### 2-3. Lumenera SDK + +- Lumenera 製カメラ(Lw110)の使用に必要. +- `lumenera.api.dll` はリポジトリ内に同梱されている. + +## 3. リポジトリのセットアップ (Repository Setup) + +1. リポジトリのクローン + + ```bash + git clone [リポジトリURL] + cd TIASshot + ``` + +2. ソリューションを開く + - `TIASshot.sln` を Visual Studio 2022 で開く. + +3. NuGet パッケージの復元 + - Visual Studio のメニューから「ビルド」→「NuGet パッケージの復元」を実行する. + - または,パッケージマネージャーコンソールで以下を実行する. + + ```bash + nuget restore TIASshot.sln + ``` + +4. ビルド + - 「ビルド」→「ソリューションのビルド」を実行し,エラーがないことを確認する. + +## 4. 実行時の準備 (Runtime Preparation) + +### 4-1. 設定ファイルの配置 + +- `TIASshot/config.xml` が実行ファイルと同じディレクトリに存在することを確認する. +- パラメータの詳細は `SPEC_02_設定ファイル仕様.md` を参照する. + +### 4-2. カメラ設定ファイルの確認 + +- ImagingSource カメラを使用する場合,以下のファイルが同ディレクトリに必要. + - `DFK33UX178.xml` + - `DFK23UX249.xml` + +### 4-3. TCC参照ファイルの確認 + +- 以下の CSV ファイルが実行ファイルと同じディレクトリに必要. + - `tcc_srgb.csv`: sRGB 変換の参照値 + - `tcc_xyz.csv`: XYZ 変換の参照値 + +### 4-4. データ保存フォルダの確認 + +- `config.xml` の `` に指定したフォルダへの書き込み権限があることを確認する. +- デフォルトは `C:\TIAS_Data`. +- `setup.ps1` を実行した場合,このフォルダは自動で作成される. diff --git "a/docs/02_ENV/ENV_01_\351\226\213\347\231\272\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" "b/docs/02_ENV/ENV_01_\351\226\213\347\231\272\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" deleted file mode 100644 index b493331..0000000 --- "a/docs/02_ENV/ENV_01_\351\226\213\347\231\272\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" +++ /dev/null @@ -1,114 +0,0 @@ -======================================================================== -開発環境構築手順 (Development Environment Setup) -======================================================================== - -1. セットアップ方法の選択 (Setup Method) ------------------------------------------------------------------------- - -1-1. 自動セットアップ(推奨) - - リポジトリルートの `setup.ps1` を使用することで,Visual Studio の - インストール,データフォルダの作成,NuGet パッケージの復元を - 自動化できる. - - ■ 実行手順 - - 1. PowerShell を管理者権限で開く. - 2. リポジトリのルートに移動する. - - $ cd [リポジトリのパス] - - 3. スクリプトの実行ポリシーを一時的に変更する. - - $ Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass - - 4. セットアップスクリプトを実行する. - - $ .\setup.ps1 - - 5. スクリプト完了後,IC Imaging Control SDK を手動でインストールする. - - 詳細は「2-2. IC Imaging Control SDK」を参照する. - - ■ 自動化される内容 - - ・Visual Studio 2022 のインストール(未インストール時のみ) - - `.vsconfig` により「.NET デスクトップ開発」ワークロードが - 自動で設定される. - ・`C:\TIAS_Data` フォルダの作成(未作成時のみ) - ・NuGet パッケージの復元 - - ■ 自動化されない内容(手動対応が必要) - - ・IC Imaging Control SDK のインストール - ・実行時設定ファイルの配置(config.xml,カメラ設定 XML,CSV) - -1-2. 手動セットアップ - - スクリプトを使用しない場合は,以下のセクション 2〜4 の手順に - 従って手動で構築する. - - -2. 必要なソフトウェア (Required Software) ------------------------------------------------------------------------- - -2-1. Visual Studio 2022 - - ・公式サイトからインストーラをダウンロードしてインストールする. - ・ワークロード選択で「.NET デスクトップ開発」を有効にする. - ・リポジトリルートの `.vsconfig` をインストーラで読み込むと, - 必要なワークロードが自動で提案される. - -2-2. IC Imaging Control SDK - - ・The Imaging Source が提供するカメラ制御ライブラリ. - ・ImagingSource 製カメラ(DFK33UX178,DFK23UX249)の使用に必要. - ・インストール後,参照 DLL が Visual Studio から認識されることを確認する. - -2-3. Lumenera SDK - - ・Lumenera 製カメラ(Lw110)の使用に必要. - ・`lumenera.api.dll` はリポジトリ内に同梱されている. - - -3. リポジトリのセットアップ (Repository Setup) ------------------------------------------------------------------------- - -1. リポジトリのクローン - - $ git clone [リポジトリURL] - $ cd TIASshot - -2. ソリューションを開く - ・`TIASshot.sln` を Visual Studio 2022 で開く. - -3. NuGet パッケージの復元 - ・Visual Studio のメニューから「ビルド」→「NuGet パッケージの復元」を実行する. - ・または,パッケージマネージャーコンソールで以下を実行する. - - $ nuget restore TIASshot.sln - -4. ビルド - ・「ビルド」→「ソリューションのビルド」を実行し,エラーがないことを確認する. - - -4. 実行時の準備 (Runtime Preparation) ------------------------------------------------------------------------- - -4-1. 設定ファイルの配置 - ・`TIASshot/config.xml` が実行ファイルと同じディレクトリに存在することを確認する. - ・パラメータの詳細は `SPEC_02_設定ファイル仕様.txt` を参照する. - -4-2. カメラ設定ファイルの確認 - ・ImagingSource カメラを使用する場合,以下のファイルが同ディレクトリに必要. - - `DFK33UX178.xml` - - `DFK23UX249.xml` - -4-3. TCC参照ファイルの確認 - ・以下の CSV ファイルが実行ファイルと同じディレクトリに必要. - - `tcc_srgb.csv`: sRGB 変換の参照値 - - `tcc_xyz.csv`: XYZ 変換の参照値 - -4-4. データ保存フォルダの確認 - ・`config.xml` の `` に指定したフォルダへの書き込み権限があることを確認する. - ・デフォルトは `C:\TIAS_Data`. - ・`setup.ps1` を実行した場合,このフォルダは自動で作成される. diff --git "a/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\346\210\220.md" "b/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\346\210\220.md" new file mode 100644 index 0000000..e3a9c28 --- /dev/null +++ "b/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\346\210\220.md" @@ -0,0 +1,72 @@ +# ディレクトリ構成 (Directory Structure) + +## 1. 全体構成 (Overview) + +``` +TIASshot/ +├── CLAUDE.md ← AI向けガイドライン(ドキュメント・コーディング規則の参照) +├── README.md ← プロジェクト概要 +├── TIASshot.sln ← Visual Studio ソリューションファイル +├── TIASshot/ ← メインプロジェクト +└── docs/ ← ドキュメント +``` + +## 2. メインプロジェクト TIASshot/ (Main Project) + +### 2-1. ソースコード + +``` +├── Program.cs ← エントリポイント +├── Form1.cs ← メインフォーム(UI・操作イベント) +├── Form1.Designer.cs ← メインフォームのデザイナー自動生成コード +├── PreviewMonitor.cs ← プレビューモニタフォーム +├── PreviewMonitor.Designer.cs ← プレビューモニタのデザイナー自動生成コード +├── CameraBase.cs ← カメラ制御の基底クラス(共通処理) +├── IScam.cs ← ImagingSource カメラの実装 +├── Lucam.cs ← Lumenera カメラの実装 +├── Config.cs ← config.xml の読み込みユーティリティ +└── LightSource.cs ← 光源(シリアル通信)制御 +``` + +### 2-2. 設定・データファイル + +``` +├── config.xml ← アプリケーション設定(パラメータ定義) +├── DFK33UX178.xml ← ImagingSource DFK33UX178 カメラ設定 +├── DFK23UX249.xml ← ImagingSource DFK23UX249 カメラ設定 +├── tcc_srgb.csv ← TCC sRGB 変換参照値(24色票×3ch) +└── tcc_xyz.csv ← TCC XYZ 変換参照値(24色票×3ch) +``` + +### 2-3. 外部ライブラリ・リソース + +``` +├── lumenera.api.dll ← Lumenera SDK(同梱) +├── lumenera.api.xml ← Lumenera SDK ドキュメント +├── CalibDone.wav ← キャリブレーション完了音 +├── OneShot.wav ← 1枚撮影完了音 +├── MultiShot.wav ← 連続撮影完了音 +└── main.ico ← アプリケーションアイコン +``` + +### 2-4. プロジェクト設定 + +``` +├── TIASshot.csproj ← プロジェクトファイル +├── App.config ← .NET アプリケーション設定 +├── packages.config ← NuGet パッケージ一覧 +└── Properties/ + ├── AssemblyInfo.cs ← アセンブリ情報 + ├── Resources.Designer.cs ← リソース自動生成コード + └── Settings.Designer.cs ← アプリ設定自動生成コード +``` + +## 3. ドキュメント docs/ (Documents) + +``` +docs/ +├── 01_GUIDE/ ← チームルール・規約(命名,Git,コーディング,コメント) +├── 02_ENV/ ← 開発環境・構成に関するドキュメント(本ディレクトリ) +├── 03_SPEC/ ← 機能仕様・設定パラメータ定義 +└── 04_TECH/ ← クラス設計・アルゴリズム等の技術設計 +``` diff --git "a/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\346\210\220.txt" "b/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\346\210\220.txt" deleted file mode 100644 index a5ec2a7..0000000 --- "a/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\346\210\220.txt" +++ /dev/null @@ -1,67 +0,0 @@ -======================================================================== -ディレクトリ構成 (Directory Structure) -======================================================================== - -1. 全体構成 (Overview) ------------------------------------------------------------------------- - - TIASshot/ - ├── CLAUDE.md ← AI向けガイドライン(ドキュメント・コーディング規則の参照) - ├── README.md ← プロジェクト概要 - ├── TIASshot.sln ← Visual Studio ソリューションファイル - ├── TIASshot/ ← メインプロジェクト - └── docs/ ← ドキュメント - - -2. メインプロジェクト TIASshot/ (Main Project) ------------------------------------------------------------------------- - -2-1. ソースコード - - ├── Program.cs ← エントリポイント - ├── Form1.cs ← メインフォーム(UI・操作イベント) - ├── Form1.Designer.cs ← メインフォームのデザイナー自動生成コード - ├── PreviewMonitor.cs ← プレビューモニタフォーム - ├── PreviewMonitor.Designer.cs ← プレビューモニタのデザイナー自動生成コード - ├── CameraBase.cs ← カメラ制御の基底クラス(共通処理) - ├── IScam.cs ← ImagingSource カメラの実装 - ├── Lucam.cs ← Lumenera カメラの実装 - ├── Config.cs ← config.xml の読み込みユーティリティ - └── LightSource.cs ← 光源(シリアル通信)制御 - -2-2. 設定・データファイル - - ├── config.xml ← アプリケーション設定(パラメータ定義) - ├── DFK33UX178.xml ← ImagingSource DFK33UX178 カメラ設定 - ├── DFK23UX249.xml ← ImagingSource DFK23UX249 カメラ設定 - ├── tcc_srgb.csv ← TCC sRGB 変換参照値(24色票×3ch) - └── tcc_xyz.csv ← TCC XYZ 変換参照値(24色票×3ch) - -2-3. 外部ライブラリ・リソース - - ├── lumenera.api.dll ← Lumenera SDK(同梱) - ├── lumenera.api.xml ← Lumenera SDK ドキュメント - ├── CalibDone.wav ← キャリブレーション完了音 - ├── OneShot.wav ← 1枚撮影完了音 - ├── MultiShot.wav ← 連続撮影完了音 - └── main.ico ← アプリケーションアイコン - -2-4. プロジェクト設定 - - ├── TIASshot.csproj ← プロジェクトファイル - ├── App.config ← .NET アプリケーション設定 - ├── packages.config ← NuGet パッケージ一覧 - └── Properties/ - ├── AssemblyInfo.cs ← アセンブリ情報 - ├── Resources.Designer.cs ← リソース自動生成コード - └── Settings.Designer.cs ← アプリ設定自動生成コード - - -3. ドキュメント docs/ (Documents) ------------------------------------------------------------------------- - - docs/ - ├── 01_GUIDE/ ← チームルール・規約(命名,Git,コーディング,コメント) - ├── 02_ENV/ ← 開発環境・構成に関するドキュメント(本ディレクトリ) - ├── 03_SPEC/ ← 機能仕様・設定パラメータ定義 - └── 04_TECH/ ← クラス設計・アルゴリズム等の技術設計 diff --git "a/docs/02_ENV/ENV_03_\344\276\235\345\255\230\343\203\251\343\202\244\343\203\226\343\203\251\343\203\252\344\270\200\350\246\247.md" "b/docs/02_ENV/ENV_03_\344\276\235\345\255\230\343\203\251\343\202\244\343\203\226\343\203\251\343\203\252\344\270\200\350\246\247.md" new file mode 100644 index 0000000..d2cd34a --- /dev/null +++ "b/docs/02_ENV/ENV_03_\344\276\235\345\255\230\343\203\251\343\202\244\343\203\226\343\203\251\343\203\252\344\270\200\350\246\247.md" @@ -0,0 +1,41 @@ +# 依存ライブラリ一覧 (Dependency List) + +## 1. 開発環境 (Development Environment) + +- IDE: Visual Studio 2022 +- ターゲットフレームワーク: .NET Framework 4.8 + +## 2. NuGet パッケージ (NuGet Packages) + +`packages.config` で管理する.Visual Studio のパッケージ復元で自動取得される. + +**OpenCvSharp4 関連** + +- `OpenCvSharp4` (4.10.0): OpenCV の C# ラッパー本体 +- `OpenCvSharp4.Extensions` (4.10.0): Bitmap 変換等の拡張機能 +- `OpenCvSharp4.runtime.win` (4.10.0): Windows 向けネイティブランタイム +- `OpenCvSharp4.Windows` (4.10.0): Windows Forms 向け統合パッケージ +- `OpenCvSharp4.WpfExtensions` (4.10.0): WPF 向け拡張機能 + +**.NET 補完ライブラリ** + +- `System.Buffers` (4.5.1) +- `System.Drawing.Common` (8.0.0) +- `System.Memory` (4.5.5) +- `System.Numerics.Vectors` (4.5.0) +- `System.Runtime.CompilerServices.Unsafe` (6.0.0) +- `System.ValueTuple` (4.5.0) + +## 3. 外部 SDK(別途インストールが必要) (External SDKs) + +**IC Imaging Control SDK (The Imaging Source)** + +- 用途: ImagingSource 製カメラの制御(DFK33UX178,DFK23UX249) +- 名前空間: `TIS.Imaging` +- インストール: The Imaging Source の公式サイトから取得する + +**Lumenera SDK** + +- 用途: Lumenera 製カメラの制御(Lw110) +- DLL: `lumenera.api.dll`(リポジトリ内に同梱) +- 別途インストール不要(同梱 DLL を参照) diff --git "a/docs/02_ENV/ENV_03_\344\276\235\345\255\230\343\203\251\343\202\244\343\203\226\343\203\251\343\203\252\344\270\200\350\246\247.txt" "b/docs/02_ENV/ENV_03_\344\276\235\345\255\230\343\203\251\343\202\244\343\203\226\343\203\251\343\203\252\344\270\200\350\246\247.txt" deleted file mode 100644 index a61c4a9..0000000 --- "a/docs/02_ENV/ENV_03_\344\276\235\345\255\230\343\203\251\343\202\244\343\203\226\343\203\251\343\203\252\344\270\200\350\246\247.txt" +++ /dev/null @@ -1,42 +0,0 @@ -======================================================================== -依存ライブラリ一覧 (Dependency List) -======================================================================== - -1. 開発環境 (Development Environment) ------------------------------------------------------------------------- -・IDE: Visual Studio 2022 -・ターゲットフレームワーク: .NET Framework 4.8 - - -2. NuGet パッケージ (NuGet Packages) ------------------------------------------------------------------------- -packages.config で管理する.Visual Studio のパッケージ復元で自動取得される. - -■ OpenCvSharp4 関連 - ・OpenCvSharp4 (4.10.0): OpenCV の C# ラッパー本体 - ・OpenCvSharp4.Extensions (4.10.0): Bitmap 変換等の拡張機能 - ・OpenCvSharp4.runtime.win (4.10.0): Windows 向けネイティブランタイム - ・OpenCvSharp4.Windows (4.10.0): Windows Forms 向け統合パッケージ - ・OpenCvSharp4.WpfExtensions (4.10.0): WPF 向け拡張機能 - -■ .NET 補完ライブラリ - ・System.Buffers (4.5.1) - ・System.Drawing.Common (8.0.0) - ・System.Memory (4.5.5) - ・System.Numerics.Vectors (4.5.0) - ・System.Runtime.CompilerServices.Unsafe (6.0.0) - ・System.ValueTuple (4.5.0) - - -3. 外部 SDK(別途インストールが必要)(External SDKs) ------------------------------------------------------------------------- - -■ IC Imaging Control SDK (The Imaging Source) - ・用途: ImagingSource 製カメラの制御(DFK33UX178,DFK23UX249) - ・名前空間: `TIS.Imaging` - ・インストール: The Imaging Source の公式サイトから取得する - -■ Lumenera SDK - ・用途: Lumenera 製カメラの制御(Lw110) - ・DLL: `lumenera.api.dll`(リポジトリ内に同梱) - ・別途インストール不要(同梱 DLL を参照) diff --git "a/docs/03_SPEC/SPEC_01_\346\251\237\350\203\275\344\273\225\346\247\230.md" "b/docs/03_SPEC/SPEC_01_\346\251\237\350\203\275\344\273\225\346\247\230.md" new file mode 100644 index 0000000..d558243 --- /dev/null +++ "b/docs/03_SPEC/SPEC_01_\346\251\237\350\203\275\344\273\225\346\247\230.md" @@ -0,0 +1,96 @@ +# 機能仕様 (Feature Specification) + +## 1. 対応カメラ (Supported Cameras) + +起動時に Lucam → ImagingSource の順で接続を試みる. + +**ImagingSource カメラ(新カメラ)** + +- 対応機種: DFK33UX178,DFK23UX249 + - ※ README には DBK33UX178 と記載されていたが,ソースコード上は DFK33UX178 として扱われている.実機の型番は要確認. +- SDK: IC Imaging Control (TIS.Imaging) +- 設定ファイル: `[デバイス名].xml`(例: `DFK33UX178.xml`) + +**Lumenera カメラ(旧カメラ)** + +- 対応機種: Lw110 +- SDK: Lumenera SDK(`lumenera.api.dll`) + +## 2. プレビュー (Preview) + +- 起動後,接続したカメラのライブ映像をメインウィンドウに表示する. +- サブモニタへのプレビュー表示にも対応する(PreviewMonitor). +- ImagingSource カメラはプレビュー時に ROI クリップを適用する. + +## 3. 自動キャリブレーション (Auto Calibration) + +プレビュー中に舌診チャートを検出すると自動でキャリブレーションを開始する. + +### 3-1. チャート検出 + +- ArUco マーカー(ID 40, 41)を使用してチャートを自動検出する. +- チャートが一定フレーム数静止したことを確認してからキャリブを開始する. + +### 3-2. ホワイトバランス調整 + +- チャートの白色票(24色票の13番)を基準にカメラのゲインを自動調整する. +- 目標値は `config.xml` の `Calib/Reference` で指定する. + +### 3-3. TCC(色変換行列)計算 + +- 24パッチの平均 RGB 値を計測し,最小二乗法(SVD)で変換行列を算出する. +- 変換次元数(多項式の次数)は `Calib/ConversionChannels` で指定する. + - 4: 1次式(R,G,B,1) + - 10: 2次式(+RG,RB,GB,R²,G²,B²) + - 17: 3次式(+R²B,R²G,G²R,G²B,B²R,B²G,RGB) +- 複数の次元数をカンマ区切りで同時に指定可能(例: `4,10,17`). +- 算出した変換行列は CSV ファイルに保存される. + +## 4. 撮影 (Shooting) + +キャリブレーション完了後に撮影ボタンが有効になる. + +**1枚撮影** + +- 撮影した画像を1枚保存する. + +**連続撮影** + +- 指定した枚数・間隔で連続撮影する. +- 枚数・間隔は UI で変更可能(デフォルト値は `config.xml` で設定). + +**保存される画像** + +- 元画像(RGB): `Shot{NO}.png` +- sRGB 変換画像: `sRGB{CN}_{NO}.jpg`(指定した次元数ぶん生成される) + +## 5. データ保存 (Data Saving) + +撮影・キャリブレーション結果は保存フォルダ以下に日時フォルダで自動保存される. + +**保存先フォルダ構成** + +- `[SaveFolder]/[日付]/[時刻]-[データ名]/` + +**キャリブレーション保存ファイル** + +- `TCC.png`: キャリブ時の画像 +- `TCC_ROIs.jpg`: チャートの ROI 確認画像 +- `TCC_RGB.csv`: チャート24色票の RGB 値 +- `TCC_sRGB{CN}.csv`: チャート24色票の sRGB 変換値 +- `Conv_RGB-sRGB{CN}.csv`: RGB→sRGB 変換行列 +- `Conv_RGB-XYZ{CN}.csv`: RGB→XYZ 変換行列 +- `Conv_sRGB-XYZ{CN}.csv`: sRGB→XYZ 変換行列 + +**撮影保存ファイル** + +- `Info.csv`: 撮影情報(カメラ型番・SN,露光時間,ゲイン等) +- `Shot{NO}.png`: 元画像(RGB) +- `sRGB{CN}_{NO}.jpg`: sRGB 変換画像 + +## 6. 光源制御 (Light Source Control) + +- シリアル通信(USB-シリアル変換)で光源の ON/OFF を制御する. +- 対応デバイス: Silicon Labs CP210x(`config.xml` で変更可能). +- キャリブレーション中は光源の切り替えが無効になる. +- 光源デバイスが見つからない場合,光源ボタンが無効化される. diff --git "a/docs/03_SPEC/SPEC_01_\346\251\237\350\203\275\344\273\225\346\247\230.txt" "b/docs/03_SPEC/SPEC_01_\346\251\237\350\203\275\344\273\225\346\247\230.txt" deleted file mode 100644 index a19d60a..0000000 --- "a/docs/03_SPEC/SPEC_01_\346\251\237\350\203\275\344\273\225\346\247\230.txt" +++ /dev/null @@ -1,92 +0,0 @@ -======================================================================== -機能仕様 (Feature Specification) -======================================================================== - -1. 対応カメラ (Supported Cameras) ------------------------------------------------------------------------- -起動時に Lucam → ImagingSource の順で接続を試みる. - -■ ImagingSource カメラ(新カメラ) - ・対応機種: DFK33UX178,DFK23UX249 - - ※ README には DBK33UX178 と記載されていたが,ソースコード上は DFK33UX178 として扱われている.実機の型番は要確認. - ・SDK: IC Imaging Control (TIS.Imaging) - ・設定ファイル: `[デバイス名].xml`(例: `DFK33UX178.xml`) - -■ Lumenera カメラ(旧カメラ) - ・対応機種: Lw110 - ・SDK: Lumenera SDK(`lumenera.api.dll`) - - -2. プレビュー (Preview) ------------------------------------------------------------------------- -・起動後,接続したカメラのライブ映像をメインウィンドウに表示する. -・サブモニタへのプレビュー表示にも対応する(PreviewMonitor). -・ImagingSource カメラはプレビュー時に ROI クリップを適用する. - - -3. 自動キャリブレーション (Auto Calibration) ------------------------------------------------------------------------- -プレビュー中に舌診チャートを検出すると自動でキャリブレーションを開始する. - -3-1. チャート検出 - ・ArUco マーカー(ID 40, 41)を使用してチャートを自動検出する. - ・チャートが一定フレーム数静止したことを確認してからキャリブを開始する. - -3-2. ホワイトバランス調整 - ・チャートの白色票(24色票の13番)を基準にカメラのゲインを自動調整する. - ・目標値は `config.xml` の `Calib/Reference` で指定する. - -3-3. TCC(色変換行列)計算 - ・24パッチの平均 RGB 値を計測し,最小二乗法(SVD)で変換行列を算出する. - ・変換次元数(多項式の次数)は `Calib/ConversionChannels` で指定する. - - 4: 1次式(R,G,B,1) - - 10: 2次式(+RG,RB,GB,R²,G²,B²) - - 17: 3次式(+R²B,R²G,G²R,G²B,B²R,B²G,RGB) - ・複数の次元数をカンマ区切りで同時に指定可能(例: `4,10,17`). - ・算出した変換行列は CSV ファイルに保存される. - - -4. 撮影 (Shooting) ------------------------------------------------------------------------- -キャリブレーション完了後に撮影ボタンが有効になる. - -■ 1枚撮影 - ・撮影した画像を1枚保存する. - -■ 連続撮影 - ・指定した枚数・間隔で連続撮影する. - ・枚数・間隔は UI で変更可能(デフォルト値は `config.xml` で設定). - -■ 保存される画像 - ・元画像(RGB): `Shot{NO}.png` - ・sRGB 変換画像: `sRGB{CN}_{NO}.jpg`(指定した次元数ぶん生成される) - - -5. データ保存 (Data Saving) ------------------------------------------------------------------------- -撮影・キャリブレーション結果は保存フォルダ以下に日時フォルダで自動保存される. - -■ 保存先フォルダ構成 - ・`[SaveFolder]/[日付]/[時刻]-[データ名]/` - -■ キャリブレーション保存ファイル - ・`TCC.png`: キャリブ時の画像 - ・`TCC_ROIs.jpg`: チャートの ROI 確認画像 - ・`TCC_RGB.csv`: チャート24色票の RGB 値 - ・`TCC_sRGB{CN}.csv`: チャート24色票の sRGB 変換値 - ・`Conv_RGB-sRGB{CN}.csv`: RGB→sRGB 変換行列 - ・`Conv_RGB-XYZ{CN}.csv`: RGB→XYZ 変換行列 - ・`Conv_sRGB-XYZ{CN}.csv`: sRGB→XYZ 変換行列 - -■ 撮影保存ファイル - ・`Info.csv`: 撮影情報(カメラ型番・SN,露光時間,ゲイン等) - ・`Shot{NO}.png`: 元画像(RGB) - ・`sRGB{CN}_{NO}.jpg`: sRGB 変換画像 - - -6. 光源制御 (Light Source Control) ------------------------------------------------------------------------- -・シリアル通信(USB-シリアル変換)で光源の ON/OFF を制御する. -・対応デバイス: Silicon Labs CP210x(`config.xml` で変更可能). -・キャリブレーション中は光源の切り替えが無効になる. -・光源デバイスが見つからない場合,光源ボタンが無効化される. diff --git "a/docs/03_SPEC/SPEC_02_\350\250\255\345\256\232\343\203\225\343\202\241\343\202\244\343\203\253\344\273\225\346\247\230.md" "b/docs/03_SPEC/SPEC_02_\350\250\255\345\256\232\343\203\225\343\202\241\343\202\244\343\203\253\344\273\225\346\247\230.md" new file mode 100644 index 0000000..58b6447 --- /dev/null +++ "b/docs/03_SPEC/SPEC_02_\350\250\255\345\256\232\343\203\225\343\202\241\343\202\244\343\203\253\344\273\225\346\247\230.md" @@ -0,0 +1,129 @@ +# 設定ファイル仕様 (Configuration File Specification) + +実行ファイルと同じディレクトリに `config.xml` を配置する. +XML のルート要素は `` とする. + +※ ファイル名・保存先のテンプレート変数: `{NO}` は4桁連番,`{CN}` は2桁の次元数に展開される. + +## 1. Lucam カメラ設定 (Lucam Camera) + +Lumenera Lw110 の初期パラメータ. + +**``** + +- ``: 露光時間 (ms) + - 例: `60.0` +- ``: マスターゲイン + - 例: `1.5` +- ``: ブルーゲイン + - 例: `2.62` +- ``: グリーンゲイン + - 例: `1.72` +- ``: レッドゲイン + - 例: `1.70` + +## 2. ImagingSource カメラ設定 (ImagingSource Camera) + +各カメラの ROI(関心領域)設定.カメラ名はデバイス名と一致させる. + +**`` / ``** + +- `` + - ``: ROI の左端座標 (px) + - ``: ROI の上端座標 (px) + - ``: ROI の幅 (px) + - ``: ROI の高さ (px) + +※ ImagingSource カメラは画像を転置してから ROI を切り出す.X・Y・W・H は転置後の座標系で指定する. + +## 3. キャリブレーション設定 (Calibration) + +**``** + +- ``: チャート固定判定の閾値 (px) + - ARマーカーの移動量がこの値未満のフレームを「静止」とみなす. + - 例: `4.0` +- ``: チャート固定判定に必要な連続静止フレーム数 + - 例: `30` +- ``: 白色票(24色票の13番)の目標 RGB 値 + - ``: ブルー目標値 (0-255) + - ``: グリーン目標値 (0-255) + - ``: レッド目標値 (0-255) + - 例: `226`(各チャンネル共通) +- ``: ホワイトバランスゲインの更新率(0.0-1.0) + - 1.0 で即時反映,値を下げると緩やかに収束する. + - 例: `0.8` +- ``: キャリブレーションに使用するフレーム数 + - 例: `100` +- ``: ゲインを更新するフレーム間隔 + - 例: `5`(5フレームごとに更新) +- ``: 変換行列の次元数 + - 4 (1次式),10 (2次式),17 (3次式) から選択する. + - カンマ区切りで複数指定可能(例: `4,10,17`). + - 詳細は `SPEC_01_機能仕様.md` の「3-3. TCC計算」を参照. + +## 4. 撮影設定 (Shot) + +**``** + +- ``: プレビューモニタの表示幅 (px) + - 例: `1280` +- ``: 連続撮影の枚数(UI の初期値) + - 例: `10` +- ``: 連続撮影の間隔 (ms)(UI の初期値) + - 例: `500` +- ``: データ名の初期値(UI のテキストボックスに表示) + - 例: `無記名` + +## 5. ファイル設定 (File) + +**``** + +- ``: データの保存先フォルダ(絶対パス) + - 例: `C:\TIAS_Data` +- ``: sRGB 変換参照値 CSV のパス + - 例: `tcc_srgb.csv` +- ``: XYZ 変換参照値 CSV のパス + - 例: `tcc_xyz.csv` +- ``: キャリブ時の画像ファイル名 + - 例: `TCC.png` +- ``: チャート ROI 確認画像ファイル名 + - 例: `TCC_ROIs.jpg` +- ``: 撮影画像ファイル名(`{NO}` で連番) + - 例: `Shot{NO}.png` +- ``: sRGB 変換画像ファイル名(`{CN}` で次元数,`{NO}` で連番) + - 例: `sRGB{CN}_{NO}.jpg` +- ``: 撮影情報 CSV のファイル名 + - 例: `Info.csv` +- ``: チャート RGB 値 CSV のファイル名 + - 例: `TCC_RGB.csv` +- ``: チャート sRGB 値 CSV のファイル名(`{CN}` で次元数) + - 例: `TCC_sRGB{CN}.csv` +- ``: RGB→sRGB 変換行列 CSV のファイル名 + - 例: `Conv_RGB-sRGB{CN}.csv` +- ``: RGB→XYZ 変換行列 CSV のファイル名 + - 例: `Conv_RGB-XYZ{CN}.csv` +- ``: sRGB→XYZ 変換行列 CSV のファイル名 + - 例: `Conv_sRGB-XYZ{CN}.csv` +- ``: RGB→XYZ 変換行列(旧形式)CSV のファイル名 + - 例: `Conv_RGB-XYZold.csv` + +## 6. 光源設定 (Light Source) + +**``** + +- ``: 光源デバイスのデバイス名(部分一致で検索) + - 例: `Silicon Labs CP210x` +- ``: シリアル通信のボーレート (bps) + - 例: `38400` + +## 7. サウンド設定 (Sound) + +**``** + +- ``: キャリブレーション完了時の効果音ファイル名 + - 例: `CalibDone.wav` +- ``: 1枚撮影完了時の効果音ファイル名 + - 例: `OneShot.wav` +- ``: 連続撮影完了時の効果音ファイル名 + - 例: `MultiShot.wav` diff --git "a/docs/03_SPEC/SPEC_02_\350\250\255\345\256\232\343\203\225\343\202\241\343\202\244\343\203\253\344\273\225\346\247\230.txt" "b/docs/03_SPEC/SPEC_02_\350\250\255\345\256\232\343\203\225\343\202\241\343\202\244\343\203\253\344\273\225\346\247\230.txt" deleted file mode 100644 index 536252e..0000000 --- "a/docs/03_SPEC/SPEC_02_\350\250\255\345\256\232\343\203\225\343\202\241\343\202\244\343\203\253\344\273\225\346\247\230.txt" +++ /dev/null @@ -1,136 +0,0 @@ -======================================================================== -設定ファイル仕様 (Configuration File Specification) -======================================================================== - -実行ファイルと同じディレクトリに `config.xml` を配置する. -XML のルート要素は `` とする. - -※ ファイル名・保存先のテンプレート変数: `{NO}` は4桁連番,`{CN}` は2桁の次元数に展開される. - - -1. Lucam カメラ設定 (Lucam Camera) ------------------------------------------------------------------------- -Lumenera Lw110 の初期パラメータ. - -■ - ・: 露光時間 (ms) - - 例: `60.0` - ・: マスターゲイン - - 例: `1.5` - ・: ブルーゲイン - - 例: `2.62` - ・: グリーンゲイン - - 例: `1.72` - ・: レッドゲイン - - 例: `1.70` - - -2. ImagingSource カメラ設定 (ImagingSource Camera) ------------------------------------------------------------------------- -各カメラの ROI(関心領域)設定.カメラ名はデバイス名と一致させる. - -■ / - ・ - - : ROI の左端座標 (px) - - : ROI の上端座標 (px) - - : ROI の幅 (px) - - : ROI の高さ (px) - ※ ImagingSource カメラは画像を転置してから ROI を切り出す. - X・Y・W・H は転置後の座標系で指定する. - - -3. キャリブレーション設定 (Calibration) ------------------------------------------------------------------------- - -■ - ・: チャート固定判定の閾値 (px) - - ARマーカーの移動量がこの値未満のフレームを「静止」とみなす. - - 例: `4.0` - ・: チャート固定判定に必要な連続静止フレーム数 - - 例: `30` - ・: 白色票(24色票の13番)の目標 RGB 値 - - : ブルー目標値 (0-255) - - : グリーン目標値 (0-255) - - : レッド目標値 (0-255) - - 例: `226`(各チャンネル共通) - ・: ホワイトバランスゲインの更新率(0.0-1.0) - - 1.0 で即時反映,値を下げると緩やかに収束する. - - 例: `0.8` - ・: キャリブレーションに使用するフレーム数 - - 例: `100` - ・: ゲインを更新するフレーム間隔 - - 例: `5`(5フレームごとに更新) - ・: 変換行列の次元数 - - 4 (1次式),10 (2次式),17 (3次式) から選択する. - - カンマ区切りで複数指定可能(例: `4,10,17`). - - 詳細は `SPEC_01_機能仕様.txt` の「3-3. TCC計算」を参照. - - -4. 撮影設定 (Shot) ------------------------------------------------------------------------- - -■ - ・: プレビューモニタの表示幅 (px) - - 例: `1280` - ・: 連続撮影の枚数(UI の初期値) - - 例: `10` - ・: 連続撮影の間隔 (ms)(UI の初期値) - - 例: `500` - ・: データ名の初期値(UI のテキストボックスに表示) - - 例: `無記名` - - -5. ファイル設定 (File) ------------------------------------------------------------------------- - -■ - ・: データの保存先フォルダ(絶対パス) - - 例: `C:\TIAS_Data` - ・: sRGB 変換参照値 CSV のパス - - 例: `tcc_srgb.csv` - ・: XYZ 変換参照値 CSV のパス - - 例: `tcc_xyz.csv` - ・: キャリブ時の画像ファイル名 - - 例: `TCC.png` - ・: チャート ROI 確認画像ファイル名 - - 例: `TCC_ROIs.jpg` - ・: 撮影画像ファイル名(`{NO}` で連番) - - 例: `Shot{NO}.png` - ・: sRGB 変換画像ファイル名(`{CN}` で次元数,`{NO}` で連番) - - 例: `sRGB{CN}_{NO}.jpg` - ・: 撮影情報 CSV のファイル名 - - 例: `Info.csv` - ・: チャート RGB 値 CSV のファイル名 - - 例: `TCC_RGB.csv` - ・: チャート sRGB 値 CSV のファイル名(`{CN}` で次元数) - - 例: `TCC_sRGB{CN}.csv` - ・: RGB→sRGB 変換行列 CSV のファイル名 - - 例: `Conv_RGB-sRGB{CN}.csv` - ・: RGB→XYZ 変換行列 CSV のファイル名 - - 例: `Conv_RGB-XYZ{CN}.csv` - ・: sRGB→XYZ 変換行列 CSV のファイル名 - - 例: `Conv_sRGB-XYZ{CN}.csv` - ・: RGB→XYZ 変換行列(旧形式)CSV のファイル名 - - 例: `Conv_RGB-XYZold.csv` - - -6. 光源設定 (Light Source) ------------------------------------------------------------------------- - -■ - ・: 光源デバイスのデバイス名(部分一致で検索) - - 例: `Silicon Labs CP210x` - ・: シリアル通信のボーレート (bps) - - 例: `38400` - - -7. サウンド設定 (Sound) ------------------------------------------------------------------------- - -■ - ・: キャリブレーション完了時の効果音ファイル名 - - 例: `CalibDone.wav` - ・: 1枚撮影完了時の効果音ファイル名 - - 例: `OneShot.wav` - ・: 連続撮影完了時の効果音ファイル名 - - 例: `MultiShot.wav` diff --git "a/docs/04_TECH/TECH_01_\343\202\257\343\203\251\343\202\271\350\250\255\350\250\210.md" "b/docs/04_TECH/TECH_01_\343\202\257\343\203\251\343\202\271\350\250\255\350\250\210.md" new file mode 100644 index 0000000..2677e8c --- /dev/null +++ "b/docs/04_TECH/TECH_01_\343\202\257\343\203\251\343\202\271\350\250\255\350\250\210.md" @@ -0,0 +1,87 @@ +# クラス設計 (Class Design) + +## 1. クラス一覧 (Class Overview) + +**CameraBase(抽象基底クラス)** + +- ファイル: `CameraBase.cs` +- カメラに共通する処理をまとめた抽象クラス. +- IScam・Lucam の両方が継承する. + +**IScam** + +- ファイル: `IScam.cs` +- ImagingSource カメラ(DFK33UX178,DFK23UX249)の実装. +- IC Imaging Control SDK(`TIS.Imaging`)を使用する. + +**Lucam** + +- ファイル: `Lucam.cs` +- Lumenera カメラ(Lw110)の実装. +- Lumenera SDK(`lumenera.api.dll`)を使用する. + +**Form1** + +- ファイル: `Form1.cs` +- メインウィンドウ.UI イベントの受け取りとカメラ・光源の操作を担う. + +**PreviewMonitor** + +- ファイル: `PreviewMonitor.cs` +- サブモニタへのプレビュー表示フォーム. + +**Config(静的クラス)** + +- ファイル: `Config.cs` +- `config.xml` の読み込みユーティリティ. +- XPath を使って文字列・整数・浮動小数点数の値を取得する. + +**LightSource** + +- ファイル: `LightSource.cs` +- シリアル通信(USB-シリアル変換)による光源の ON/OFF 制御. + +## 2. 継承関係 (Inheritance) + +``` +CameraBase(抽象) +├── IScam ← ImagingSource カメラ +└── Lucam ← Lumenera カメラ +``` + +## 3. CameraBase の主なメンバ (CameraBase Members) + +### 3-1. 抽象メソッド(派生クラスで実装する) + +- `Connect() : bool`: カメラに接続する +- `Disconnect()`: カメラを切断する +- `Shot(numImages, interval)`: 撮影処理 + +### 3-2. 公開メソッド + +- `ShotOne()`: 1枚撮影 +- `ShotMulti()`: 連続撮影 + +### 3-3. 保護メソッド(派生クラスから呼ぶ) + +- `BootCheck() : bool`: 起動時の前提条件チェック(設定・TCC参照ファイル) +- `DetectChart(img)`: ArUco マーカーによるチャート検出 +- `CalcTcc(img)`: TCC 変換行列の計算・保存 +- `ConvertImage(src, conv) : Mat`: 画像の色変換 +- `SaveThread(numImages)`: 画像保存スレッド処理 +- `GetRatio(value, target) : float`: ゲイン更新比率の計算 + +### 3-4. 主なフィールド + +- `_calibrating`: キャリブレーション残りフレーム数(0 で完了) +- `_calibrated`: キャリブレーション完了フラグ +- `_chartMasks`: 24色票の ROI マスクリスト +- `_convRGB2SRGB`: 次元数をキーとした RGB→sRGB 変換行列の辞書 +- `_roi`: ROI 矩形(IScam のみ使用) +- `_shots`: 撮影済み画像バッファ + +## 4. Form1 とカメラの関係 (Form1 and Camera) + +- Form1 は `CameraBase` 型の `_camera` フィールドを持つ. +- 起動時に Lucam → IScam の順で接続を試みる(詳細は `TECH_02` 参照). +- UI スレッドとカメラスレッドをまたぐメソッド(`ShowMessage`,`EnableShots` 等)は `InvokeRequired` を確認してスレッドセーフに呼び出す. diff --git "a/docs/04_TECH/TECH_01_\343\202\257\343\203\251\343\202\271\350\250\255\350\250\210.txt" "b/docs/04_TECH/TECH_01_\343\202\257\343\203\251\343\202\271\350\250\255\350\250\210.txt" deleted file mode 100644 index 217c822..0000000 --- "a/docs/04_TECH/TECH_01_\343\202\257\343\203\251\343\202\271\350\250\255\350\250\210.txt" +++ /dev/null @@ -1,83 +0,0 @@ -======================================================================== -クラス設計 (Class Design) -======================================================================== - -1. クラス一覧 (Class Overview) ------------------------------------------------------------------------- - -■ CameraBase(抽象基底クラス) - ・ファイル: `CameraBase.cs` - ・カメラに共通する処理をまとめた抽象クラス. - ・IScam・Lucam の両方が継承する. - -■ IScam - ・ファイル: `IScam.cs` - ・ImagingSource カメラ(DFK33UX178,DFK23UX249)の実装. - ・IC Imaging Control SDK(`TIS.Imaging`)を使用する. - -■ Lucam - ・ファイル: `Lucam.cs` - ・Lumenera カメラ(Lw110)の実装. - ・Lumenera SDK(`lumenera.api.dll`)を使用する. - -■ Form1 - ・ファイル: `Form1.cs` - ・メインウィンドウ.UI イベントの受け取りとカメラ・光源の操作を担う. - -■ PreviewMonitor - ・ファイル: `PreviewMonitor.cs` - ・サブモニタへのプレビュー表示フォーム. - -■ Config(静的クラス) - ・ファイル: `Config.cs` - ・`config.xml` の読み込みユーティリティ. - ・XPath を使って文字列・整数・浮動小数点数の値を取得する. - -■ LightSource - ・ファイル: `LightSource.cs` - ・シリアル通信(USB-シリアル変換)による光源の ON/OFF 制御. - - -2. 継承関係 (Inheritance) ------------------------------------------------------------------------- - - CameraBase(抽象) - ├── IScam ← ImagingSource カメラ - └── Lucam ← Lumenera カメラ - - -3. CameraBase の主なメンバ (CameraBase Members) ------------------------------------------------------------------------- - -3-1. 抽象メソッド(派生クラスで実装する) - ・`Connect() : bool`: カメラに接続する - ・`Disconnect()`: カメラを切断する - ・`Shot(numImages, interval)`: 撮影処理 - -3-2. 公開メソッド - ・`ShotOne()`: 1枚撮影 - ・`ShotMulti()`: 連続撮影 - -3-3. 保護メソッド(派生クラスから呼ぶ) - ・`BootCheck() : bool`: 起動時の前提条件チェック(設定・TCC参照ファイル) - ・`DetectChart(img)`: ArUco マーカーによるチャート検出 - ・`CalcTcc(img)`: TCC 変換行列の計算・保存 - ・`ConvertImage(src, conv) : Mat`: 画像の色変換 - ・`SaveThread(numImages)`: 画像保存スレッド処理 - ・`GetRatio(value, target) : float`: ゲイン更新比率の計算 - -3-4. 主なフィールド - ・`_calibrating`: キャリブレーション残りフレーム数(0 で完了) - ・`_calibrated`: キャリブレーション完了フラグ - ・`_chartMasks`: 24色票の ROI マスクリスト - ・`_convRGB2SRGB`: 次元数をキーとした RGB→sRGB 変換行列の辞書 - ・`_roi`: ROI 矩形(IScam のみ使用) - ・`_shots`: 撮影済み画像バッファ - - -4. Form1 とカメラの関係 (Form1 and Camera) ------------------------------------------------------------------------- -・Form1 は `CameraBase` 型の `_camera` フィールドを持つ. -・起動時に Lucam → IScam の順で接続を試みる(詳細は `TECH_02` 参照). -・UI スレッドとカメラスレッドをまたぐメソッド(`ShowMessage`,`EnableShots` 等)は - `InvokeRequired` を確認してスレッドセーフに呼び出す. diff --git "a/docs/04_TECH/TECH_02_\343\202\253\343\203\241\343\203\251\345\210\266\345\276\241\344\273\225\346\247\230.md" "b/docs/04_TECH/TECH_02_\343\202\253\343\203\241\343\203\251\345\210\266\345\276\241\344\273\225\346\247\230.md" new file mode 100644 index 0000000..796d58f --- /dev/null +++ "b/docs/04_TECH/TECH_02_\343\202\253\343\203\241\343\203\251\345\210\266\345\276\241\344\273\225\346\247\230.md" @@ -0,0 +1,88 @@ +# カメラ制御仕様 (Camera Control Specification) + +## 1. 起動時のカメラ接続フロー (Startup Connection Flow) + +Form1 ロード時に以下の順で接続を試みる. + +1. `Lucam.Connect()` を実行する + - 成功: Lucam をアクティブカメラとして使用する + - 失敗: 次へ + +2. ImagingSource デバイス一覧を走査する + - 接続されているデバイス名を順に `IScam.Connect()` で試行する + - 最初に成功したカメラをアクティブカメラとして使用する + +3. どのカメラも接続できない場合 + - エラーダイアログを表示してアプリを終了する + +## 2. IScam(ImagingSource カメラ)の制御 (IScam Control) + +### 2-1. 接続 + +- `[デバイス名].xml` からカメラ設定をロードする. +- `config.xml` の `<カメラ名>/ROI` から ROI 設定を読み込む. +- `FrameQueueSink` をシンクに設定してライブ開始する. + +### 2-2. プレビュー(フレーム取得コールバック) + +- `FrameQueueSink` の `Retrieve` コールバックでフレームを受け取る. +- 受け取った画像を転置(`.T()`)し,ROI を切り出して表示する. +- キャリブレーション中は白色票の測定・ゲイン更新も行う(後述). + +### 2-3. ROI クリップ + +- ImagingSource カメラは横向きに画像を出力するため,転置して縦向きに変換する. +- 転置後の画像座標系で ROI(X,Y,W,H)を切り出す. + +### 2-4. 撮影 + +- シンクを `FrameQueueSink` → `FrameSnapSink` に切り替える. +- `SnapSingle()` で1フレームずつ取得して `_shots` に蓄積する. +- 撮影完了後,シンクを `FrameQueueSink` に戻す. +- 最初の1フレームは捨てる(カメラの安定待ち). + +## 3. Lucam(Lumenera カメラ)の制御 (Lucam Control) + +### 3-1. 接続 + +- `LucamNumCameras()` で接続台数を確認する(0台または2台以上はエラー). +- カメラ ID から機種を特定する(`0x49f` → Lw110). +- `LucamRgbPreviewCallback` コールバックを登録する. +- `config.xml` の `` からカメラパラメータを設定して,プレビューを開始する. + +### 3-2. プレビュー(フレーム取得コールバック) + +- `LucamRgbPreviewCallback` でフレームを受け取る. +- 受け取った画像を転置(`.T()`)して表示する(ROI クリップなし). +- キャリブレーション中は白色票の測定・ゲイン更新も行う(後述). + +### 3-3. 撮影 + +- `LucamEnableFastFrames()` でスナップ撮影モードに切り替える. +- `LucamTakeFastFrame()` でRAW画像を取得し,`LucamConvertFrameToRgb24()` でRGB変換する. +- 撮影完了後,`LucamDisableFastFrames()` で通常モードに戻す. + +## 4. ホワイトバランス自動調整 (White Balance Calibration) + +チャート検出後(`_calibrating` が `Calib/Frames` にセットされた後),各フレームで以下の処理を行う. + +1. 白色票(`_chartMasks[12]`,24色票の13番)の平均 RGB 値を測定する + +2. `Calib/UpdateInterval` フレームごとにゲインを更新する + - 更新比率: `ratio = (target / current - 1) * UpdateRate + 1` + - IScam: `VCDRangeProperty.Value` を直接更新する + - Lucam: `_snap.Gain*` を更新し `SetCameraParam()` で反映する + +3. `_calibrating` をデクリメントし,0 になったら `CalcTcc()` を呼び出す + +## 5. データ保存フォルダの生成 (Save Folder) + +`SetSaveFolder(note)` が保存先フォルダを以下の書式で生成する. + +``` +[SaveFolder]/[yyyy-MM-dd]/[HH_mm_ss]-[note]/ +``` + +- `SaveFolder` は `config.xml` の `` で指定する. +- `note` は「データ名」(撮影時)または「校正」(キャリブ時). +- フォルダが存在しない場合は自動作成する. diff --git "a/docs/04_TECH/TECH_02_\343\202\253\343\203\241\343\203\251\345\210\266\345\276\241\344\273\225\346\247\230.txt" "b/docs/04_TECH/TECH_02_\343\202\253\343\203\241\343\203\251\345\210\266\345\276\241\344\273\225\346\247\230.txt" deleted file mode 100644 index c9ec368..0000000 --- "a/docs/04_TECH/TECH_02_\343\202\253\343\203\241\343\203\251\345\210\266\345\276\241\344\273\225\346\247\230.txt" +++ /dev/null @@ -1,88 +0,0 @@ -======================================================================== -カメラ制御仕様 (Camera Control Specification) -======================================================================== - -1. 起動時のカメラ接続フロー (Startup Connection Flow) ------------------------------------------------------------------------- -Form1 ロード時に以下の順で接続を試みる. - -1. Lucam.Connect() を実行する - ・成功: Lucam をアクティブカメラとして使用する - ・失敗: 次へ - -2. ImagingSource デバイス一覧を走査する - ・接続されているデバイス名を順に IScam.Connect() で試行する - ・最初に成功したカメラをアクティブカメラとして使用する - -3. どのカメラも接続できない場合 - ・エラーダイアログを表示してアプリを終了する - - -2. IScam(ImagingSource カメラ)の制御 (IScam Control) ------------------------------------------------------------------------- - -2-1. 接続 - ・`[デバイス名].xml` からカメラ設定をロードする. - ・`config.xml` の `<カメラ名>/ROI` から ROI 設定を読み込む. - ・`FrameQueueSink` をシンクに設定してライブ開始する. - -2-2. プレビュー(フレーム取得コールバック) - ・`FrameQueueSink` の `Retrieve` コールバックでフレームを受け取る. - ・受け取った画像を転置(`.T()`)し,ROI を切り出して表示する. - ・キャリブレーション中は白色票の測定・ゲイン更新も行う(後述). - -2-3. ROI クリップ - ・ImagingSource カメラは横向きに画像を出力するため,転置して縦向きに変換する. - ・転置後の画像座標系で ROI(X,Y,W,H)を切り出す. - -2-4. 撮影 - ・シンクを `FrameQueueSink` → `FrameSnapSink` に切り替える. - ・`SnapSingle()` で1フレームずつ取得して `_shots` に蓄積する. - ・撮影完了後,シンクを `FrameQueueSink` に戻す. - ・最初の1フレームは捨てる(カメラの安定待ち). - - -3. Lucam(Lumenera カメラ)の制御 (Lucam Control) ------------------------------------------------------------------------- - -3-1. 接続 - ・`LucamNumCameras()` で接続台数を確認する(0台または2台以上はエラー). - ・カメラ ID から機種を特定する(`0x49f` → Lw110). - ・`LucamRgbPreviewCallback` コールバックを登録する. - ・`config.xml` の `` からカメラパラメータを設定して,プレビューを開始する. - -3-2. プレビュー(フレーム取得コールバック) - ・`LucamRgbPreviewCallback` でフレームを受け取る. - ・受け取った画像を転置(`.T()`)して表示する(ROI クリップなし). - ・キャリブレーション中は白色票の測定・ゲイン更新も行う(後述). - -3-3. 撮影 - ・`LucamEnableFastFrames()` でスナップ撮影モードに切り替える. - ・`LucamTakeFastFrame()` でRAW画像を取得し,`LucamConvertFrameToRgb24()` でRGB変換する. - ・撮影完了後,`LucamDisableFastFrames()` で通常モードに戻す. - - -4. ホワイトバランス自動調整 (White Balance Calibration) ------------------------------------------------------------------------- -チャート検出後(`_calibrating` が `Calib/Frames` にセットされた後), -各フレームで以下の処理を行う. - -1. 白色票(`_chartMasks[12]`,24色票の13番)の平均 RGB 値を測定する - -2. `Calib/UpdateInterval` フレームごとにゲインを更新する - ・更新比率: `ratio = (target / current - 1) * UpdateRate + 1` - ・IScam: `VCDRangeProperty.Value` を直接更新する - ・Lucam: `_snap.Gain*` を更新し `SetCameraParam()` で反映する - -3. `_calibrating` をデクリメントし,0 になったら `CalcTcc()` を呼び出す - - -5. データ保存フォルダの生成 (Save Folder) ------------------------------------------------------------------------- -`SetSaveFolder(note)` が保存先フォルダを以下の書式で生成する. - - [SaveFolder]/[yyyy-MM-dd]/[HH_mm_ss]-[note]/ - -・`SaveFolder` は `config.xml` の `` で指定する. -・`note` は「データ名」(撮影時)または「校正」(キャリブ時). -・フォルダが存在しない場合は自動作成する. diff --git "a/docs/04_TECH/TECH_03_\350\211\262\350\243\234\346\255\243\345\207\246\347\220\206\344\273\225\346\247\230.md" "b/docs/04_TECH/TECH_03_\350\211\262\350\243\234\346\255\243\345\207\246\347\220\206\344\273\225\346\247\230.md" new file mode 100644 index 0000000..30b55d3 --- /dev/null +++ "b/docs/04_TECH/TECH_03_\350\211\262\350\243\234\346\255\243\345\207\246\347\220\206\344\273\225\346\247\230.md" @@ -0,0 +1,85 @@ +# 色補正処理仕様 (Color Correction Specification) + +## 1. 処理の全体フロー (Overall Flow) + +``` +1. ArUco マーカー検出(DetectChart) + ↓ +2. チャート固定判定 + ↓ +3. ホワイトバランス自動調整(ゲイン更新) + ↓ +4. TCC 変換行列の計算(CalcTcc) + ↓ +5. 変換行列の保存・撮影の有効化 +``` + +## 2. チャート検出(DetectChart) (Chart Detection) + +### 2-1. ArUco マーカー検出 + +- 辞書: Dict4X4_50(4×4 ビット,50種) +- 使用マーカー ID: 40(チャート上端),41(チャート下端) +- 両方のマーカーが検出できない場合は処理をスキップする. +- ID40 の Y 座標が ID41 より大きい場合(上下逆)は警告を表示する. + +### 2-2. チャート固定判定 + +- ID40 の検出座標と前フレームの座標の距離を計算する. +- 距離 < `Calib/ChartSetCriteria` が `Calib/ChartSetCount` フレーム連続したら固定と判断する. +- 動きを検出したらカウントをリセットする. + +### 2-3. ホモグラフィ計算とチャートマスク作成 + +- 2つのマーカーの角点(計8点)からホモグラフィ行列を計算する. +- ホモグラフィで画像を 1545×810 px に正面化する. +- 正面化画像上で 24 色票の ROI を定義し(6列×4行,各 80×80 px),元の画像座標系に逆変換してマスクを生成する. +- 生成したマスクを `_chartMasks` リスト(インデックス 0〜23)に格納する. + +## 3. TCC 変換行列の計算(CalcTcc) (TCC Matrix Calculation) + +### 3-1. チャート RGB 値の取得 + +- `_chartMasks` を使って 24 パッチの平均 RGB 値を測定する(24×3 行列). + +### 3-2. 多項式拡張(ExtendMat) + +3チャンネル(R,G,B)を指定の次元数に拡張する. + +**次元数と項の対応** + +| 次元数 | 追加される項 | +| ------ | ------------ | +| 4 (1次式) | 1, R, G, B | +| 10 (2次式) | + RG, RB, GB, R², G², B² | +| 17 (3次式) | + R²B, R²G, G²R, G²B, B²R, B²G, RGB | + +- 各項は `ExtendChannels` テーブルで定義した3チャンネルの積として計算する. + +### 3-3. 変換行列の算出(CalcConvertMatrix) + +- 拡張行列(24×N)と目標行列(24×3)から最小二乗法(SVD分解)で変換行列(N×3)を算出する. +- `Cv2.Solve(..., DecompTypes.SVD)` を使用する. + +### 3-4. 算出する変換行列の種類 + +- RGB→sRGB: カメラ RGB から sRGB への変換行列 +- RGB→XYZ: カメラ RGB から XYZ 色空間への変換行列 +- sRGB→XYZ: sRGB から XYZ 色空間への変換行列 +- 各行列は指定した次元数ぶん計算・保存される. + +### 3-5. TCC参照値ファイル + +- `tcc_srgb.csv`: 24色票の標準 sRGB 値(24×3 行列) +- `tcc_xyz.csv`: 24色票の標準 XYZ 値(24×3 行列) +- アプリ起動時に読み込み,`CameraBase` に保持する. + +## 4. 画像の色変換(ConvertImage) (Image Color Conversion) + +1. 入力画像を `CV_64FC3`(64bit浮動小数点3チャンネル)に変換する +2. 画像を1次元(ピクセル数×3)に変形(Reshape)する +3. 多項式拡張(ExtendMat)でピクセル数×N 行列にする +4. 変換行列(N×3)を右から掛けて変換後の値を得る +5. `CV_8UC3`(8bit整数)に変換して出力する + +- 変換後の値は 0〜255 の範囲に自動クリップされる(`ConvertTo` による飽和). diff --git "a/docs/04_TECH/TECH_03_\350\211\262\350\243\234\346\255\243\345\207\246\347\220\206\344\273\225\346\247\230.txt" "b/docs/04_TECH/TECH_03_\350\211\262\350\243\234\346\255\243\345\207\246\347\220\206\344\273\225\346\247\230.txt" deleted file mode 100644 index 4a51773..0000000 --- "a/docs/04_TECH/TECH_03_\350\211\262\350\243\234\346\255\243\345\207\246\347\220\206\344\273\225\346\247\230.txt" +++ /dev/null @@ -1,82 +0,0 @@ -======================================================================== -色補正処理仕様 (Color Correction Specification) -======================================================================== - -1. 処理の全体フロー (Overall Flow) ------------------------------------------------------------------------- - - 1. ArUco マーカー検出(DetectChart) - ↓ - 2. チャート固定判定 - ↓ - 3. ホワイトバランス自動調整(ゲイン更新) - ↓ - 4. TCC 変換行列の計算(CalcTcc) - ↓ - 5. 変換行列の保存・撮影の有効化 - - -2. チャート検出(DetectChart) (Chart Detection) ------------------------------------------------------------------------- - -2-1. ArUco マーカー検出 - ・辞書: Dict4X4_50(4×4 ビット,50種) - ・使用マーカー ID: 40(チャート上端),41(チャート下端) - ・両方のマーカーが検出できない場合は処理をスキップする. - ・ID40 の Y 座標が ID41 より大きい場合(上下逆)は警告を表示する. - -2-2. チャート固定判定 - ・ID40 の検出座標と前フレームの座標の距離を計算する. - ・距離 < `Calib/ChartSetCriteria` が `Calib/ChartSetCount` フレーム連続したら固定と判断する. - ・動きを検出したらカウントをリセットする. - -2-3. ホモグラフィ計算とチャートマスク作成 - ・2つのマーカーの角点(計8点)からホモグラフィ行列を計算する. - ・ホモグラフィで画像を 1545×810 px に正面化する. - ・正面化画像上で 24 色票の ROI を定義し(6列×4行,各 80×80 px), - 元の画像座標系に逆変換してマスクを生成する. - ・生成したマスクを `_chartMasks` リスト(インデックス 0〜23)に格納する. - - -3. TCC 変換行列の計算(CalcTcc) (TCC Matrix Calculation) ------------------------------------------------------------------------- - -3-1. チャート RGB 値の取得 - ・`_chartMasks` を使って 24 パッチの平均 RGB 値を測定する(24×3 行列). - -3-2. 多項式拡張(ExtendMat) - ・3チャンネル(R,G,B)を指定の次元数に拡張する. - - ■ 次元数と項の対応 - - 4 (1次式): 1, R, G, B - - 10 (2次式): + RG, RB, GB, R², G², B² - - 17 (3次式): + R²B, R²G, G²R, G²B, B²R, B²G, RGB - - ・各項は `ExtendChannels` テーブルで定義した3チャンネルの積として計算する. - -3-3. 変換行列の算出(CalcConvertMatrix) - ・拡張行列(24×N)と目標行列(24×3)から最小二乗法(SVD分解)で変換行列(N×3)を算出する. - ・`Cv2.Solve(..., DecompTypes.SVD)` を使用する. - -3-4. 算出する変換行列の種類 - ・RGB→sRGB: カメラ RGB から sRGB への変換行列 - ・RGB→XYZ: カメラ RGB から XYZ 色空間への変換行列 - ・sRGB→XYZ: sRGB から XYZ 色空間への変換行列 - ・各行列は指定した次元数ぶん計算・保存される. - -3-5. TCC参照値ファイル - ・`tcc_srgb.csv`: 24色票の標準 sRGB 値(24×3 行列) - ・`tcc_xyz.csv`: 24色票の標準 XYZ 値(24×3 行列) - ・アプリ起動時に読み込み,`CameraBase` に保持する. - - -4. 画像の色変換(ConvertImage) (Image Color Conversion) ------------------------------------------------------------------------- - -1. 入力画像を `CV_64FC3`(64bit浮動小数点3チャンネル)に変換する -2. 画像を1次元(ピクセル数×3)に変形(Reshape)する -3. 多項式拡張(ExtendMat)でピクセル数×N 行列にする -4. 変換行列(N×3)を右から掛けて変換後の値を得る -5. `CV_8UC3`(8bit整数)に変換して出力する - -・変換後の値は 0〜255 の範囲に自動クリップされる(`ConvertTo` による飽和). diff --git "a/docs/05_PLAN/PLAN_01_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\350\250\210\347\224\273.md" "b/docs/05_PLAN/PLAN_01_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\350\250\210\347\224\273.md" new file mode 100644 index 0000000..7ff1481 --- /dev/null +++ "b/docs/05_PLAN/PLAN_01_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\350\250\210\347\224\273.md" @@ -0,0 +1,103 @@ +# リファクタリング計画 (Refactoring Plan) + +## 0. 方針 (Policy) + +- 処理の変更は一切行わない.構造の整理のみを目的とする. +- 各フェーズ完了後に必ずテストを実施し,動作が変わっていないことを確認してから次へ進む. +- テストの具体的な手順は `TEST_01_テスト仕様.md` を参照する. + +## 1. 現状の問題点 (Current Issues) + +`CameraBase.cs` に以下の責務が集中している. + +- カメラ制御の抽象定義(Connect/Disconnect/Shot) +- チャート検出(ArUco マーカー検出,ホモグラフィ計算,マスク生成) +- 色補正処理(TCC行列計算,多項式拡張,画像変換) +- ファイル I/O(CSV読み書き,保存フォルダ生成,撮影情報出力) +- サウンド再生 + +## 2. 目標とするディレクトリ構成 (Target Structure) + +``` +TIASshot/ +├── Cameras/ ← カメラ制御(CameraBase, IScam, Lucam) +├── ChartDetection/ ← チャート検出(CameraBaseから分離) +├── ColorCorrection/ ← 色補正・TCC計算(CameraBaseから分離) +├── UI/ ← フォーム(Form1, PreviewMonitor) +├── Config.cs ← 設定ファイル読み込み(変更なし) +├── LightSource.cs ← 光源制御(変更なし) +└── Program.cs ← エントリポイント(変更なし) +``` + +## 3. フェーズ構成 (Phases) + +### 3-1. フェーズ1: フォルダ整理とファイル移動 + +**作業内容** + +- 以下のフォルダを作成し,既存ファイルを移動する. + - `Cameras/` ← CameraBase.cs, IScam.cs, Lucam.cs + - `UI/` ← Form1.cs, Form1.Designer.cs, Form1.resx, PreviewMonitor.cs, PreviewMonitor.Designer.cs, PreviewMonitor.resx +- 名前空間(namespace)はそのまま `TIASshot` で統一する. +- ファイルの中身は変更しない. + +**テスト** + +- ビルドが成功することを確認する. +- アプリが起動し,カメラが接続されることを確認する(手動). + +### 3-2. フェーズ2: 色補正処理の分離 + +**作業内容** + +- `ColorCorrection/` フォルダを作成する. +- CameraBase から以下を新クラス `ColorCorrector` に切り出す. + - フィールド: `TCC_SRGB`, `TCC_XYZ`, `ChannelList`, `ExtendChannels`, `UpdateRate` + - メソッド: `ExtendMat`, `CalcConvertMatrix`, `ConvertColor`, `ConvertImage` + - メソッド: `CalcTcc`(チャート RGB 値の受け取りと行列計算・保存を担当) +- CameraBase は `ColorCorrector` を保持し,処理を委譲する. + +**テスト** + +- ビルドが成功することを確認する. +- 回帰テスト: 同一入力画像から算出した変換行列が,リファクタリング前と一致することを確認する. + - 具体的な手順は `TEST_01_テスト仕様.md` の「2. 回帰テスト」を参照する. + +### 3-3. フェーズ3: チャート検出処理の分離 + +**作業内容** + +- `ChartDetection/` フォルダを作成する. +- CameraBase から以下を新クラス `ChartDetector` に切り出す. + - フィールド: `ARDict`, `PointsDst40`, `PointsDst41`, `_detectionCount`, `_lastPosition` + - メソッド: `DetectChart` + - 出力: チャートマスクリスト(`List`)を戻り値または引数で渡す +- CameraBase は `ChartDetector` を保持し,処理を委譲する. + +**テスト** + +- ビルドが成功することを確認する. +- 回帰テスト: 保存済みの実画像を入力として,チャートマスクの位置が一致することを確認する. + - 具体的な手順は `TEST_01_テスト仕様.md` の「3. チャート検出テスト」を参照する. + +### 3-4. フェーズ4: ファイル I/O・サウンドの分離 + +**作業内容** + +- CameraBase から以下をユーティリティクラスとして切り出す(配置先は `Cameras/` または新フォルダ). + - `LoadMatFromCsv`, `SaveMatToCsv` + - `SetSaveFolder`, `WriteInfo` + - `EventSound` + +**テスト** + +- ビルドが成功することを確認する. +- 撮影からファイル保存までの一連の動作を手動で確認する. +- 保存された CSV・画像の内容がリファクタリング前と一致することを確認する. + +## 4. 共通ルール (Common Rules) + +- 各フェーズは独立したブランチではなく,`refactor/code-cleanup` ブランチ上で順に進める. +- フェーズ完了ごとにコミットする.コミットメッセージは `[clean]` タグを使用する. + - 例: `[clean] 色補正処理を ColorCorrector クラスに分離` +- テストが通らない場合は,次のフェーズに進まない. diff --git "a/docs/05_PLAN/PLAN_01_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\350\250\210\347\224\273.txt" "b/docs/05_PLAN/PLAN_01_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\350\250\210\347\224\273.txt" deleted file mode 100644 index a60c933..0000000 --- "a/docs/05_PLAN/PLAN_01_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\350\250\210\347\224\273.txt" +++ /dev/null @@ -1,102 +0,0 @@ -======================================================================== -リファクタリング計画 (Refactoring Plan) -======================================================================== - -0. 方針 (Policy) ------------------------------------------------------------------------- -・処理の変更は一切行わない.構造の整理のみを目的とする. -・各フェーズ完了後に必ずテストを実施し,動作が変わっていないことを確認してから次へ進む. -・テストの具体的な手順は `TEST_01_テスト仕様.txt` を参照する. - - -1. 現状の問題点 (Current Issues) ------------------------------------------------------------------------- -`CameraBase.cs` に以下の責務が集中している. - - ・カメラ制御の抽象定義(Connect/Disconnect/Shot) - ・チャート検出(ArUco マーカー検出,ホモグラフィ計算,マスク生成) - ・色補正処理(TCC行列計算,多項式拡張,画像変換) - ・ファイル I/O(CSV読み書き,保存フォルダ生成,撮影情報出力) - ・サウンド再生 - - -2. 目標とするディレクトリ構成 (Target Structure) ------------------------------------------------------------------------- - - TIASshot/ - ├── Cameras/ ← カメラ制御(CameraBase, IScam, Lucam) - ├── ChartDetection/ ← チャート検出(CameraBaseから分離) - ├── ColorCorrection/ ← 色補正・TCC計算(CameraBaseから分離) - ├── UI/ ← フォーム(Form1, PreviewMonitor) - ├── Config.cs ← 設定ファイル読み込み(変更なし) - ├── LightSource.cs ← 光源制御(変更なし) - └── Program.cs ← エントリポイント(変更なし) - - -3. フェーズ構成 (Phases) ------------------------------------------------------------------------- - -3-1. フェーズ1: フォルダ整理とファイル移動 - - ■ 作業内容 - ・以下のフォルダを作成し,既存ファイルを移動する. - - `Cameras/` ← CameraBase.cs, IScam.cs, Lucam.cs - - `UI/` ← Form1.cs, Form1.Designer.cs, Form1.resx, - PreviewMonitor.cs, PreviewMonitor.Designer.cs, PreviewMonitor.resx - ・名前空間(namespace)はそのまま `TIASshot` で統一する. - ・ファイルの中身は変更しない. - - ■ テスト - ・ビルドが成功することを確認する. - ・アプリが起動し,カメラが接続されることを確認する(手動). - -3-2. フェーズ2: 色補正処理の分離 - - ■ 作業内容 - ・`ColorCorrection/` フォルダを作成する. - ・CameraBase から以下を新クラス `ColorCorrector` に切り出す. - - フィールド: `TCC_SRGB`, `TCC_XYZ`, `ChannelList`, `ExtendChannels`, `UpdateRate` - - メソッド: `ExtendMat`, `CalcConvertMatrix`, `ConvertColor`, `ConvertImage` - - メソッド: `CalcTcc`(チャート RGB 値の受け取りと行列計算・保存を担当) - ・CameraBase は `ColorCorrector` を保持し,処理を委譲する. - - ■ テスト - ・ビルドが成功することを確認する. - ・回帰テスト: 同一入力画像から算出した変換行列が,リファクタリング前と一致することを確認する. - - 具体的な手順は `TEST_01_テスト仕様.txt` の「2. 回帰テスト」を参照する. - -3-3. フェーズ3: チャート検出処理の分離 - - ■ 作業内容 - ・`ChartDetection/` フォルダを作成する. - ・CameraBase から以下を新クラス `ChartDetector` に切り出す. - - フィールド: `ARDict`, `PointsDst40`, `PointsDst41`, `_detectionCount`, `_lastPosition` - - メソッド: `DetectChart` - - 出力: チャートマスクリスト(`List`)を戻り値または引数で渡す - ・CameraBase は `ChartDetector` を保持し,処理を委譲する. - - ■ テスト - ・ビルドが成功することを確認する. - ・回帰テスト: 保存済みの実画像を入力として,チャートマスクの位置が一致することを確認する. - - 具体的な手順は `TEST_01_テスト仕様.txt` の「3. チャート検出テスト」を参照する. - -3-4. フェーズ4: ファイル I/O・サウンドの分離 - - ■ 作業内容 - ・CameraBase から以下をユーティリティクラスとして切り出す(配置先は `Cameras/` または新フォルダ). - - `LoadMatFromCsv`, `SaveMatToCsv` - - `SetSaveFolder`, `WriteInfo` - - `EventSound` - - ■ テスト - ・ビルドが成功することを確認する. - ・撮影からファイル保存までの一連の動作を手動で確認する. - ・保存された CSV・画像の内容がリファクタリング前と一致することを確認する. - - -4. 共通ルール (Common Rules) ------------------------------------------------------------------------- -・各フェーズは独立したブランチではなく,`refactor/code-cleanup` ブランチ上で順に進める. -・フェーズ完了ごとにコミットする.コミットメッセージは `[clean]` タグを使用する. - - 例: `[clean] 色補正処理を ColorCorrector クラスに分離` -・テストが通らない場合は,次のフェーズに進まない. diff --git "a/docs/05_PLAN/PLAN_02_\343\203\220\343\202\260\344\277\256\346\255\243\350\250\210\347\224\273.md" "b/docs/05_PLAN/PLAN_02_\343\203\220\343\202\260\344\277\256\346\255\243\350\250\210\347\224\273.md" new file mode 100644 index 0000000..3f34971 --- /dev/null +++ "b/docs/05_PLAN/PLAN_02_\343\203\220\343\202\260\344\277\256\346\255\243\350\250\210\347\224\273.md" @@ -0,0 +1,115 @@ +# バグ修正計画 (Bug Fix Plan) + +## 0. 前提 (Prerequisites) + +- `PLAN_01_リファクタリング計画.md` の全フェーズが完了し,動作がリファクタリング前と同一であることを確認してから着手する. +- 修正は1件ずつ独立して行い,都度テストを実施する. +- コミットメッセージは `[fix]` タグを使用する. + - 例: `[fix] _shots へのスレッドセーフなアクセスに修正` + +## 1. 症状 (Symptom) + +- 連続撮影で4枚以上取得するとアプリがたまにクラッシュする. +- 再現性は不安定(毎回ではなく「たまに」落ちる). + +## 2. 原因と修正方針 (Causes and Fix Policy) + +### 2-1. 優先度1: `_shots` へのスレッドセーフでないアクセス(根本原因) + +**原因** + +`_shots`(`List`)は Shot スレッドと SaveThread から同時にアクセスされる. +`List` はスレッドセーフではないため,以下の2点で競合が発生する. + +- リサイズ競合 + - `List` の内部配列は容量が足りなくなると自動で拡張される(デフォルト容量 4 → 5枚目の Add 時に 8 に拡張). + - 拡張中に SaveThread が `_shots[saveCount]` を読むとメモリ破壊が起きる. + - 「4枚以上でたまに落ちる」という症状に一致する. +- TOCTOU(確認と使用の間の競合) + - SaveThread の `_shots.Count` チェックと `_shots[saveCount]` アクセスの間に Shot スレッドがリサイズを起こすと `IndexOutOfRangeException` が発生する. + +**修正方針** + +- `_shots` を `List` から `System.Collections.Concurrent.ConcurrentQueue` またはロック付きアクセスに変更する. +- SaveThread の待機ロジックをスレッドセーフな方法(`SemaphoreSlim` 等)に変更する. + +**テスト** + +- 連続撮影を10枚以上で複数回繰り返し,クラッシュしないことを確認する. + +### 2-2. 優先度2: `ConvertImage` 内の Mat 未 Dispose によるメモリ蓄積 + +**原因** + +`ConvertImage` 内で生成される中間 Mat(`extended`,`converted`,`convertedImage`)が Dispose されないまま残る. +1回の呼び出しで数百 MB〜1 GB 超が蓄積し,画像枚数×チャンネル数分だけ積み重なる. +(例: IScam 1840×2440,17次元,4枚連続撮影 → 数十 GB 規模) + +**修正方針** + +- `extended`,`converted`,`convertedImage` を `using` ブロックで管理して確実に Dispose する. + +**テスト** + +- タスクマネージャでメモリ使用量を監視しながら連続撮影を繰り返し,撮影ごとにメモリが増加し続けないことを確認する. + +### 2-3. 優先度3: `Parallel.For` 内での未捕捉例外 + +**原因** + +`ExtendMat` の `Parallel.For` 内で OOM 等の例外が発生した場合,`AggregateException` としてラップされて SaveThread に伝播する. +SaveThread で捕捉されなければアプリがクラッシュする. +※ 優先度2の修正でメモリ蓄積が解消されれば,発生頻度は大幅に下がる. + +**修正方針** + +- SaveThread に例外ハンドラを追加し,クラッシュではなくエラーメッセージを表示して処理を中断するようにする. +- `ExtendMat` の `Parallel.For` に try-catch を追加する. + +**テスト** + +- 例外発生時にアプリが落ちずエラーが表示されることを確認する. + +### 2-4. 優先度4: `ConvertImage` による `_shots[i]` の in-place 書き換え + +**原因** + +`ConvertImage` 内の `src.ConvertTo(src, CV_64FC3)` が `_shots[i]` 自体を CV_8UC3 から CV_64FC3 に書き換える副作用がある. +特に IScam の `new Mat(imgt_full, _roi)`(サブマトリクス)に対して in-place の型変換を行うと不正な動作を引き起こす可能性がある. +また複数チャンネルを処理する際,2回目以降は変換済みのデータに対して処理をかけることになり,変換結果が誤る. + +**修正方針** + +- `ConvertImage` の冒頭で `src` をコピーし,コピー側を変換するようにする(`src` を直接書き換えない). + +**テスト** + +- 複数チャンネル(例: `4,10,17`)で撮影し,各チャンネルの sRGB 変換画像が正しく出力されることを確認する. + +### 2-5. 優先度5: Mat 未 Dispose によるメモリリーク + +**原因 A: `_shots.Clear()` で Mat が解放されない** + +- 撮影ごとに `_shots.Clear()` が呼ばれるが,格納された Mat は Dispose されない. + +**原因 B: `_chartMasks.Clear()` で Mat が解放されない** + +- チャート再検出時に `_chartMasks.Clear()` が呼ばれるが,同様に Dispose されない. + +**修正方針** + +- Clear 前に各 Mat を Dispose するヘルパーを追加する. + +**テスト** + +- タスクマネージャでメモリ使用量を監視し,撮影・キャリブを繰り返してもメモリが増加し続けないことを確認する. + +## 3. 修正順序まとめ (Summary) + +| 順位 | 原因 | クラッシュとの関連 | +| ---- | ---- | ------------------ | +| 1 | `_shots` のスレッドセーフでないアクセス | 直接原因(「たまに落ちる」に一致) | +| 2 | `ConvertImage` 内の Mat 未 Dispose | 直接原因(OOM によるクラッシュ) | +| 3 | `Parallel.For` 内の未捕捉例外 | 間接原因(2の修正で頻度減) | +| 4 | `ConvertImage` の in-place 書き換え | 誤動作(変換結果の誤り) | +| 5 | `_shots` / `_chartMasks` の Mat 未 Dispose | メモリリーク(蓄積) | diff --git "a/docs/05_PLAN/PLAN_02_\343\203\220\343\202\260\344\277\256\346\255\243\350\250\210\347\224\273.txt" "b/docs/05_PLAN/PLAN_02_\343\203\220\343\202\260\344\277\256\346\255\243\350\250\210\347\224\273.txt" deleted file mode 100644 index 073b746..0000000 --- "a/docs/05_PLAN/PLAN_02_\343\203\220\343\202\260\344\277\256\346\255\243\350\250\210\347\224\273.txt" +++ /dev/null @@ -1,126 +0,0 @@ -======================================================================== -バグ修正計画 (Bug Fix Plan) -======================================================================== - -0. 前提 (Prerequisites) ------------------------------------------------------------------------- -・PLAN_01_リファクタリング計画.txt の全フェーズが完了し, - 動作がリファクタリング前と同一であることを確認してから着手する. -・修正は1件ずつ独立して行い,都度テストを実施する. -・コミットメッセージは `[fix]` タグを使用する. - - 例: `[fix] _shots へのスレッドセーフなアクセスに修正` - - -1. 症状 (Symptom) ------------------------------------------------------------------------- -・連続撮影で4枚以上取得するとアプリがたまにクラッシュする. -・再現性は不安定(毎回ではなく「たまに」落ちる). - - -2. 原因と修正方針 (Causes and Fix Policy) ------------------------------------------------------------------------- - -2-1. 優先度1: _shots へのスレッドセーフでないアクセス(根本原因) ------------------------------------------------------------------------- -■ 原因 - `_shots`(`List`)は Shot スレッドと SaveThread から同時にアクセスされる. - `List` はスレッドセーフではないため,以下の2点で競合が発生する. - - A. リサイズ競合 - ・`List` の内部配列は容量が足りなくなると自動で拡張される - (デフォルト容量 4 → 5枚目の Add 時に 8 に拡張). - ・拡張中に SaveThread が `_shots[saveCount]` を読むとメモリ破壊が起きる. - ・「4枚以上でたまに落ちる」という症状に一致する. - - B. TOCTOU(確認と使用の間の競合) - ・SaveThread の `_shots.Count` チェックと `_shots[saveCount]` アクセスの - 間に Shot スレッドがリサイズを起こすと `IndexOutOfRangeException` が発生する. - -■ 修正方針 - ・`_shots` を `List` から `System.Collections.Concurrent.ConcurrentQueue` - またはロック付きアクセスに変更する. - ・SaveThread の待機ロジックをスレッドセーフな方法(`SemaphoreSlim` 等)に変更する. - -■ テスト - ・連続撮影を10枚以上で複数回繰り返し,クラッシュしないことを確認する. - - -2-2. 優先度2: ConvertImage 内の Mat 未 Dispose によるメモリ蓄積 ------------------------------------------------------------------------- -■ 原因 - `ConvertImage` 内で生成される中間 Mat(`extended`,`converted`,`convertedImage`) - が Dispose されないまま残る. - 1回の呼び出しで数百 MB〜1 GB 超が蓄積し,画像枚数×チャンネル数分だけ積み重なる. - (例: IScam 1840×2440,17次元,4枚連続撮影 → 数十 GB 規模) - -■ 修正方針 - ・`extended`,`converted`,`convertedImage` を `using` ブロックで管理して - 確実に Dispose する. - -■ テスト - ・タスクマネージャでメモリ使用量を監視しながら連続撮影を繰り返し, - 撮影ごとにメモリが増加し続けないことを確認する. - - -2-3. 優先度3: Parallel.For 内での未捕捉例外 ------------------------------------------------------------------------- -■ 原因 - `ExtendMat` の `Parallel.For` 内で OOM 等の例外が発生した場合, - `AggregateException` としてラップされて SaveThread に伝播する. - SaveThread で捕捉されなければアプリがクラッシュする. - ※ 優先度2の修正でメモリ蓄積が解消されれば,発生頻度は大幅に下がる. - -■ 修正方針 - ・SaveThread に例外ハンドラを追加し,クラッシュではなくエラーメッセージを - 表示して処理を中断するようにする. - ・`ExtendMat` の `Parallel.For` に try-catch を追加する. - -■ テスト - ・例外発生時にアプリが落ちずエラーが表示されることを確認する. - - -2-4. 優先度4: ConvertImage による _shots[i] の in-place 書き換え ------------------------------------------------------------------------- -■ 原因 - `ConvertImage` 内の `src.ConvertTo(src, CV_64FC3)` が `_shots[i]` 自体を - CV_8UC3 から CV_64FC3 に書き換える副作用がある. - 特に IScam の `new Mat(imgt_full, _roi)`(サブマトリクス)に対して - in-place の型変換を行うと不正な動作を引き起こす可能性がある. - また複数チャンネルを処理する際,2回目以降は変換済みのデータに対して - 処理をかけることになり,変換結果が誤る. - -■ 修正方針 - ・`ConvertImage` の冒頭で `src` をコピーし,コピー側を変換するようにする. - (`src` を直接書き換えない) - -■ テスト - ・複数チャンネル(例: `4,10,17`)で撮影し,各チャンネルの sRGB 変換画像が - 正しく出力されることを確認する. - - -2-5. 優先度5: Mat 未 Dispose によるメモリリーク ------------------------------------------------------------------------- -■ 原因 A: _shots.Clear() で Mat が解放されない - ・撮影ごとに `_shots.Clear()` が呼ばれるが,格納された Mat は Dispose されない. - -■ 原因 B: _chartMasks.Clear() で Mat が解放されない - ・チャート再検出時に `_chartMasks.Clear()` が呼ばれるが,同様に Dispose されない. - -■ 修正方針 - ・Clear 前に各 Mat を Dispose するヘルパーを追加する. - -■ テスト - ・タスクマネージャでメモリ使用量を監視し,撮影・キャリブを繰り返しても - メモリが増加し続けないことを確認する. - - -3. 修正順序まとめ (Summary) ------------------------------------------------------------------------- - - 順位 原因 クラッシュとの関連 - ---- -------------------------------------- ------------------ - 1 _shots のスレッドセーフでないアクセス 直接原因(「たまに落ちる」に一致) - 2 ConvertImage 内の Mat 未 Dispose 直接原因(OOM によるクラッシュ) - 3 Parallel.For 内の未捕捉例外 間接原因(2の修正で頻度減) - 4 ConvertImage の in-place 書き換え 誤動作(変換結果の誤り) - 5 _shots / _chartMasks の Mat 未 Dispose メモリリーク(蓄積) diff --git "a/docs/06_TEST/TEST_01_\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.md" "b/docs/06_TEST/TEST_01_\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.md" new file mode 100644 index 0000000..f8860d5 --- /dev/null +++ "b/docs/06_TEST/TEST_01_\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.md" @@ -0,0 +1,91 @@ +# テスト仕様 (Test Specification) + +## 0. 方針 (Policy) + +リファクタリングによって処理が変わっていないことを確認するためのテスト仕様. +各フェーズの適用タイミングは `PLAN_01_リファクタリング計画.md` を参照する. + +テストの種類: + +- ビルドテスト: コンパイルエラーがないことを確認する +- 回帰テスト: リファクタリング前後の出力が一致することを確認する +- 手動テスト: 実機を使って動作を目視確認する + +## 1. ビルドテスト (Build Test) + +全フェーズで実施する. + +**手順** + +1. Visual Studio で「ビルド」→「ソリューションのビルド」を実行する +2. エラーが0件であることを確認する +3. 警告が増加していないことを確認する(リファクタリング前の警告数を記録しておく) + +**合格条件** + +- ビルドエラーが0件 + +## 2. 回帰テスト: 色補正処理(フェーズ2) + +リファクタリング前に基準データを作成し,リファクタリング後の出力と比較する. + +### 2-1. 基準データの作成(リファクタリング前に実施) + +1. 実機でキャリブレーションを実行する +2. 保存された以下のファイルを「基準データ」として別フォルダに保管する + - `TCC_RGB.csv` ← チャート24色票のRGB値 + - `Conv_RGB-sRGB{CN}.csv` ← RGB→sRGB 変換行列 + - `Conv_RGB-XYZ{CN}.csv` ← RGB→XYZ 変換行列 + - `Conv_sRGB-XYZ{CN}.csv` ← sRGB→XYZ 変換行列 + - `TCC_sRGB{CN}.csv` ← チャートのsRGB変換値 + - `sRGB{CN}_0001.jpg` ← 撮影した sRGB 変換画像1枚 + +### 2-2. 比較(リファクタリング後に実施) + +1. 同一のキャリブレーション画像・撮影条件で再度実行する + - ※ 実機でのキャリブレーション再現が困難な場合は,TCC_RGB.csv を直接入力として行列計算のみ比較する +2. 基準データと出力ファイルを比較する + +**合格条件** + +- CSV の数値が全行・全列で一致する(または浮動小数点誤差 ±1e-6 以内) +- 画像のピクセル値が全ピクセルで一致する + +## 3. チャート検出テスト(フェーズ3) + +保存済みの実画像を入力として,チャートマスクの位置を比較する. + +### 3-1. 基準データの作成(リファクタリング前に実施) + +1. キャリブレーション時に保存される `TCC_ROIs.jpg` を基準データとして保管する + - ※ TCC_ROIs.jpg はチャートの ROI マスク位置を緑色で重ねた確認画像 + +### 3-2. 比較(リファクタリング後に実施) + +1. 同一条件でキャリブレーションを実行する +2. 出力された `TCC_ROIs.jpg` を基準データと目視比較する + - ※ 緑色のマスク位置が完全に一致していることを確認する + +**合格条件** + +- マスクの位置・形状が基準データと目視で一致する + +## 4. 手動テスト(全フェーズ) + +実機を使った動作確認.フェーズごとに実施する. + +**確認項目** + +- アプリが正常に起動する +- カメラが自動で接続される(Lucam または ImagingSource) +- プレビューが表示される +- 舌診チャートを映すとキャリブレーションが自動開始される +- キャリブレーション完了後に撮影ボタンが有効になる +- 1枚撮影が正常に完了し,ファイルが保存される +- 連続撮影が正常に完了し,ファイルが保存される +- 光源の ON/OFF が切り替わる +- アプリを閉じてもエラーが出ない + +**合格条件** + +- 上記の全項目でエラー・クラッシュが発生しない diff --git "a/docs/06_TEST/TEST_01_\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.txt" "b/docs/06_TEST/TEST_01_\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.txt" deleted file mode 100644 index 516ae3f..0000000 --- "a/docs/06_TEST/TEST_01_\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.txt" +++ /dev/null @@ -1,87 +0,0 @@ -======================================================================== -テスト仕様 (Test Specification) -======================================================================== - -0. 方針 (Policy) ------------------------------------------------------------------------- -リファクタリングによって処理が変わっていないことを確認するためのテスト仕様. -各フェーズの適用タイミングは `PLAN_01_リファクタリング計画.txt` を参照する. - -テストの種類: - ・ビルドテスト: コンパイルエラーがないことを確認する - ・回帰テスト: リファクタリング前後の出力が一致することを確認する - ・手動テスト: 実機を使って動作を目視確認する - - -1. ビルドテスト (Build Test) ------------------------------------------------------------------------- -全フェーズで実施する. - -■ 手順 - 1. Visual Studio で「ビルド」→「ソリューションのビルド」を実行する - 2. エラーが0件であることを確認する - 3. 警告が増加していないことを確認する(リファクタリング前の警告数を記録しておく) - -■ 合格条件 - ・ビルドエラーが0件 - - -2. 回帰テスト: 色補正処理(フェーズ2) ------------------------------------------------------------------------- -リファクタリング前に基準データを作成し,リファクタリング後の出力と比較する. - -2-1. 基準データの作成(リファクタリング前に実施) - 1. 実機でキャリブレーションを実行する - 2. 保存された以下のファイルを「基準データ」として別フォルダに保管する - ・`TCC_RGB.csv` ← チャート24色票のRGB値 - ・`Conv_RGB-sRGB{CN}.csv` ← RGB→sRGB 変換行列 - ・`Conv_RGB-XYZ{CN}.csv` ← RGB→XYZ 変換行列 - ・`Conv_sRGB-XYZ{CN}.csv` ← sRGB→XYZ 変換行列 - ・`TCC_sRGB{CN}.csv` ← チャートのsRGB変換値 - ・`sRGB{CN}_0001.jpg` ← 撮影した sRGB 変換画像1枚 - -2-2. 比較(リファクタリング後に実施) - 1. 同一のキャリブレーション画像・撮影条件で再度実行する - ※ 実機でのキャリブレーション再現が困難な場合は, - TCC_RGB.csv を直接入力として行列計算のみ比較する - 2. 基準データと出力ファイルを比較する - -■ 合格条件 - ・CSV の数値が全行・全列で一致する(または浮動小数点誤差 ±1e-6 以内) - ・画像のピクセル値が全ピクセルで一致する - - -3. チャート検出テスト(フェーズ3) ------------------------------------------------------------------------- -保存済みの実画像を入力として,チャートマスクの位置を比較する. - -3-1. 基準データの作成(リファクタリング前に実施) - 1. キャリブレーション時に保存される `TCC_ROIs.jpg` を基準データとして保管する - ※ TCC_ROIs.jpg はチャートの ROI マスク位置を緑色で重ねた確認画像 - -3-2. 比較(リファクタリング後に実施) - 1. 同一条件でキャリブレーションを実行する - 2. 出力された `TCC_ROIs.jpg` を基準データと目視比較する - ※ 緑色のマスク位置が完全に一致していることを確認する - -■ 合格条件 - ・マスクの位置・形状が基準データと目視で一致する - - -4. 手動テスト(全フェーズ) ------------------------------------------------------------------------- -実機を使った動作確認.フェーズごとに実施する. - -■ 確認項目 - ・アプリが正常に起動する - ・カメラが自動で接続される(Lucam または ImagingSource) - ・プレビューが表示される - ・舌診チャートを映すとキャリブレーションが自動開始される - ・キャリブレーション完了後に撮影ボタンが有効になる - ・1枚撮影が正常に完了し,ファイルが保存される - ・連続撮影が正常に完了し,ファイルが保存される - ・光源の ON/OFF が切り替わる - ・アプリを閉じてもエラーが出ない - -■ 合格条件 - ・上記の全項目でエラー・クラッシュが発生しない