14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RGB 3 色合成図を作る

Last updated at Posted at 2017-01-16

これは何か

天文でよく使われる 3 色合成図を python を使って作る方法を紹介します。

使うモジュール

  • PIL
  • astropy
  • astroquery (画像データを python でダウンロードしたい場合必要)

目次

  1. Red, Green, Blue の 3 種類の画像を用意します
  2. PIL.Image を使って 3 色合成します
  3. rgbimage.py を使ってインタラクティブに 3 色合成図を作ります

1. 画像の準備

天文では FITS というファイルフォーマットで画像を管理しています。SkyView Virtual Observatory でダウンロードすることもできます。Web ブラウザからもダウンロードできますが、今回は python を使って自動でダウンロードしてみます。

コード

download.py
from astroquery.skyview import SkyView
import astropy.units

target = 'M17'
surveys = ['2MASS-J', '2MASS-H', '2MASS-K']
radius = 0.3 * astropy.units.deg
pixels = 1000

hdu = SkyView.get_images(target, surveys, radius=radius, pixels=pixels)
hdu[0].writeto('M17-2MASS-J.fits', clobber=True)
hdu[1].writeto('M17-2MASS-H.fits', clobber=True)
hdu[2].writeto('M17-2MASS-K.fits', clobber=True)

ちょっと紹介

M17 は、オメガ星雲として有名な散光星雲で、大質量星をたくさん含む NGC6618 クラスタが周囲の分子ガスを電離している領域です。天の川銀河の中でもかなり活発な大質量星形成領域です。

2MASS は近赤外線での全天サーベイ観測プロジェクトです。J バンド (1.2 μm)、H バンド (1.7 μm)、Ks バンド (2.2 μm) のデータが公開されています。

2. PIL.Image を使って 3 色合成図を作る

ダウンロードした 3 つのデータを使って、3 色合成図を作ります。
手順としては、

  1. FITS ファイルを読み込む
  2. min, max のレンジを決め、0 - 255 の int 型に変換する
  3. image を保存する
    を行なっていきます。

コード

plot.py
import numpy
import PIL.Image
import astropy.io.fits

r = astropy.io.fits.open('M17-2MASS-K.fits')[0].data[::-1,:]
g = astropy.io.fits.open('M17-2MASS-H.fits')[0].data[::-1,:]
b = astropy.io.fits.open('M17-2MASS-J.fits')[0].data[::-1,:]

pix_y, pix_x = r.shape


def scale(data, scale_min=None, scale_max=None, stretch='linear'):
    if stretch == 'linear':
        scale_func = scale_linear
    elif stretch == 'log':
        scale_func = scale_log
    else:
        scale_func = scale_linear
        pass

    if scale_min is None:
        scale_min = numpy.nanmin(data)
        pass

    if scale_max is None:
        scale_max = numpy.nanmax(data)
        pass

    scaled = scale_func(data, scale_min, scale_max)
    scaled = numpy.uint8(scaled * 255)
    return scaled

def scale_linear(data, scale_min, scale_max):
    print('%f, %f'%(scale_min, scale_max))
    scaled = (data - scale_min) / (scale_max - scale_min)
    scaled[numpy.where(scaled<0)] = 0
    scaled[numpy.where(scaled>=1)] = 1
    return scaled

def scale_log(data, scale_min, scale_max):
    print('%e, %e'%(scale_min, scale_max))
    scaled = scale_linear(data, scale_min, scale_max)
    scaled = numpy.log10((scaled * 9) + 1)
    return scaled


img = numpy.zeros([pix_y, pix_x, 3], dtype=numpy.uint8)
img[:,:,0] = scale(r, 630, 840, 'log')
img[:,:,1] = scale(g, 595, 730, 'log')
img[:,:,2] = scale(b, 150, 190, 'log')

PIL.Image.fromarray(img).save('rgbimage-M17-2MASS.png')

こんな画像が出てきます。

rgbimage-M17-2MASS.png

3. インタラクティブに 3 色合成図を作る

レンジを指定し、画像を確認し、またレンジを指定し、、、と繰り返しながら良い配色を探します。たくさん繰り返すと大変なので、GUI で操作できるツールを作りました。

rgbimage.py

使い方

  • rgbimage.py をダウンロードして保存
  • 実行する : python rgbimage.py
  • ファイルをロードし、レンジを指定し、セーブする

実行すると、こんなウィンドウが出てきます。
スクリーンショット 2017-01-16 16.38.57.png

  • "Open" をクリックすると、ダイアログが開くので FITS ファイルを選びます
  • "linear" と書かれたオプションメニュー : stretch を 'linear', 'log', 'sqrt' から選びます
  • "min テキストボックス" : レンジ指定バーの下限値
  • "max テキストボックス" : レンジ指定バーの上限値
  • "min スライドバー" : 色レンジの最小を指定します
  • "max スライドバー" : 色レンジの最大を指定します

いろいろ設定するとこんな感じです。
スクリーンショット 2017-01-16 16.45.39.png

最後に、"Save as" をクリックして画像を保存します。

4. 作った画像に座標をつける

astropy.wcs を使って matplotlib でプロットしてみます。

コード

plot_with_coordinate.py
import astropy.io.fits
import astropy.wcs
import astropy.units
import matplotlib.pyplot
import PIL.Image

matplotlib.rcParams['font.family'] = 'arial'

hdu = astropy.io.fits.open('M17-2MASS-K.fits')[0]
wcs = astropy.wcs.WCS(hdu.header)
img = PIL.Image.open('rgbimage-M17-2MASS.png')

fig = matplotlib.pyplot.figure()
ax = fig.add_subplot(111, projection=wcs)
ax.imshow(img)
ax.grid(color='w', linestyle='-')
ax.coords[0].set_major_formatter('hh:mm:ss')
ax.coords[1].set_major_formatter('dd:mm')
ax.set_xlabel('R.A. (J2000)')
ax.set_ylabel('Dec. (J2000)')

ax2 = ax.get_coords_overlay('galactic')
ax2[0].set_ticks(spacing=0.05*astropy.units.deg)
ax2[1].set_ticks(spacing=0.05*astropy.units.deg)
ax2[0].set_major_formatter('d.dd')
ax2[1].set_major_formatter('d.dd')
ax2[0].set_axislabel('Galactic Longitude')
ax2[1].set_axislabel('Galactic Latitude')
ax2.grid(color='y', linestyle='-')

fig.savefig('rgbimage-M17-2MASS-withcoord.png')

こんな画像が出ます。
rgbimage-M17-2MASS-withcoord.png

14
13
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
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?