Welcome to the ImageJ2 tutorial series. These notebooks offer a hands-on series of lessons for learning ImageJ2. ImageJ2 is a rewrite of ImageJ. See here to view the mission of ImageJ2 and how it differs from ImageJ.
For a quick demo of what ImageJ2 can do, ___just scroll down___!
To dive in to the tutorials, click the links below. If ImageJ2 is new to you, please try the "Using ImageJ2" notebooks first.
For a thorough academic overview of the ImageJ2 software stack, including its features, history, motivation and goals, see:
Rueden CT et al. "ImageJ2: ImageJ for the next generation of scientific image data." BMC Bioinformatics 18:529 (29 November 2017).
Learn more about ImageJ at imagej.net. Learn more about Jupyter Notebook at jupyter.org.
See also scikit-image tutorial notebooks and SimpleITK tutorial notebooks.
If interested, see Javadocs for ImageJ2, SciJava, and more and how to use them.
Feedback is very welcome! Please share your ideas on the Image.sc Forum!
First, we tell the notebook to download and install ImageJ2 from the remote repository.
%classpath config resolver scijava.public https://maven.scijava.org/content/groups/public
%%classpath add mvn
net.imagej imagej 2.0.0-rc-71
net.imagej imagej-notebook 0.7.1
Added new repo: scijava.public
Now that ImageJ2 functionality is available to the notebook, we create an ImageJ2 gateway.
// Creates a new ImageJ2 gateway: a variable to be used as the central enrty point to any ImageJ2 functionality
ij = new net.imagej.ImageJ()
"ImageJ v${ij.getVersion()} is ready to go."
ImageJ v2.0.0-rc-71 is ready to go.
For further details, see the Fundamentals of ImageJ2 notebook.
You can open images from local files as well as remote URLs.
image = ij.io().open("https://imagej.net/images/lymp.tif")
histogram = ij.op().image().histogram(image)
mandrill = ij.io().open("https://imagej.net/images/baboon.jpg")
[INFO] Populating metadata [INFO] Populating metadata
import net.imglib2.FinalInterval
min = [85, 5, 0]
len = [335, 110, 1]
bounds = FinalInterval.createMinSize(min[0], min[1], min[2], len[0], len[1], len[2])
eyes = ij.op().transform().crop(mandrill, bounds, true)
eyes32 = ij.op().convert().float32(eyes)
eyes.firstElement().getClass().getName()
net.imglib2.type.numeric.integer.UnsignedByteType
eyes32.firstElement().getClass().getName()
net.imglib2.type.numeric.real.FloatType
import net.imglib2.algorithm.neighborhood.HyperSphereShape
median = ij.op().run("create.img", eyes32)
neighborhood = new HyperSphereShape(4)
ij.op().run("filter.median", median, eyes32, neighborhood)
dogFormula = "gauss(image, sigma1) - gauss(image, sigma2)"
// The [] in Groovy makes a list or a map storing values
dog = ij.op().eval(dogFormula, [
"image": eyes32,
"sigma1": [20, 20],
"sigma2": [4, 4]
])
topHat = ij.op().morphology().topHat(eyes, [neighborhood])
blackTopHat = ij.op().morphology().blackTopHat(eyes, [neighborhood])
ij.notebook().display(["median":median, "topHat":topHat, "blackTopHat":blackTopHat])
median | |
topHat | |
blackTopHat |
ij.notebook().display([["median":median, "topHat":topHat, "blackTopHat":blackTopHat]])
median | topHat | blackTopHat |
---|---|---|
Define a lowpass filtering function, operating in the Fourier domain:
import net.imglib2.util.Util
lowpass = { fft, radius ->
// Declare an array to hold the current position of the cursor.
pos = new long[fft.numDimensions()]
// Define origin as 0,0.
long[] origin = [0, 0]
// Define a 2nd 'origin' at bottom left of image.
// This is a bit of a hack. We want to draw a circle around the origin,
// since the origin is at 0,0 - the circle will 'reflect' to the bottom.
long[] origin2 = [0, fft.dimension(1)]
// Loop through all pixels.
cursor = fft.localizingCursor()
while (cursor.hasNext()) {
cursor.fwd()
cursor.localize(pos)
// Calculate distance from 0,0 and bottom left corner
// (so we can form the reflected semi-circle).
dist = Util.distance(origin, pos)
dist2 = Util.distance(origin2, pos)
// If distance is above radius (cutoff frequency) set value of FFT to zero.
if (dist > radius && dist2 > radius)
cursor.get().setZero()
}
}
script1650604747034$_run_closure1@5cb69e02
Perform a fast Fourier transform (FFT) on the image, run the lowpass filter, then invert the FFT:
import net.imglib2.type.numeric.real.FloatType
// Perform fft of the input.
fft = ij.op().filter().fft(image)
// Filter it.
lowpass(fft, radius=10)
// Reverse the FFT.
inverse = ij.op().run("create.img", image, new FloatType())
ij.op().filter().ifft(inverse, fft)
// Display the result.
ij.notebook().display([["image":image, "lowpass":inverse]])
image | lowpass |
---|---|