You are on page 1of 15

NB2121: Image Analysis

Practical 3: Morphology

Learning Goals
After this practical you should know by heart how to:
 Set the pixel convention for binary morphology in ImageJ.
 Visualize the structuring elements used by ImageJ.
 Apply binary dilation, erosion, opening, and closing.
 Apply gray-scale dilation, erosion, opening, and closing.
 Select the right binary operator to remove small objects.
 Use morphological operators to get the largest object.
 Create a selection of a binary object automatically.
 Specify a custom selection in any given image.
 Clear or invert the intensities of any given image.
 Remove boundary objects and fill holes in a binary image.
 Use the particle analyzer functionality of ImageJ.
 Write a macro to fully automate object measurements.

Object Versus Background


In mathematical morphology, binary images are considered as discrete point sets
(pixels in 2D, voxels in 3D). By definition, each point in a binary image can have only
one of two possible values: object or background.

A few remarks need to be made here:


 In order for an image to be considered as a binary image by ImageJ, it must be
an 8-bit image in which the value of each pixel is either 0 or 255 (not 1).
 In some articles and software, pixels with value 0 are considered background
(black = background and white = objects), while in others they are considered
object pixels (white = background and black = objects).
 In this course we use the first convention: pixels with value 0 are considered as
background, so visually we concentrate on the white pixels as objects.
 ImageJ is able to work with both conventions. To make sure we all use the same
convention, go to the ImageJ menu for binary mathematical morphology, which is

1
Process > Binary, and run the command Options… (the last one in the list).
Select the option Black background and click OK.

Structuring Element
As we have learned in today’s lecture, the structuring element used by morphological
operators can in principle have any shape. However, the commands in the Process
> Binary menu all use only one particular structuring element.

In linear image processing problems (remember the previous two lessons) we can
find the convolution kernel of a filter by feeding it with an impulse. Similarly, we can
find the structuring element by applying a dilation operation to an impulse.

Question

Create a binary impulse image (2D) and run the command Process > Binary >
Dilate. What structuring element is used by ImageJ? Draw the pixel mask.

Answer

ImageJ uses a 3 x 3 structuring element (all pixels “on” with center pixel as origin):

A wider variety of structuring elements is available in the ImageJ command for gray-
scale mathematical morphology: Process > Morphology > Gray Morphology.
Since binary images are actually gray-scale images (but with only two gray values: 0
or 255) we can also use this command to perform binary mathematical morphology.

Question

Run the command Process > Morphology > Gray Morphology to perform dilation
on your binary impulse image using a circular structuring element with radius 1. What
does the structuring element look like (draw the mask)? Also answer the question for
circular structuring elements with radii 1.5 and 2.0 and 2.5 pixels.

2
Answer

Radius 1.0 Radius 1.5

Radius 2.0 Radius 2.5

Basic Morphological Operators


Open Images / Morphology / Gray Image 08.tif and make a duplicate of the image
(use the corresponding ImageJ command) so that we can play around with the
duplicate while keeping the original image as a visual reference.

In order to do binary morphology we first need to convert the (duplicate) image to a


binary image. One way to do this is by running the command Process > Binary >
Make Binary, which analyzes the intensity histogram of the image, and then makes
some intelligent decision about whether pixels belong to the object (higher
intensities) or to the background (lower intensities) and labels them accordingly.

Please note that this command does not generally yield a good binary result for any
image, but it does so for this particular image, because its intensity histogram is
nicely bimodal (check for yourself). The command uses an automatic thresholding
method named IsoData. In the next lesson (on segmentation) you will learn much
more about different automatic thresholding methods, including this one. For now, it
is important to remember that it is just one specific thresholding method, and you
should use it with care (only when the histogram is bimodal).

3
The behavior of the basic morphological operators Erode, Dilate, Open, and Close
from the Process > Binary menu is determined by the settings in the window that is
opened by running the command Process > Binary > Options…

Let’s explore the effects of the different operators. But instead of running the
commands Erode, Dilate, Open, and Close every time, we can also experiment with
them using the Preview option of the Binary Options window. Run the command to
open that window (make sure it is applied to the binary image and not the original
gray-scale image) and start with the same settings as shown above.

Select Erode from the Do choice list in the window and look at its effect by switching
the Preview option on and off a few times. Repeat this for Dilate, Open, and Close.

The number specified in the Iterations field of the window determines how many
times the operator is applied.

Question

Which operator and how many iterations of this operator are needed to remove the
smallest object (the tiny noise spot close to the center of the image) while preserving
the morphology of the other objects (the real cells) as best as possible? And why do
we need this many iterations and not less (or more)?

