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

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

ImageJ / Python プログラミング Tips: ImageJにおける32bit画像の扱い

 今まで ImageJ上で32bit画像を扱うことがなかったのでよく分からなかったのですが、プログラミング上の必要があり、今回いろいろと調べてみました。

 まず、以前にも書きましたが、16bit以上の画像の場合、1枚のImageProsessorには1チャンネルの画像しか収容できません。そしてRGBフルカラー画像の場合は、RGB、3つのチャンネルに関する3枚のImageProcessorを持ったスタック構造のImagePlusとして扱われます。これをTIFFファイルに落とすと、RGBの3ページを持ったTIFFファイルとして保存され、ImageJのみが読める特有のタグ情報に、チャンネル識別情報が記録されます。このファイルを再度ImageJで読み込むとRGBフルカラー画像として表示できますが、他の画像処理ソフトでは、ImageJ特有のタグ情報が読めないので、3ページのグレースケール画像を持ったTIFFファイルとしか読めません。したがってこのTIFFファイルをフルカラー画像として表示させるには、RGB合成を当該画像処理ソフト上でやり直す必要があります。

 ImageJ上の32bit画像上での画像データは、正負符号付(Signed)の浮動小数点データとなります。これはどういうことを示すかというと、負の値を取ることができるとともに、最大値も固定されない、ということです。ですので、0~16,777,216のデータであってもよいし、0~1.0のデータでもあったもよい、はたまた-1.0~+1.0のデータであってもよいということです。ともあれ有効桁数は32 bit になります。
 ちなみに、32bit TIFFデータを0~1.0の形で保存したものであっても、0~16,777,215の形で保存したものであっても、いずれも同じように読めます。ただし、ImageJ上で、0~16,777,215のデータを、最大値16,777,216で割り、0~1.0のデータに直した場合、表示上は真っ暗になってしまいます。これをTIFFデータに保存しなおし、再度読み込みなおしても真っ暗のままです。しかし、ImageJで0~1.0の形で保存した32bit TIFF ファイルをGIMPで読み込み、GIMP上で再度32bit TIFF として保存しなおしたものを ImageJで読むと、正しく表示されるので、TIFFファイルのどこかに表示できる明度の最大値・最小値を記したタグ情報があり、それを基に ImageJ 上で表示の仕方を決めているものと思われます。そしてGIMPで保存しなおしたときにその表示明度範囲データを更新するので、GIMPで保存しなおすと、画像データを変換前と同じように表示できるようになるものと思われます。ただそのタグ情報は、あくまで表示の仕方のみを決めているのであって、データ上の扱いを制約するものではないと思われます。

 なお、ImageJ の API 上、8, 16 bit の画像を 32 bit 画像に変換するには、

ImageConverter(imagePlus).convertToGray32()

 を使うか、もしくは、ImageProcessor に対して、

convertToFloatProcessor()

 メソッドを使います。

 また、ImageJ の UI 上から変換するときは、

Image の Type 変換

メニューの [Image] → [Type] → [32 bit] を選択します。

 なお、8bitや16bitの画像を32bitに変換したとしても、画像データは全く変わりません(これは、8 bit画像を 16 bit 画像に変換しても同じ。一方 bit 深度を落として変換する場合は、bit 深度に合わせて最大値を落として自動調整)。この点は、GUI上で変換しても、プログラムからAPIを使って操作しても同じです。例えば、0~65535の16bitデータを32bitに変換しても、0~65535のままです。このデータを0.0~1.0に変えたければ、さらに65535で割るという操作が必要です。また計算上、マイナスの値になっても、正負符号付なので、そのままマイナス値のデータは保持されます。

 なお、データを0.0 ~ 1.0 の小数浮動点データに直したときに、ImageJ 上で真っ暗に表示されてしまうことに対する対策ですが、明度の表示させる最小値・最大値の範囲を指定するには ImageJ の API ですと、ImagePlus に、setDisplayRange​(double min, double max) というメソッドがありますので、これを使うのではないかと思われます(確認済み)。UI 上からは表示すべき明度範囲を指定するメニューは見当たらないようです(見逃しているかもしれません)。ImageJ は、まだまだ 8 bit データを扱うことを前提としている部分が多いので、この辺りは今後改善されるのかもしれません。

--------------

関連記事

yasuo-ssi.hatenablog.com

yasuo-ssi.hatenablog.com

yasuo-ssi.hatenablog.com