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 ImageJ Forum!
First, we spin up an ImageJ. For more details on how this works, see the Fundamentals of ImageJ notebook.
%classpath config resolver imagej.public https://maven.imagej.net/content/groups/public
%classpath add mvn net.imagej imagej 2.0.0-rc-71
ij = new net.imagej.ImageJ()
"ImageJ v${ij.getVersion()} is ready to go."
Added new repo: imagej.public
ImageJ v2.0.0-rc-71 is ready to go.
sourcePath = "https://imagej.net/images"
//sourcePath = System.getProperty("user.home") + "/data"
cells = ij.io().open(sourcePath + "/FluorescentCells.jpg")
mandrill = ij.io().open(sourcePath + "/baboon.jpg")
ij.notebook().display([["mandrill": mandrill, "cells": cells]])
[INFO] Populating metadata [INFO] Populating metadata [INFO] Populating metadata [INFO] Populating metadata
mandrill | cells |
---|---|
%classpath add mvn org.knowm.xchart xchart 3.5.2
import net.imglib2.FinalInterval
import org.knowm.xchart.CategoryChart
import org.knowm.xchart.CategoryChartBuilder
// Set this to the image you want to analyze.
image = mandrill
xLen = image.dimension(0)
yLen = image.dimension(1)
cLen = image.dimension(2)
// Create a chart.
CategoryChart chart = new CategoryChartBuilder().width(800).height(400).
title("Histogram").xAxisTitle("Bin").yAxisTitle("Count").build();
chart.getStyler().setPlotGridVerticalLinesVisible(false).setOverlapped(true)
cNames = ["red", "green", "blue"]
colors = [new java.awt.Color(0xED4337), new java.awt.Color(0x90D860), new java.awt.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 and add them to the chart.
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])
}
org.knowm.xchart.BitmapEncoder.getBufferedImage(chart)
import net.imglib2.FinalInterval
// N-dimensional crop.
eyes = ij.op().transform().crop(mandrill, FinalInterval.createMinSize(85, 5, 0, 335, 110, 1), true)
// Type conversion.
eyes32 = ij.op().convert().float32(eyes)
// Median filter.
median = ij.op().run("create.img", eyes32)
neighborhood = new HyperSphereShape(4)
ij.op().run("filter.median", median, eyes32, neighborhood)
// Difference of Gaussians.
dogFormula = "gauss(image, sigma1) - gauss(image, sigma2)"
dog = ij.op().eval(dogFormula, [
"image": eyes32,
"sigma1": [20, 20],
"sigma2": [4, 4]
])
// Grayscale morphology operators.
import net.imglib2.algorithm.neighborhood.HyperSphereShape
topHat = ij.op().morphology().topHat(eyes, [neighborhood])
blackTopHat = ij.op().morphology().blackTopHat(eyes, [neighborhood])
ij.notebook().display([["image":eyes, "median":median, "dog":dog, "topHat":topHat, "blackTopHat":blackTopHat]])
image | median | dog | topHat | blackTopHat |
---|---|---|---|---|
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.
ij.notebook().display([["image":image, "lowpass":inverse]])
image | lowpass |
---|---|