Answer

Operator: Open

4
Iterations: 3

Why: The right choice in this case is the Open operator because it first erodes
objects pixels and then dilates the remaining objects more or less back to their
original morphology. Erode by itself only removes object pixels, Dilate only adds
object pixels, and Close first dilates and then erodes objects so that does not result
in a removal of small objects. The value of the Iterations parameter determines how
many erosions are first applied, followed by the same number of dilations. In this
case we need 3 iterations, because the “radius” of the spot is about 3 pixels, so 1 or
2 erosions (each of them “eating away” only one layer of pixels) are not sufficient to
remove it. And we should not use more than 3 iterations, because the Open operator
does change the morphology of the remaining objects a little bit, which gets worse
and worse as the number of iterations increases.

Measuring Neuron Soma Size


Open Images / Morphology / Single Neuron.tif. The image shows a neuronal cell
with its soma (cell body) and dendrites (outgrowth). Suppose we want to measure
certain morphological properties of the soma of this neuron, such as its size.

Question

Binarize the image and repeat the previous exercise to find out which operator and
how many iterations are needed to keep only the soma and nothing else.

Answer

Operator: Open

Iterations: 8

Why: The same argumentation as in the previous exercise. Now we need more
iterations because the diameters of the thickest dendrites (to be eroded away) are
larger. Using a few more iterations does not make much difference in this case.

Once you have found the optimal settings you can click the OK button of the Binary
Options window to perform the operation and get the processed image.

5
As you can see, the resulting binary image is quite blocky. This is because of the
square structuring element used by the Binary commands of ImageJ.

An alternative approach to get the soma of the neuron in the given image is to apply
gray-scale morphology first and then do the binarization afterwards.

Question

Reopen the original gray-scale image and apply the ImageJ command for gray-scale
mathematical morphology (see above). Select the circle as the structuring element.
Which operator and which radius are needed to keep only the soma and nothing else
after binarization of the processed image?

Answer

Operator: Open (same as in the binary case).

Radius: 12 yields a fairly good result. Smaller radii leave additional structures or
blobs in places where dendrites sprout from the soma. Further increasing the radius
would yield even smoother results but it does not work with the standard binarization
command: too many structures are then labeled as object. As explained above, this
command makes certain assumptions about the intensity statistics in an image and
automatically selects a threshold based on this, but apparently when using larger
radii the statistics change so much that these assumptions are no longer valid. A
different binarization command would be needed.

Comparing the results of the previous exercise (image on the left) and the current
exercise (image on the right) we see that the soma in the latter is smoother:

6
In previous practicals you have learned how to measure various properties of objects
in images using the Analyze > Measure command. However, if this command is run
without a selection (an object outline), it will measure the entire image.

So if we want to measure the soma in the processed image, we need to create a


selection. And to avoid human subjectivity, we don’t want to do this manually (as we
have done previously using, for example, the polygonal selection tool of ImageJ), but
we want to obtain the selection completely automatically.

ImageJ provides an easy command to automatically create a selection (outline) of


the object pixels in a binary image: Edit > Selection > Create Selection.

Question

What is the area and perimeter (in pixels) of the soma in Single Neuron.tif obtained
using the binary morphology versus the gray-scale morphology approach?

Answer

Area: 7903 versus 7502 pixels.

Perimeter: 373.522 versus 359.061 pixels.

As expected, the area and perimeter obtained with the gray-scale morphology
approach are smaller, because the soma contour is smoother there.

Removing Boundary Objects


Open Images / Morphology / CHO PCNA-GFP 1.tif. The image shows the nuclei of
several Chinese hamster ovary (CHO) cells that are PCNA-GFP labeled. We want to
measure the size and the average fluorescence intensity of each nucleus without any
manual cell selection. Eventually we want to fully automate the process.

Make a duplicate of the image so that we can use the duplicate to test things while
keeping the original as a visual reference. Then make a binary image of the duplicate
(use the same command as before) to see if we get a nice separation of pixels into
object (white) versus background (black).

As you can see, this doesn’t really work very well: the result is rather noisy (the cells
contain many black pixels, the cell boundaries are not smooth, and the background
contains some white pixels). Undo the binarization using Edit > Undo.

7
The image contains too much noise to start analyzing things directly. In such
situations it is very helpful to first make the image a bit smoother by using Gaussian
blurring. Run Process > Filters > Gaussian Blur… with a Sigma of 2 pixels (that
means do not use the Scaled Units option). Make a binary image of the result.

