# 形状指標の見直しと新指標導入 (Shape Metric Redesign and New Metrics)

本ドキュメントは「輝度マップの形を直接評価する指標」の導入背景・設計・実装・予想値を記録する．
Step 8-14 での A1/A9 検証を通じて「数値が実機に近づいた」評価が「形の偽物一致」になりうることが判明したため，形状指標を体系化した．

関連:

- 実装: `src/sm_tias_lightsim/evaluation/shape_metrics.py`
- 設定: `configs/eval_baseline_dng_target_shape.yaml`
- 評価仕様: [SPEC_04 評価仕様](../04_SPEC/SPEC_04_評価仕様.md)
- 残差候補: [TECH_10 残差主因候補](TECH_10_残差主因候補の網羅整理.md)
- 形状追跡: [TEST_03 輝度マップ形状追跡](../06_TEST/TEST_03_輝度マップ形状追跡.md)
- キャリブ履歴: [TEST_01 キャリブレーション検証履歴](../06_TEST/TEST_01_キャリブレーション検証履歴.md)

## §背景: 現状 4 指標が「形」を区別しない構造的問題

現状の均一性指標は以下の 4 種（+ 動径 min/max）：

| 指標 | 定義 | 本質 |
| --- | --- | --- |
| CoV | std / mean | **ばらつきの絶対量** |
| 勾配 % | (center_mean - periphery_mean) / center_mean × 100 | **中心-周辺差の絶対量** |
| C/P 比 | center_mean / periphery_mean | **中心-周辺比の絶対量** |
| 動径 min/max | min(radial_bins) / max(radial_bins) | **動径方向の均一性絶対量** |

これらは全て「どれくらい不均一か（絶対量）」を表すが，**「どのような形の不均一か（構造）」を表さない**．

### 構造的限界の具体例

「Y 軸単調勾配（下明・上暗）」と「中央ピーク楕円（中心明・周辺暗）」は，下記のような同じ CoV を持てる：

- Y 単調勾配: 上端 0.7, 下端 1.3（平均 1.0）→ std ≈ 0.18 → CoV ≈ 0.18
- 中央ピーク楕円: 中心 1.3, 周辺 0.82（同じ分散設計）→ CoV ≈ 0.18

CoV 0.18 で一致しても「形は全く違う」．C/P 比・勾配・動径 min/max も同様に「量」は一致しうる．

