# 照明均一性評価アルゴリズム (Illumination Uniformity Evaluation)

## 概要 (Overview)

SmTIAS で撮影した白板画像の照明均一性を定量的に評価する．白板の白壁面領域の輝度分布を解析し，3 つの指標で均一性を定量化する．

## 輝度変換 (Luminance Conversion)

### 方法

RGB 画像を ITU-R BT.709（Rec.709）の輝度係数でグレースケールに変換する [1]．

$$Y = 0.2126 R + 0.7152 G + 0.0722 B$$

- $Y$: 輝度（0.0〜255.0, float64）
- $R, G, B$: 各チャネルの画素値（0〜255, uint8）

> **DNG 経路**: RAW_SENSOR DNG では同じ Rec.709 係数を linear 値に適用し，PNG 図と軸を揃えるため ×255 スケールで表現する（CoV・max/min・中心周辺比はスケール不変）．詳細は [TECH_01](../05_TECH/TECH_01_DNG対応要求仕様.md)．

### 選定理由

| 方法 | 定義 | 不採用の理由 |
| --- | --- | --- |
| **Rec.709（採用）** | 上記の加重平均 | — |
| V チャネル（HSV） | max(R, G, B) | 白板では R≈G≈B のため差は小さいが，規格に基づかない |
| L\*（CIE L\*a\*b\*） | 非線形変換 | 物理的な照明ムラと比例せず，照明均一性評価には不適 |

Rec.709 は人間の視感度に基づく標準的な輝度定義であり，照明工学・画像評価の分野で広く使用されている [2]．

## 均一性指標 (Uniformity Metrics)

ROI 内の全画素の輝度値から以下の 3 指標を算出する．

### CoV（変動係数）

$$\text{CoV} = \frac{\sigma}{\mu}$$

- $\mu$: 輝度の平均値
- $\sigma$: 輝度の標準偏差
- 無次元量．値が小さいほど均一
- 照明の均一性評価で広く用いられる指標 [3][4]

### 標準偏差

$$\sigma = \sqrt{\frac{1}{N} \sum_{i=1}^{N} (Y_i - \mu)^2}$$

- $N$: ROI 内の総画素数
- 輝度のばらつきの絶対値を示す
- CoV と併用することで，平均輝度の影響を考慮した評価が可能

### 最大/最小比

$$\text{Max/Min Ratio} = \frac{Y_{\max}}{Y_{\min}}$$

- 極端なムラ（局所的な明暗）の検出に有効
- 理想的な均一照明では 1.0
- $Y_{\min} = 0$ の場合は計算不能（ROI 設定の誤りを示す）

## ROI 設定 (Region of Interest)

### 対象領域

SmTIAS の開口部に白板を取り付けて撮影する．ROI は**白板の表面領域**（中央の白い四角形）とする．以下を除外する:

- 白板の外側（SmTIAS 筐体の壁面）
- 白板のフレーム・エッジ部分
- ラベル（「SmTIAS 001」等）

### 設定方法

1. `scripts/select_roi.py` で 1 枚の画像上に矩形を描いて座標を決定
2. 座標は `config/roi_config.json` に保存
3. 同一画角の全画像に同じ ROI を適用（バッチ解析）

### 起動コマンド

```bash
python scripts/select_roi.py --image data/smtias/whiteboard/<画像ファイル名>.png --config config/roi_config.json --roi smtias.whiteboard
```

OpenCV のウィンドウが開くので，マウスで矩形を選択して Enter で確定する．ESC でキャンセル．

## 空間分析 (Spatial Analysis)

ROI 内の輝度の空間的な偏り（中心-周辺勾配）を定量化する．

### 正規化楕円距離マップ

各ピクセルについて，ROI 中心からの正規化楕円距離 $d$ を算出する．

$$d(x, y) = \sqrt{\left(\frac{x - c_x}{c_x}\right)^2 + \left(\frac{y - c_y}{c_y}\right)^2}$$

- $c_x = W/2$, $c_y = H/2$: ROI の中心座標
- 値域を $[0, 1]$ に再正規化（$d \leftarrow d / d_{\max}$）
- 楕円距離を使用することで，縦横比が異なる ROI でも等方的な評価が可能

### 3 ゾーン分類

正規化距離の閾値で ROI を 3 つの同心楕円ゾーンに分割する．

| ゾーン | ラベル | 距離条件 |
| --- | --- | --- |
| Center（中心） | 0 | $d < 0.33$ |
| Middle（中間） | 1 | $0.33 \leq d < 0.66$ |
| Periphery（周辺） | 2 | $0.66 \leq d$ |

