我正在使用eclipse中的pydev插件在Jython中编写一个imageJ / Fiji插件。该插件将是已经存在的一个名为CANDLE的去噪软件的ImageJ版本,该软件被编写为matlab程序。在matlab中更改图像的每个像素(体素)的值是微不足道的:
InputImage = 2 * sqrt(InputImage + (3/8));
Median3DFilteredImage = 2 * sqrt(Median3DFiltered + (3/8));
此处“InputImage”和“Median3DFilteredImage”是3D矩阵,最后一个维度是时间(切片)。为了在ImageJ图像上重现以下操作,我不得不使用两个for循环,一个迭代图像切片(第三维),另一个循环迭代特定切片中的所有像素:
medFiltStack = medianFilteredImage.getStack()
newMedFiltStack = ImageStack(medianFilteredImage.width, medianFilteredImage.height)
InputStack = InputImage.getStack()
newInputStack = ImageStack(InputImage.width, InputImage.height)
for i in xrange(1 , medianFilteredImage.getNSlices() + 1):
ip = medFiltStack.getProcessor(i).convertToFloat()
ip2 = InputStack.getProcessor(i).convertToFloat()
pixels = ip.getPixels()
pixels2 = ip2.getPixels()
for j in xrange (len(pixels)):
pixels[j] = 2 * javaMath.sqrt(pixels[j] + (3.0/8.0) )
pixels2[j] = 2 * javaMath.sqrt(pixels2[j] + (3.0/8.0) )
newMedFiltStack.addSlice(ip)
newInputStack.addSlice(ip2)
medianFilteredImage = ImagePlus("MedianFiltered-Image", newMedFiltStack)
InputImage = ImagePlus("Input-Image", newInputStack)
我的问题如下:是否有办法在图像堆栈上执行数学运算,即在图像堆栈中的每个像素(体素)上执行数学运算,而无需编写明确访问图像的每个切片中的每个像素的代码,即循环。它似乎是一种非常原始的方式,我想知道是否没有一种最佳的方法来进行此操作。我还必须使用副本,然后为新图像提供与以前相同的名称,而不是使用原始图像并直接编辑它们。那么有没有办法编辑原始图像的像素值而不是图像的副本?任何帮助将不胜感激,因为我必须执行更多的数学运算。在代码量方面以及如果可能的话,在速度方面找到以最佳方式对图像进行数学运算的方法将是非常有用的。
答案 0 :(得分:1)
在纯ImageJ 1.x中,答案是:没有,除了访问每个切片并获取其ImageProcessor
之外别无他法。这就是ImageJ1处理其有限数量的维度(z,时间,通道)的方式,你总是有一个(超 - )2D平面堆栈。
然而,有一种更强大的方法来处理名为ImgLib的 n 维度图像,它与ImageJ2一起被包含在斐济。
为了避免重新发明轮子,你应该看看Jean-Yves Tinevez的精彩插件Image Expression Parser。与斐济一起使用headlessly,或者只看一下它的source code(它使用的是以前的版本,ImgLib1,但想法是一样的:你避免使用Java泛型对维度进行硬编码) ,见例如对于sqrt function:
public final <R extends RealType<R>> float evaluate(final R alpha) {
return (float) Math.sqrt(alpha.getRealDouble());
}