Welcome to the ImageJ tutorial series. These notebooks offer a hands-on series of lessons for learning ImageJ.
For a quick demo of what ImageJ can do, ___just scroll down___!
To dive in to the tutorials, click the links below. If ImageJ is new to you, please try the "Using ImageJ" notebooks first.
For a thorough academic overview of the ImageJ 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.
Feedback is very welcome! Please share your ideas on the Image.sc Forum!
First, we tell the notebook to download and install ImageJ 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 ImageJ functionality is available to the notebook, we create an ImageJ 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 ImageJ 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()
}
}
script1646677426732$_run_closure1@4e976eac
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 |
---|---|