閾値は正規化距離の三等分点に設定し，標準的な照明評価の領域分割に対応する．

### 空間分析指標

#### ゾーン別統計

各ゾーンの平均輝度 $\mu_z$ と標準偏差 $\sigma_z$ を算出する（$z \in \{center, middle, periphery\}$）．

#### 中心/周辺比

$$\text{C/P Ratio} = \frac{\mu_{center}}{\mu_{periphery}}$$

- 1.0 に近いほど均一
- 1.0 より大 → 中心が明るい（照明の集中）
- 1.0 より小 → 周辺が明るい

#### 勾配量（%）

$$\text{Gradient} = \frac{\mu_{center} - \mu_{periphery}}{\mu_{center}} \times 100$$

- 0% に近いほど空間的ムラが小さい
- 正値 → 中心から周辺に向かって輝度が減衰

### 放射状輝度プロファイル

正規化距離を 20 等分のビンに分割し，各ビン内の平均輝度を集計する．中心から周辺にかけての輝度変化の傾向を連続的に把握できる．

- 出力: 20 × 2 の配列（列 0 = ビン中心距離，列 1 = 平均輝度）
- 最外ビンは上端を含める（$d = 1.0$ の画素を欠損させない）

### 動径 min/max 比 (Radial Min/Max Ratio)

放射状輝度プロファイル（20 ビンの輪帯平均）の最小値と最大値の比を，外れ画素にロバストな周辺減衰指標として算出する．

$$\text{Radial Min/Max Ratio} = \frac{Y^{\text{ring}}_{\min}}{Y^{\text{ring}}_{\max}}$$

- 値域 $[0, 1]$．1.0 に近いほど均一（周辺減衰が小さい）
- 画素単位の max/min 比と異なり輪帯平均を用いるため，局所ノイズ・外れ画素に頑健
- 併せて最小輝度ビンの正規化距離（`radial_min_distance`）を報告する

## 位置合わせ (Image Registration)

スマートフォンの取り付け位置の微小なずれを補正し，照明パターンの真の再現性を評価するために，位相相関法による並進位置合わせを実装する [10]．

### 位相相関法 (Phase Correlation)

2 枚の画像 $f$, $g$ の並進シフト $(dy, dx)$ を周波数領域で算出する．

$$C = \mathcal{F}^{-1}\!\left(\frac{\mathcal{F}(f) \cdot \overline{\mathcal{F}(g)}}{\left|\mathcal{F}(f) \cdot \overline{\mathcal{F}(g)}\right|}\right)$$

- $\mathcal{F}$: 2 次元 FFT（`scipy.fft.fft2`）
- $\overline{\cdot}$: 複素共役
- $C$: 位相相関マップ（ピーク位置がシフト量に対応）
- ゼロ除算を防ぐため分母に微小値 $10^{-10}$ を加算する

### サブピクセル精度の放物線補間

FFT のピーク位置は整数精度のみのため，ピーク周辺 3 点で放物線補間を行いサブピクセル精度を達成する．

$$\delta = \frac{c_{-1} - c_{+1}}{2(c_{-1} - 2c_0 + c_{+1})}$$

- $c_{-1}, c_0, c_{+1}$: ピーク前後の相関値
- $\delta$: サブピクセル補正量

FFT の周期境界による折り返しを補正するため，シフト量が画像サイズの半分を超える場合は反対方向として解釈する．

### シフト適用

`scipy.ndimage.shift`（3 次スプライン補間，`order=3`，`mode='constant'`，`cval=0.0`）でサブピクセルシフトを適用する．

### 有効領域マスキング

シフトにより境界にゼロパディング領域が生じる．マスクで無効領域を除外し，有効領域のみで SSIM を算出することで境界の影響を排除する．

| シフト方向 | 無効領域 |
| --- | --- |
| 正（下・右） | 上端・左端 $\lceil |dy| \rceil$，$\lceil |dx| \rceil$ 行列 |
| 負（上・左） | 下端・右端 $\lceil |dy| \rceil$，$\lceil |dx| \rceil$ 行列 |

## 再現性評価 (Reproducibility Assessment)

バッチ解析時に複数画像間の再現性を SSIM（Structural Similarity Index）で評価する [9]．

### SSIM (Structural Similarity Index)

2 枚の画像 $x$, $y$ 間の構造的類似度を以下の式で算出する．

$$\text{SSIM}(x, y) = \frac{(2\mu_x\mu_y + C_1)(2\sigma_{xy} + C_2)}{(\mu_x^2 + \mu_y^2 + C_1)(\sigma_x^2 + \sigma_y^2 + C_2)}$$

