Scala による ImageJ プラグイン
ImageJ の拡張のために Java を使ってプラグインを書いたり独自仕様のマクロを書いたりしてきたが,どうもしっくりこない. Java は面倒な時があるし, ImageJ のマクロは再利用性に乏しい(importや#includeに相当するものがない).

Python が好きなので Jython + ImageJ を試したり,CPython + ImageJ 用のプラグインを作ってはみたものの,遅かったり,準備が面倒で共同作業先に持っていきにくかったりする.そこで JVM 上で動く言語を調べたり試した挙句, Scala を試用することにした.

ImageJ 起動時の CLASSPATH に scala-library.jar を加えるだけで, Scala で ImageJ プラグインを書くことができた.以下は単純なバックプロジェクションをする例.ImageJ API を呼ぶだけなので Java との差は型宣言の量くらいになった.そういえば Scala には ImageJ マクロと同じく break と continue がない.

import ij._
import ij.plugin._
import ij.process._
import ij.gui._

object Kbi_TestScala_ {
private def getHorizLine(ip: ImageProcessor, y: int) =
(for (x <- 0 until ip.getWidth) yield ip getf (x, y)).toArray[float]

private def makeEmpty(ip: ImageProcessor) =
new FloatProcessor(ip.getWidth, ip.getHeight)

private def project(fp: FloatProcessor, angle: double, line: Array[float]) = {
val ipTmp = makeEmpty(fp)
val numX = fp.getWidth
for (y <- 0 until fp.getHeight)
for (x <- 0 until numX)
ipTmp setf (x, y, line(x))
ipTmp setInterpolate true
ipTmp rotate angle
fp copyBits (ipTmp, 0, 0, Blitter.ADD)
}

def process(ipTomo: ImageProcessor, step: double) = {
val ipRet = makeEmpty(ipTomo)
var angle = 90.0
for (y <- 0 until ipTomo.getHeight) {
project (ipRet, angle, getHorizLine(ipTomo, y))
angle -= step
}
ipRet
}

def processAsPlugIn(imp: ImagePlus, step: double) =
new ImagePlus(WindowManager getUniqueName (imp.getTitle + "_bp"),
process(imp getProcessor, step)) show
}

class Kbi_TestScala extends PlugIn {
def run(arg: String) = {
val imp = IJ.getImage
val gd = new GenericDialog("parms")
gd addNumericField ("angle", 1.0, 1)
gd showDialog
if (!(gd wasCanceled))
Kbi_TestScala_ processAsPlugIn(imp, gd getNextNumber)
}
}


b0095474_630418.jpg

左上: 原画像(植物培養細胞),右上: 原画像を1度ずつ回転後,投影して得たシノグラム,左下: 上記プラグインにてバックプロジェクションして得られた復元像,右下: 復元像の高周波数成分のみを取り出した像.
[PR]
by edogawadai_bio | 2008-03-17 02:51 | comp
<< 桜 京都 >>