Notice that some of the cells (the ones at the boundary) partly fall outside the image.
Since it does not make sense to measure their size, they should be excluded from
the binary image. As discussed in today’s lecture this can be done by applying binary
morphological reconstruction using the boundary pixels as seed points.

We are now going to implement this operation. But first make sure the settings of the
Binary Options window are put back to their initial values (as shown before). Most
importantly, the number of Iterations must be 1 again, as this setting is also used by
Process > Binary > Dilate (and other commands).

Perform the following steps:


 Rename the binary image to Objects using Image > Rename…
 Duplicate the Objects image using Boundary as the title for the duplicate.
 Run Edit > Selection > Specify… on Boundary and specify the Width, Height,
X coordinate, and Y coordinate values such that the resulting rectangular
selection covers the entire image except for the boundary pixels.
 Run Edit > Clear to keep only the boundary pixels and clear the rest.
 Run Edit > Selection > Select None to remove the selection.

If everything went well, the Boundary image should now be black (background
value) everywhere except for the boundary pixels, which should still have the same
values as in the original Objects image. If not, repeat the above steps correctly.

Perform the next set of steps:


 Run Plugins > Macros > Record… to start the macro recorder.
 Apply a single dilation to Boundary (run the corresponding menu command).
 Run Process > Image Calculator…, using Boundary as Image 1, AND as
Operation, and Objects as Image 2 (deselect the other options).
 Click Create in Recorder window (a new macro window opens).
 Close the Recorder window.

In the new macro window you can now simply click the Run button to repeat the
dilation operation followed by the AND operation to see the Boundary image grow.
Repeat this until there is no more change.

8
At this point the Boundary image contains all the boundary objects of the original
Objects image. Now use the Image Calculator to subtract Boundary from Objects
so that the resulting image contains only the cells that fall entirely within the image.

The only thing that is not so nice about the above approach is that you have to
manually click the Run button of the macro window many times and you need to
visually check whether there is no more change. It would be much better if we could
automate all of this, so that only one click of the Run button is needed.

Question

Extend the macro code so that if you Run the macro on the initial Boundary image it
will automatically repeat the dilation + AND operation again and again until there is
no more change in the image. Write down the resulting macro code below and also
save the macro using File > Save as… in the macro window (save it wherever you
want but use the .ijm extension of the file name).

Hints for this exercise:


 Make a new initial Boundary image (with only the boundary pixels) and save that
image so you can simply reload it each time you need to test your macro.
 As a measure of change, you could, for example, keep track of the mean intensity
in the image. The macro function for this is getStatistics(area,mean). See Help
> Macro Functions… for online descriptions of all built-in macro functions of
ImageJ including this one. In particular, notice that this function can have more
arguments, but that “trailing arguments can be omitted”. Since we want the mean
intensity value, we need to keep at least the first two arguments (as above). Also
notice that the function stores the values of the area and the mean in the
variables used as arguments in the function call.
 Repeating a series of operations can be done by putting them in a while loop in
your macro code. See the ImageJ Macro Guide linked on Brightspace for a
description of looping statements such as while. The only thing you need to do is
to define the right stopping criterion.

Answer

The following macro reconstructs the boundary objects fully automatically (but
different implementations are possible that will give the same result):

// Make sure to reset Binary > Options:


run("Options...", "iterations=1 count=1 black do=Nothing");

9
// Algorithm:
oldmean = 0;
getStatistics(area,mean);
while(mean != oldmean) {
oldmean = mean;
run("Dilate");
imageCalculator("AND", "Boundary","Objects");
getStatistics(area,mean);
}

Filling Object Holes


The Objects image after removal of the Boundary objects is still not ready for doing
measurements because most of the remaining objects contain holes.

Question

What series of steps is needed to fill the holes in all objects of image Objects?

Hint: See today’s lecture. And you can reuse the macro you wrote above.

Answer

The following steps will fill the holes in all objects:


 Invert the image.
 Create a boundary image (as before).
 Run the macro of the previous exercise.
 Invert the result again.

Apply these steps to fill the holes in Objects. Notice that inversion of intensities in an
image can be done using the command Edit > Invert.

Save the resulting image (just in case).

Measuring Mean Object Intensities


After the previous exercise you should now have an image that contains only objects
that are fully within the image and that have no holes. We can use these objects as

10
pixel masks for doing measurements on the cells in the original gray-scale image
CHO PCNA-GFP 1.tif that we started with.

Run the command Analyze > Analyze Particles… to open the window shown below
and use the exact same settings. When you click OK, ImageJ will search for blobs of
connected pixels and put them as separate selections in the ROI Manager.

