# カメラ制御仕様 (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` の `<Lucam>` からカメラパラメータを設定して，プレビューを開始する．

### 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` の `<File/SaveFolder>` で指定する．
- `note` は「データ名」（撮影時）または「校正」（キャリブ時）．
- フォルダが存在しない場合は自動作成する．
