省型旧形国電の残影を求めて

戦前型旧形国電および鉄道と変褪色フィルム写真を中心とした写真補正編集の話題を扱います。他のサイトでは得られない、筆者独自開発の写真補正ツールや補正技法についても情報提供しています。写真補正技法への質問はコメント欄へどうぞ

ImageJ / Python プログラミング Tips: ImageConverter でグレースケール画像に変換する際の注意

 ImageConverter を使ってRGB画像をグレースケール画像に変換する際に注意があります。それは 3 スタック形式の RGB 画像に適用することができないという点です。

 

 例えば、いま R, G, B のチャンネルが3つのスタックに収容されている imp という ImagePlus オブジェクトを考えると、これに対し、

 

ImageConverter(imp).convertToGray32()
 

 

のように、いきなり ImageConverter を使ってグレースケール画像に変換しようとすると何もやってくれません。これは変換したいグレースケール画像がどの bit 深度でも同じです。つまり、converToGray8, converToGray16 でも同じです。

 

 この場合どうするかというと、

1) 一旦、カラープロセッサに変換してからグレースケール変換する

か、

2) チャンネル分解を行ってから、それをグレースケールに変換する

のいずれしかありません。

例えば、1) の場合

ImageConverter(imp0).convertToRGB()
ImageConverter(imp0).convertToGray8()
 

でうまくいきます。

convertToRGB メソッドは、24bit (8 bit x 3 channels) のColor Processorを含んだ ImagePlus に変換します。その後スタックが1つになったので、グレースケールにコンバートするとうまくいく、という訳です。なお convertToRGB メソッドは、オリジナルがどんな bit 深度、最大値でも、 0-255 のカラープロセッサに変換してくれます。

あるいは、2) の場合

Channels = ChannelSplitter.split(imp0)

で Channels[0], Channels[1], Channels[2] の3つのチャンネル画像 ImagePlus に分解し、それぞれのチャンネルに対し、ImageConverter を掛けてグレースケール画像にする、という方法です。

 

以下、検証用コードです。

from fileinput import filename
from ij import IJ
from ij import WindowManager as WM
from ij.io import OpenDialog
from ij.process import ImageConverter
from loci.plugins import BF
from org.python.core import codecs
codecs.setDefaultEncoding('utf-8')


imgCurrent = WM.getCurrentImage()
if not imgCurrent:
    od = OpenDialog("Choose a file")
    folder = od.getDirectory()
    filename = od.getFileName()
    if filename:
        path = folder + filename
        IJ.log(path)
        IJ.log(folder)
        IJ.log(filename)
# Always Open file with Bio-format Plugin
        imps = BF.openImagePlus(folder + filename) 
        imp0 = imps[0] #imp0: Original Image 
        imp0.show()
    else:
        IJ.showMessage("File is not selected.")
else: # target image is already open
    imp0 = imgCurrent
    imagename = imp0.getTitle()
    try:
        folder = imp0.getOriginalFileInfo().directory
    except:
        folder = IJ.getDirectory("Output_directory")

#---  code for test
IJ.showMessage("Convert to Grayscale")
ImageConverter(imp0).convertToRGB()
ImageConverter(imp0).convertToGray32()
imp0.setTitle("Test Image")
StackSize = imp0.getStackSize()
IJ.showMessage("Stack Size: " + str(StackSize))

imp0.show()
#---

 上記コードを実行すると、ファイルを開くダイアログが開きますので、何か画像ファイルを開くと Bio-format Plugin を使ってスタック形式でファイルを読み込みます。そこで "Convert to Grayscale" というメッセージダイアログが出ますので、OK ボタンを押すと、グレースケール画像に変換します。そして画像に含まれるスタック数を表示します。

 コード上では、

ImageConverter(imp0).convertToRGB()

で一旦、1 スタックのカラー画像、 24bit (8 bit x 3 Channels) Color Processor に変換してから、

ImageConverter(imp0).convertToGray32()

で、32bit グレースケール画像に変換していますが、

ImageConverter(imp0).convertToRGB()

の頭に、 # をつけてコメントアウトすると、グレースケールに変換できません。スタック数も 3 のままです。グレースケールに変換できるときはスタック数が 1 になっています。つまり 3 スタック RGB画像のままだとグレースケールに変換できない、ということが分かります。

 また convertToGray32 を convertToGray8 や convertToGray16 に変えても結果が同じことが分かります。

 なお、32bit カラー画像の場合、ピクセルの最大値が不定になりますが、convertToRGB で自動的に 0-255 の 8bit 画像に変換してくれるようです。