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, C. T., et al. "ImageJ2: ImageJ for the next generation of scientific image data." arXiv preprint (2017).
Learn more about ImageJ at imagej.net. Learn about Beaker Notebook from its tutorials: Help → Tutorial.
Feedback is very welcome! Please start a discussion with us on the ImageJ Forum!
In [2]:
#@ImageJ ij
// Behind a firewall? Configure your proxy settings here.
//System.setProperty("http.proxyHost","myproxy.domain")
//System.setProperty("http.proxyPort","8080")
//////////////////////////////////////////////////////////////
// Load ImageJ. This may take some minutes the first time //
// while ImageJ is installed into ~/.groovy/grapes locally. //
//////////////////////////////////////////////////////////////
"ImageJ is ready to go."
Out[2]:
In [3]:
sourcePath = "http://imagej.net/images"
//sourcePath = System.getProperty("user.home") + "/data"
cells = ij.io().open(sourcePath + "/FluorescentCells.jpg")
lena = ij.io().open(sourcePath + "/lena.jpg")
[["cells":cells, "lena":lena]]
Out[3]:
In [4]:
import net.imglib2.FinalInterval
// Set this to the image you want to analyze.
image = lena
xLen = image.dimension(0)
yLen = image.dimension(1)
cLen = image.dimension(2)
// Create a chart.
import org.knowm.xchart.CategoryChart
import org.knowm.xchart.CategoryChartBuilder
CategoryChart chart = new CategoryChartBuilder().width(800).height(400).
title("Histogram").xAxisTitle("Bin").yAxisTitle("Count").build();
chart.getStyler().setPlotGridVerticalLinesVisible(false).setOverlapped(true)
import java.awt.Color
cNames = ["red", "green", "blue"]
colors = [new Color(0xED4337), new Color(0x90D860), new Color(0x7989FF)]
for (c in 0..cLen - 1) {
// Slice the image at this channel.
slice = ij.op().transform().crop(image, FinalInterval.createMinSize(0, 0, c, xLen, yLen, 1))
// Get the histogram.
histogram = ij.op().image().histogram(slice)
// Extract the counts to a Groovy-friendly data structure.
counts = []
for (value in histogram)
counts.add(value.getRealDouble())
chart.addSeries(cNames[c as int], (0..counts.size()-1), counts).setFillColor(colors[c as int])
}
chart
Out[4]:
__Quiz!__ What is wrong with those histograms?
In [5]:
import net.imglib2.FinalInterval
// N-dimensional crop.
face = ij.op().transform().crop(lena, FinalInterval.createMinSize(200, 200, 0, 170, 195, 1), true)
// Type conversion.
face32 = ij.op().convert().float32(face)
// Median filter.
median = ij.op().run("create.img", face32)
neighborhood = new HyperSphereShape(4)
ij.op().run("filter.median", median, face32, neighborhood)
// Difference of Gaussians.
dogFormula = "gauss(image, sigma1) - gauss(image, sigma2)"
dog = ij.op().eval(dogFormula, [
"image": face32,
"sigma1": [20, 20],
"sigma2": [4, 4]
])
// Grayscale morphology operators.
import net.imglib2.algorithm.neighborhood.HyperSphereShape
topHat = ij.op().morphology().topHat(face, [neighborhood])
blackTopHat = ij.op().morphology().blackTopHat(face, [neighborhood])
[["face":face, "median":median, "dog":dog, "topHat":topHat, "blackTopHat":blackTopHat]]
Out[5]:
In [7]:
import net.imglib2.util.Util
import net.imglib2.FinalDimensions
image = cells
radius = 10
def 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()
}
}
// Perform fft of the input.
fft = ij.op().filter().fft(image)
// Filter it.
lowpass(fft, 10)
// Reverse the FFT.
import net.imglib2.type.numeric.real.FloatType
inverse = ij.op().run("create.img", image, new FloatType())
ij.op().filter().ifft(inverse, fft)
// Display the result.
[["image":image, "lowpass":inverse]]
Out[7]:
In [ ]: