"""輝度均一性評価モジュール."""
import numpy
# Rec.709 グレースケール変換係数
# 参照: ITU-R BT.709 (https://www.itu.int/rec/R-REC-BT.709/en)
REC709_COEFF_R = 0.2126
REC709_COEFF_G = 0.7152
REC709_COEFF_B = 0.0722
def to_grayscale(image: numpy.ndarray) -> numpy.ndarray:
"""RGB 画像を Rec.709 輝度係数でグレースケール(輝度画像)に変換する.
OpenCV の cvtColor ではなく Rec.709 の係数を明示的に使用する.
参照: ITU-R BT.709
Args:
image: 入力 RGB 画像の NumPy 配列(H x W x 3, uint8).
Returns:
輝度画像の NumPy 配列(H x W, float64).値域は 0.0〜255.0.
"""
# float64 に変換してから係数を適用する(整数演算による丸め誤差を防ぐ)
img_float = image.astype(numpy.float64)
luminance = (
REC709_COEFF_R * img_float[:, :, 0]
+ REC709_COEFF_G * img_float[:, :, 1]
+ REC709_COEFF_B * img_float[:, :, 2]
)
return luminance
def calc_uniformity(luminance: numpy.ndarray) -> dict:
"""輝度画像から均一性指標を算出する.
3 つの指標を算出する:
- CoV(変動係数): σ / μ — 小さいほど均一(無次元)
- std(標準偏差): 輝度のばらつきの絶対値
- max_min_ratio(最大/最小比): max / min — 極端なムラの検出
Args:
luminance: 輝度画像の NumPy 配列(H x W, float64).
Returns:
均一性指標を格納した辞書.キーは "cov", "std", "max_min_ratio",
"mean", "max", "min".
Raises:
ValueError: 輝度画像の最小値が 0 の場合(最大/最小比が計算不能).
"""
mean = float(numpy.mean(luminance))
std = float(numpy.std(luminance))
lmax = float(numpy.max(luminance))
lmin = float(numpy.min(luminance))
# CoV: 相対的なばらつきの指標
cov = std / mean if mean != 0.0 else float("inf")
# 最大/最小比: 極端なムラを検出する指標
if lmin == 0.0:
raise ValueError(
"輝度の最小値が 0 のため最大/最小比を計算できません."
"ROI の設定を確認してください."
)
max_min_ratio = lmax / lmin
return {
"cov": cov,
"std": std,
"max_min_ratio": max_min_ratio,
"mean": mean,
"max": lmax,
"min": lmin,
}