0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

天体画像解析やFITSデータ処理では、
RGB画像や3チャネルの強度をそれぞれの色で表示して比較したい場面がよくあります。
例えば、

  • X線・可視光・赤外の比較
  • 3つの波長チャネルの強度評価
  • RGB合成前のチャネル確認
  • 画像シミュレーションの検証

などです。

しかし matplotlib には標準で

  • 黒→赤
  • 黒→緑
  • 黒→青

のような単色カラーマップが存在しません。

本記事では、こうした 単色によるチャネル強度表示 を可能にするために、
自分でカラーマップを定義し、matplotlibへ登録して利用する方法を紹介します。

この記事のコードは Google Colab こちら からも閲覧できます。

カラーマップ登録コード

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colormaps
from matplotlib.colors import LinearSegmentedColormap

def register_single_color_cmap(color):
    rgb = {
        'red':   (1,0,0),
        'green': (0,1,0),
        'blue':  (0,0,1),
    }[color]

    cmap_name = f"my_{color}"
    if cmap_name not in colormaps:
        cmap = LinearSegmentedColormap.from_list(
            cmap_name, [(0,0,0), rgb], N=256
        )
        colormaps.register(name=cmap_name, cmap=cmap)

    cmap_r_name = f"my_{color}_r"
    if cmap_r_name not in colormaps:
        cmap_r = colormaps[cmap_name].reversed()
        colormaps.register(name=cmap_r_name, cmap=cmap_r)

for c in ["red", "green", "blue"]:
    register_single_color_cmap(c)

これで以下が使用可能になります:

image.png

image.png

使用例

利用方法はシンプルで、plt.imshow()cmap= を渡すだけです。

# サンプルデータ作成
x = np.linspace(0, 1, 100)
X, Y = np.meshgrid(x, x)
Z = np.sin(2 * np.pi * X) * np.cos(2 * np.pi * Y)

# プロット
fig, ax = plt.subplots(figsize=(6, 4))
img = ax.imshow(Z, cmap='my_red', origin='lower')

# カラーバーの追加
fig.colorbar(img, ax=ax)

plt.show()

黒 → 赤 の単色で強度が表示されます:

image.png

補足

各色チャネルの強度比較について

RGBや複数チャネルの画像を比較する際には、
チャネルごとに強度のスケールが違ってしまうと正しく比較できないため、
データ型が持つ値域で正規化し、全チャネルを 0〜1 に揃えるのが無難です:

info = np.iinfo(img.dtype)
img_norm = (img - info.min) / (info.max - info.min)
plt.imshow(img_norm, cmap='my_red', vmin=0.0, vmax=1.0)

こうして正規化しておくことで、赤・緑・青の強度を同一スケール(0〜1)で比較できるという利点があります。


色表示とグレースケールの使い分け

RGBでの表示は、

  • どのチャネルが強いか
  • どの色が局所的に優勢か

といった特徴を直感的につかむのに向いています。

一方で、人間の視覚は色に対して感度が異なり、
特に 青は暗く見えやすく、緑は明るく感じやすい という性質があります。

そのため、ピクセル強度そのものを公平に比較したい場合は
グレースケール(cmap='gray')同士で比較するのがおすすめです。

また、グレースケール表示でも同じスケーリング(vmin/vmax)で表示しておくと、
各チャネルの強度差をより素直に比較しやすくなります。

まとめ

  • matplotlib には単色のR/G/Bカラーマップが標準で無い
  • my_red / my_green / my_blue を登録することで簡単に利用可能
  • FITS cube / RGB画像 / 天体画像解析などに有効
  • 色チャネルの比較には値域の統一(正規化)が重要

関連資料

天文学でよく使われる SAOImage DS9 のカラーマップを使いたい場合はこちら:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?