Step 8 で「CoV が実機方向に動いた」と評価した過去の検証は，形の改善を保証しない．[TEST_01 注記 (2026-06-03)](#) 参照．

### シミュ vs 実機の形の乖離

TEST_03 の視覚比較から：

- **シミュ**: 下端のみ明の **Y 軸単調勾配**（LED が下基板に集中し，上端は内壁多重反射でしか届かない）
- **実機**: 中央付近にピークを持つ **楕円状** 分布

Step 8-1〜8-12 の全検証ステップで「形は全く変わっていない」という重要発見 ([TEST_03](../06_TEST/TEST_03_輝度マップ形状追跡.md)) と整合する．

## §現状指標の限界の具体例（数値計算デモ）

以下は 100×100 の合成画像で，CoV が同じでも形が異なるケースのデモ：

```python
import numpy as np

# ケース 1: Y 軸単調勾配
H, W = 100, 100
y_gradient = np.linspace(1.3, 0.7, H)[:, None] * np.ones((H, W))
# mean=1.0, std≈0.18, CoV≈0.18

# ケース 2: 中央ピーク楕円（半径で減衰）
cy, cx = H/2, W/2
ys = np.arange(H)[:, None]; xs = np.arange(W)[None, :]
r = np.sqrt(((xs-cx)/cx)**2 + ((ys-cy)/cy)**2)
radial = 1.0 + 0.3 * np.exp(-2.0 * r**2)
# mean ≈ 1.0, std ≈ 0.18, CoV ≈ 0.18

# 両者の CoV は等しい（設計通り）
# しかし形は正反対: Y 単調 vs 中央ピーク
# 新指標 angular_ratio でのみ区別可能:
# - ケース 1: angular_ratio ≈ 0.3〜0.4（Y 方向の方向性あり）
# - ケース 2: angular_ratio ≈ 0.1〜0.2（ほぼ同心円）
```

## §新指標 5 つの物理的意味と計算式

実装は `src/sm_tias_lightsim/evaluation/shape_metrics.py`．

### 1. 輝度重心 `calc_intensity_centroid`

**物理的意味**: 光の「重力中心」．ROI 中心から大きくずれていれば非対称な照明分布を示す．

**計算式**:

```
cx = Σ(I(x,y) * x) / Σ(I(x,y))
cy = Σ(I(x,y) * y) / Σ(I(x,y))
centroid_x_norm = (cx - ROI_center_x) / (ROI_half_width)
centroid_y_norm = (cy - ROI_center_y) / (ROI_half_height)
centroid_offset_norm = √(x_norm² + y_norm²)
```

**出力**: `centroid_x_px`, `centroid_y_px`, `centroid_x_norm`, `centroid_y_norm`, `centroid_offset_norm` の 5 値．

### 2. 角度-放射分解 `calc_angular_radial_decomposition`

**物理的意味**: 輝度ムラが「同心円方向（r）」か「方向性ムラ（θ）」かを分離する形状識別器．

**計算式**:

```
極座標変換: (x,y) → (r, θ)
グリッド I[r_bin, θ_bin] = 平均輝度
angular_variance = mean_r[ Var_θ[I | r] ]   ← 各 r での角度方向分散の平均
radial_variance  = Var_r[ mean_θ[I | r] ]   ← 角度平均した放射プロファイルの分散
angular_ratio = angular_variance / (angular_variance + radial_variance)
```

**値域と解釈**:

| angular_ratio | 意味 |
| --- | --- |
| 0 | 完全同心円（各 r で角度方向の輝度変化ゼロ） |
| NaN | 完全均一画像（全 variance = 0） |
| 0.1〜0.3 | 中央ピーク楕円に典型的（角度依存が小） |
| 0.3〜0.5 | Y 単調勾配に典型的（Y 方向に偏った方向性） |
| 1 | 完全角度依存（同心円成分ゼロ） |

### 3. SSIM `calc_ssim`

**物理的意味**: 実機 DNG 輝度マップを参照として，シミュ輝度マップとの構造類似性を 0〜1 で数値化．1 で完全一致．

**実装**: `skimage.metrics.structural_similarity` を使用（依存: `scikit-image>=0.21.0`）．

**注意**:
- `shape_reference` が指定されたときのみ算出（未指定 = NaN）
- shape が異なれば自動スキップ（呼び出し側で resize が必要）

### 4. NCC `calc_ncc`

**物理的意味**: 絶対輝度スケールに依存しない形の類似性．SSIM より単純だが，線形スケールや露出変動に完全不変（mean を引いて相関を取るため）．

**計算式**:

```
NCC = Σ((I - mean(I)) * (R - mean(R))) / √(Σ(I-mean(I))² * Σ(R-mean(R))²)
```

**値域**: -1〜+1（1=完全相関，0=無相関，-1=逆相関）．均一画像では NaN を返す．

### 5. 輝度分布 PCA `calc_intensity_pca`

**物理的意味**: 輝度を重みとして空間分布の「伸び方向」を固有ベクトルで表現する．主軸角度が 90° に近ければ Y 方向の勾配が支配的（シミュの典型），0° に近ければ X 方向の勾配が支配的，楕円なら中程度の eccentricity．

**計算式**:

```
(cx, cy) = 輝度重み重心
共分散行列 [[Σ(I*Δx²)/W, Σ(I*Δx*Δy)/W], [同, Σ(I*Δy²)/W]]
固有値分解 → eigenvalue[0] ≤ eigenvalue[1] (主軸)
primary_axis_angle_deg = arctan2(v_y, v_x) × 180/π  (-90〜+90 に折り畳み)
eccentricity = √(1 - secondary_eigenvalue / primary_eigenvalue)
```

**値域**:

| 指標 | 中央ピーク楕円 | Y 単調勾配 |
| --- | --- | --- |
| primary_axis_angle_deg | 様々（楕円の向きに依存） | ≈ ±90°（Y 方向） |
| eccentricity | 中程度（0.4〜0.7 程度） | 高め（0.7〜0.9 程度） |

## §シミュ vs 実機での新指標の予想値

現状のシミュ（Y 軸単調勾配）と実機（中央ピーク楕円）での典型的な期待値：

| 指標 | シミュ予想 | 実機予想 | 判定の方向 |
| --- | --- | --- | --- |
| `centroid_y_norm` | 負（< 0）（下端明なので重心が下方） | ≈ 0（中心に近い） | シミュは負，実機は 0 近傍 |
| `centroid_offset_norm` | 大きい（0.1〜0.3） | 小さい（< 0.1） | 小さいほど中心対称 |
| `angular_ratio` | 中程度（0.3〜0.5） | 小さい（0.1〜0.3） | 小さいほど同心円に近い |
| `pca_primary_axis_angle_deg` | ≈ ±90°（Y 軸） | 様々（楕円の向き次第） | 90° から遠ざかれば形改善 |
| `pca_eccentricity` | 高め（0.7〜0.9） | 低め（0.4〜0.6） | 小さいほど円に近い |

**重要**: SSIM / NCC は `shape_reference` に実機 DNG 由来の参照輝度マップを指定することで，シミュが実機に近づいているかを 1 枚の数値で追跡できる．

## §過去判断への遡及的注記

Step 8 の以下の評価は「数値の偽物一致」の可能性がある：

| Step | 評価内容 | 形指標の観点 |
| --- | --- | --- |
| 8-1 | spp=1024 で CoV 0.236 → 0.183（MC ノイズ縮小） | 形は不変（単純な量低減） |
| 8-2 | R=0.92 で CoV 0.183 → 0.170（反射率スイープ） | 形は不変（均一化フィルタ） |
| 8-3 | OETF 適用で CoV 0.183 → 0.089（ドメイン整合） | 形は不変（単調変換） |
| 8-4 | max_depth=12 で勾配改善 | 形は不変（均一化フィルタ） |
| 8-14 A9 | max_depth スイープで CoV 21% 縮小 | **形が全く変わらない**ことが視覚確認済み ([TECH_10 §A9 検証結果](TECH_10_残差主因候補の網羅整理.md#a9-検証結果2026-06-03-完了)) |

TEST_03「Step 8-1〜8-7 で輝度マップの形は全く変わっていない」という発見と完全に整合する．

**結論**: 過去の「数値が実機方向に動いた」評価は「均一化フィルタが効いた」だけで，「形が実機に近づいた」わけではない．本評価の目的（MiniTIAS 均一性の構造的改善）のためには，形指標の追跡が必須である．

## §今後の評価方針: 数値指標 4 + 新形指標 5 + 視覚比較の 3 軸評価

今後の Step 8-14 以降は以下の 3 軸で評価する：

```
評価 3 軸
├── 数値指標（量）: CoV / 勾配 / C/P / 動径 min/max
│   └── 実機に近づいているか（絶対量の改善）
├── 形指標（構造）: angular_ratio / SSIM / NCC / 重心 / PCA
│   └── Y 単調勾配から中央ピーク楕円に形が変化しているか
└── 視覚比較: luminance_map.png + TEST_03 パネル
    └── 目視で形のパターン変化を確認
```

「数値改善のみで形が変わらない」候補（A9 max_depth 等）と「形を変えうる候補」（B1 幾何精度，ζ LED ティルト等）を明確に区別する判断材料として機能する．

## §設定方法

### 基本（形状指標のみ）

```yaml
metrics:
  cov: true
  radial_min_max: true
  shape_metrics: true
  shape_reference: null
```

`configs/eval_baseline_dng_target_shape.yaml` がこの設定に対応する．

### SSIM / NCC 有効化（参照画像指定時）

```yaml
metrics:
  shape_metrics: true
  shape_reference: reference_measurement/quantitative/expected_results/MiniTIAS_QM_20260601_124500_luminance_map.npy
```

参照画像は ROI 抽出後の輝度マップ（`luminance.npy` と同じ ROI サイズの 2D float64 配列）を期待する．
実機 DNG からの輝度マップ生成は MiniTias-Evaluation で行い，`reference_measurement/quantitative/expected_results/` に配置する（gitignore 対象外として管理すること）．

### 後方互換

`shape_metrics` および `shape_reference` フィールドはいずれも省略可能（デフォルト false/null）．既存の YAML は変更不要で動作する．

## §関連ドキュメント (Related Documents)

- [SPEC_04 評価仕様](../04_SPEC/SPEC_04_評価仕様.md): 均一性評価パイプライン全体
- [TECH_10 残差主因候補](TECH_10_残差主因候補の網羅整理.md): 形指標導入のきっかけとなった A9 検証
- [TEST_01 キャリブレーション検証履歴](../06_TEST/TEST_01_キャリブレーション検証履歴.md): Step 8 数値評価の歴史
- [TEST_03 輝度マップ形状追跡](../06_TEST/TEST_03_輝度マップ形状追跡.md): 形の視覚比較（既存）