- $\mu_x$, $\mu_y$: 各画像の平均輝度
- $\sigma_x$, $\sigma_y$: 各画像の標準偏差
- $\sigma_{xy}$: 共分散
- $C_1 = (K_1 L)^2$, $C_2 = (K_2 L)^2$: 安定化定数（$L$ はデータレンジ，$K_1 = 0.01$, $K_2 = 0.03$）
- 値域は $[-1, 1]$，1.0 で完全一致

### ペアワイズ評価

$N$ 枚の輝度マップに対し，全 $\binom{N}{2}$ ペアの SSIM を算出する．集計統計として平均・最小・最大・標準偏差を報告する．

### 位置合わせ付き SSIM

各ペアに対し，位置合わせなし SSIM と位置合わせ後 SSIM の両方を算出する（`calc_pairwise_ssim_registered`）．

1. 位置合わせなし SSIM を算出
2. `phase_correlate` でシフト $(dy, dx)$ を推定
3. `apply_shift` でターゲット画像をシフト
4. `compute_valid_mask` で有効領域を限定
5. 有効領域内で位置合わせ後 SSIM を算出

副産物として各ペアのシフト量（ピクセル単位）を定量化し，取り付け位置ずれの統計量として報告する．

### 解釈の目安

| SSIM | 解釈 |
| --- | --- |
| $\geq 0.99$ | 極めて高い再現性 |
| $0.95 \leq$ SSIM $< 0.99$ | 高い再現性 |
| $< 0.95$ | 再現性に課題あり |

## バッチ解析 (Batch Analysis)

`scripts/run_uniformity.py` で白板画像を一括解析する．ROI 設定済みであること．

### 起動コマンド

```bash
# ディレクトリ内の全画像を一括解析
python scripts/run_uniformity.py --image data/smtias/whiteboard/ --config config/roi_config.json --roi smtias.whiteboard

# 単一画像の解析
python scripts/run_uniformity.py --image data/smtias/whiteboard/<画像ファイル名>.png --config config/roi_config.json --roi smtias.whiteboard
```

### 出力

- `output/results/summary_uniformity.csv` — 全画像の均一性指標一覧
- `output/results/summary_spatial.csv` — 全画像の空間分析指標一覧
- `output/results/<画像名>_uniformity.csv` — 各画像の均一性指標
- `output/figures/<画像名>_luminance_map.png` — 輝度マップ
- `output/figures/<画像名>_histogram.png` — 輝度ヒストグラム
- `output/figures/<画像名>_radial_profile.png` — 放射状輝度プロファイル
- `output/figures/<画像名>_zone_map.png` — ゾーンオーバーレイマップ

## 結果の確認 (Result Viewer)

Streamlit ベースのビューアで解析結果を確認できる．

### 起動方法

```bash
.venv\Scripts\streamlit run scripts/viewer.py
```

### 前提条件

- `scripts/run_uniformity.py` でバッチ解析が完了していること
- `output/results/summary_uniformity.csv` および `output/figures/` に画像ファイルが存在すること

### 機能

- **全体比較タブ**: 全画像の均一性指標テーブル・統計サマリー・指標の比較グラフ（2×2 棒グラフ）
- **個別画像タブ**: ドロップダウンまたは矢印ボタンで画像を切り替え，元画像（ROI オーバーレイ付き）・輝度マップ・ヒストグラムを横並びで確認

## キャリブレーション (Calibration)

照明均一性評価ではカラーキャリブレーションを行わない．輝度の相対的なばらつき（CoV 等）は画像内の比較であり，カメラの色特性のズレが全画素に等しく影響するため，指標の値に影響しない．

## 参考文献 (References)

- [1] ITU, "BT.709-6: Parameter values for the HDTV standards for production and international programme exchange," ITU-R, 2015.
- [2] C. Poynton, *Digital Video and HD: Algorithms and Interfaces*, 2nd ed. Morgan Kaufmann, 2012.
- [3] EN 12464-1:2021, "Light and lighting — Lighting of work places — Part 1: Indoor work places," CEN, 2021.
- [4] ANSI/IES LM-79-24, "Approved Method: Optical and Electrical Measurements of Solid-State Lighting Products," IES, 2024.
- [9] Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image quality assessment: from error visibility to structural similarity," *IEEE Trans. Image Process.*, vol. 13, no. 4, pp. 600–612, 2004. DOI: 10.1109/TIP.2003.819861
- [10] H. Foroosh, J. B. Zerubia, and M. Berthod, "Extension of phase correlation to subpixel registration," *IEEE Trans. Image Process.*, vol. 11, no. 3, pp. 188–200, 2002. DOI: 10.1109/83.988953
