ImageJ の 32-bit 浮動小数点画像 (FloatProcessor) は 8-bit (ByteProcessor), 16-bit 整数画像 (ShortProcessor) とは異なり、所定の値を超えてもデータがクリップすることはありませんし、負の値もとることがあります。8-bit, 16-bit 整数画像は、正負符号のない (unsigned) 0-255, もしくは 0-65535 までの値を取り、この範囲を超えた場合は 0 もしくは最大値 (255 or 65535) にクリップされます。
この32-bit データのクリップしないという特徴は都合が良い場合もありますが、不都合な場合もあります。一般的な 32-bit 浮動小数点画像データは、0.0-1.0 を取ることが多いですが、計算上その範囲を下回ったり上回ってもデータがクリップされません。これをマイナスの値を取る場合は 0.0 に、また 1.0 を上回る場合は 1.0 にクリップさせるにはどうしたら良いでしょうか。
当初は threshold と ROI を組み合わせていろいろやろうとしましたが、よく考えたら、より簡単な方法がありました。
以下、マイナスの値を取ったら、0.0 に直すユーザ作成関数の例です。なお、FloatProcessor を含む ImagePlus を読み込むことを前提としています。
-----------------------
def clipUnder0(imp):
ip0 = imp.getProcessor()
ip1 = FloatProcessor(ip0.width, ip0.height)
ip1.setValue(0.0)
ip1.fill()
imp1 = ImagePlus("imp1", ip1)
ic = plugin.ImageCalculator()
imp2 = ic.run("Max created", imp, imp1)
imp2.setLut(None)
imp1.close()
imp.close()
return imp2
-----------------------
オリジナルの画像は imp として読み込みます。元の画像と同じサイズで、0.0 で塗りつぶした imp1 という ImagePlus を作成し、Image Calculator でオリジナルの画像 (imp) と比較明の画像 imp2 を作っています。すると、マイナスの値を取るピクセルは 0.0 で塗りつぶされた画像が出来上がります。
同様に、1.0 を超えたピクセルはすべて、1.0 に塗潰す関数は...
-----------------------
def clipOver1(imp):
ip0 = imp.getProcessor()
ip1 = FloatProcessor(ip0.width, ip0.height)
ip1.setValue(1.0)
ip1.fill()
imp1 = ImagePlus("imp1", ip1)
ic = plugin.ImageCalculator()
imp2 = ic.run("Min created", imp, imp1)
imp2.setLut(None)
imp1.close()
imp.close()
return imp2
-----------------------
こちらは、1.0 で塗りつぶした imp1 という ImagePlus を作成し、Image Calculator を使って、オリジナル画像との比較暗の画像を作成します。すると 1.0 を超えた部分はすべて 1.0 に揃った画像を戻り値として出力します。
なお、 Image Calculator を使っていますので、以下のインポート文が必要です。
from ij import plugin