If you select the options Show All and Labels in the ROI Manager you will see the
labeled selections as an overlay in the image.

Activate the original gray-scale image CHO PCNA-GFP 1.tif and make the selections
visible in that image by clicking Show All again in the ROI Manager.

11
Question

What is the area and the mean fluorescence intensity in each cell nucleus? Compare
your measurements with those of your neighbor. Are there any differences?

Answer

Cell 1: Area = 161.983 Mean = 85.689


Cell 2: Area = 187.151 Mean = 90.082
Cell 3: Area = 221.049 Mean = 95.461
Cell 4: Area = 223.537 Mean = 91.607
Cell 5: Area = 197.430 Mean = 69.607
Cell 6: Area = 164.512 Mean = 91.956
Cell 7: Area = 205.548 Mean = 73.585
Cell 8: Area = 143.259 Mean = 93.725

There should not be any differences between your results and those of your
neighbors because you both used the exact same computations. The higher the level
of automation and standardization of methods and parameters, the better the
reproducibility of the measurements.

12
Fully Automated Measurements
In the previous exercises you have learned several useful image processing steps to
get biologically meaningful and fully reproducible measurements from a gray-scale
image without making any manual selections.

However, even though you wrote a macro to automate some of the steps, you still
needed to do quite a bit of manual work, such as picking commands from the ImageJ
menus and setting the right parameter values. Also, some of these parameter values
were specific for the given image.

That is unacceptable if you have to do these measurements on hundreds of images.


What you need then is a macro that does everything in a single click of the Run
button, and that also works for images of, for example, different sizes.

Challenge

Write a macro that fully automatically performs the measurement process we


designed in the previous exercises. That is, after loading CHO PCNA-GFP 1.tif,
a single click of the Run button should result in the above measurements.

The macro should work also for other (but similar) images. That is, after loading CHO
PCNA-GFP 2.tif, and without changing the macro code, a single click of the Run
button should produce sensible measurements also for that image.

Hints for this challenge:


 Use the macro recorder to get the code for the first few steps of the process (up to
the point where you need to remove the boundary objects).
 Then create a macro of those steps (a new macro window will open) to which you
can manually add more code as needed. At the same time, keep the recorder
window open as well, so you can see how each menu command translates into
macro code, which you can then copy to your macro.
 Inspect which commands in your macro code are image-specific, and try to
generalize them by using variables and relevant macro functions. See the ImageJ
Macro Guide for more explanation of variables. And see Help > Macro
Functions… to find useful macro functions.
 The previous macro (for binary morphological reconstruction) will be needed
twice: once for removing the boundary objects and a second time for filling the
holes in the remaining objects. To avoid doubling of code, the best way is to put
this piece of code in a function. See the ImageJ Macro Guide under User-

13
Defined Functions for more information on how to do this.
 Do not try to write the entire macro script at once, but build it up step by step, and
test the intermediate versions to see if the code does what it should do.

Solution

The following macro fully automates the measurement process. Empty lines are
added just for better readability. And some commands are added to make the macro
applicable also to other images (with a different name, width, height) and to close all
windows that we don’t need anymore once we have the ROIs.

input = getTitle(); // Name of the input image

run("Duplicate...", "title=Objects");
run("Gaussian Blur...", "sigma=2");
run("Make Binary");

run("Duplicate...", "title=Boundary");
w = getWidth() - 2; // Width of the selection
h = getHeight() - 2; // Height of the selection
run("Specify...", "width=&w height=&h x=1 y=1");
run("Clear", "slice");
run("Select None");

reconstruct(); // First call to the function below

imageCalculator("Subtract", "Objects","Boundary");

selectWindow("Boundary");
close();

run("Invert");
run("Duplicate...", "title=Boundary");
run("Specify...", "width=&w height=&h x=1 y=1");
run("Clear", "slice");
run("Select None");

reconstruct(); // Second call to the function below

run("Invert");
rename("Masks");

14
run("Analyze Particles...", "pixel add");
roiManager("Show All with labels");

selectWindow(input);
roiManager("Show All with labels");

run("Set Measurements...", "area mean redirect=None decimal=3");


roiManager("Measure");

selectWindow("Objects");
close();
selectWindow("Masks");
close();

function reconstruct() {
run("Options...", "iterations=1 count=1 black do=Nothing");
oldmean = 0;
getStatistics(area,mean);
while(mean != oldmean) {
oldmean = mean;
run("Dilate");
imageCalculator("AND", "Boundary","Objects");
getStatistics(area,mean);
}
}

15

You might also like