【画質評価】CZPチャートをpythonで作成

カメラ・信号処理

カメラや画像処理アルゴリズムの評価を行う際、解像度やシャープネス、ノイズ特性などを定量的に測定するために「テストチャート」がよく使われます。
その中でも CZPチャート(Circular Zone Plate chart) は、空間周波数に対する応答を可視化するのに非常に便利なパターンです。

ナイキスト周波数

イメージセンサが持つ画素は、空間的な輝度をサンプリングしています。

輝度が4画素周期で変化していた場合は、その空間的な輝度の周期を捉えることができます。

輝度変化を捉えられる最大の空間周期は2画素周期となります。これを周波数で表現したものがナイキスト周波数です。

ナイキスト周波数より高い空間周波数の被写体は正しくサンプリングできず、低周波成分として折り返し(エイリアシング)、RGBでナイキスト周波数が異なる場合は偽色(color artifact)が発生します。

イメージセンサのRAW画像ではカラーフィルターの配列から色毎にサンプリング密度や位相が異なることが通常であり、デモザイク・リモザイクといった画素配列の変換処理によるエイリアシングや偽色の影響を確認するのに、CZPチャートは有用です。

カメラ画質評価に使われるCZPチャートとは?

CZPチャートは、中心から放射状に広がる同心円状のパターンを持ち、位置ごとに異なる空間周波数成分を含んでいます。

この特性により、単一の画像から MTF(Modulation Transfer Function)、サンプリングの折り返し(aliasing)、および補間アルゴリズムの影響 を視覚的に確認することができます。

CZPチャートを生成するpythonコード

Pythonを用いてCZPチャートを生成するシンプルなpythonコードを掲載します。

CZPチャートの生成には、映像情報メディア学会記載の式を用いました。(リンク)

import numpy as np
import cv2


def create_czp_chart(width=512, height=512):
    # 空の3チャンネル画像を作成 (値域は0-1)
    chart = np.zeros((height, width, 3), dtype=np.float32)

    # 中心座標を計算
    cx = width // 2
    cy = height // 2

    # CZPチャートの輝度パターンを生成
    for y in range(height):
        for x in range(width):
            # 中心からの距離に基づくパターン
            chart[y, x] = 0.5 * np.sin((np.pi / 2) * ((x - cx) ** 2 / cx + (y - cy) ** 2 / cy) + np.pi / 2) + 0.5

    # 全チャンネルに同じパターンを適用
    chart = np.stack([chart[:, :, 0], chart[:, :, 0], chart[:, :, 0]], axis=-1)

    return chart


def save_chart(chart, filename):
    # float32からuint8に変換 (0-1 → 0-255)
    chart_uint8 = (chart * 255).astype(np.uint8)
    # JPEGとして保存
    cv2.imwrite(filename, chart_uint8)


if __name__ == "__main__":
    # チャートを生成
    chart = create_czp_chart(512, 512)
    # 保存
    save_chart(chart, "czp_chart.jpg")

これにより生成された画像はこちら。

CZPチャート

中心から外側に向かって放射状のパターンが高周波化していく様子が分かります。

CZPチャートとナイキスト周波数

CZPチャートでは半径方向に周波数が連続的に変化するため、画像全体で 低周波から高周波までの応答 を一度に観察できます。画角の端に行くほど周波数が高くなっていき、画角端ではナイキスト周波数となります。

Bayer配列のG画素の場合、水平方向、垂直方向でみると、1画素周期でサンプリングしています。

斜め方向で見ると、\(\sqrt{2}\)画素周期でサンプリングしています。

このため、

  • G画素のナイキスト周波数
    • 水平・垂直方向 : \(1/2pix\)
    • 斜め方向 : \(1/\sqrt{2}pix\)

となります。

このナイキスト周波数をCZPチャート上にプロットすると、以下のようになります。

この緑線から外側の領域はG画素のサンプリング限界を超えているため、G画素ではエイリアシングが発生する領域となります。

同じのような見方でR画素を見ると、

  • R画素のナイキスト周波数
    • 水平・垂直方向 : \(1/4 pix\)
    • 斜め方向 : \(1/\sqrt{2} pix\)

となり、G画素とR画素ではエイリアシングが発生する領域に差があることが分かります。

高周波成分を持つ被写体を撮影すると、色毎でのナイキスト周波数の差により偽色が発生することがあります。

デモザイク・リモザイク処理では、偽色を抑えながら、ナイキスト周波数までの解像度を出すことが目標の一つとなります。

コメント

タイトルとURLをコピーしました