## Prerequisites

Before starting this lesson, you should be familiar with:

## Learning Objectives

After completing this lesson, learners should be able to:
• Describe the relationship between an intensity image and a derived binary image

• Apply a threshold to segment an image into foreground and background regions

## Motivation

One strategy to detect objects or specific regions in images is to first distinguish so-called background pixels, which do not contain objects or interesting regions from foreground pixels, which mark the areas of interest. This process is called two class semantic segmentation and is often referred to as image binarization. The foreground regions can then be further processed, e.g. to detect objects or perform intensity measurements.

## Concept map

graph TD I("Image") --> T("Threshold") T --> BI("Binary image / Binary mask") BI --- BG("Background pixels (false, 0)") BI --- FG("Foreground pixels (true, 1, 255)")

## Figure

#### Image thresholding

A common algorithm for binarization is thresholding. A threshold value `t` is chosen, either manually or automatically, and all pixels with intensities below `t` are set to 0, whereas pixels with intensities `>= t` are set to the value for the foreground. Depending on the software the foreground value can be different (e.g. 1 in MATLAB or 255 in ImageJ). At any pixel `(x,y)`:

`p_im(x,y) < t` `->` `p_bin(x,y) = 0`

`p_im(x,y) >= t` `->` `p_bin(x,y) = 1`

where, p_im and p_bin are the intensity and binary images respectively.

It is also possible to define an interval of threshold values, i.e. a lower and upper threshold value. Pixels with intensity values within this interval belong to the foreground and vice versa.

## Activities

• Open the image xy_8bit__two_cells.tif
• Visualise the image and inspect its data type and value content
• Threshold the image
• Identify a threshold value that segments both cells
• Apply that threshold, generating a binary image
• Visualise the binary image and inspect its data type and value content
• Threshold again, now choosing a threshold such that only the brighter cell is segmented

Show activity for:

## ImageJ GUI

• Inspect ImageJ binary image
• Inspect MATLAB binary image
• Find/apply a threshold
• Open xy_8bit__two_cells.tif
• Inspect pixel values to find a threshold separating fore- and background
• Hover over the image and observe the pixel values in ImageJ status bar
• Draw line profile and [Analyze > Plot Profile ] or [Ctrl-K]
• Inspect histogram using [Analyze > Histogram] or [Ctrl-H]
• [ Image > Adjust > Manual Threshold… ]
• `Lower threshold level` which is the value that you observed in the aforementioned step that would separate foreground and background
• `Upper threshold level` can be set to the maximum bit depth (in this case 255)
• Press OK, this will produce an overlaid image where you can see the regions above the threshold in red.
• Note: The image is not binary yet (check the pixel values)!
• Set binary options: [Process > Binary > Options ..] [X] Black background
• [Process > Binary > Convert to Mask], now the image is binary.
• Open xy_8bit__two_cells.tif
• Repeat above applying a higher threshold so that only the high intensity level nucleus becomes foreground

## MATLAB

%These matlab scripts illustrate separating the foreground from the %background using a threshold value provided by the user %Prompt user for a threshold value thres_val = input('Enter a threshold value: '); % Prompt user to choose an image, e.g. xy_8bit__two_cells.tif [file, path] = uigetfile("*.tif"); %Read input image in_image = imread(fullfile(path, file)); %display input image figure; imagesc(in_image); %Binarize input image with the threshold valuein_image bin_image = uint8(in_image>= thres_val); % Display binary image figure; imagesc(bin_image);

## KNIME ## Exercises

Perform one of the following exercises.

Show exercise/solution for:

## ImageJ GUI

Open image xy_8bit__PCNA.tif and

1. Find a threshold value so that there are 2 foreground nuclei.
2. Find a threshold value so that only the bright dots remain
3. Find threshold interval so that only the boundary of the nuclei remains.

## Solution

[File > Open…] xy_8bit__PCNA.tif

[Analyze > Plot Profile ] or [Ctrl-K]

1. Lower threshold, i.e. at about 5
2. Lower threshold at about 44

## ImageJ Macro

Open image xy_8bit__PCNA.tif and

1. Find a threshold value so that there are 2 foreground nuclei.
2. Find a threshold value so that only the bright dots remain
3. Find threshold interval so that only the boundary of the nuclei remains.

## Solution

``````open("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__PCNA.tif")
selectWindow("xy_8bit__PCNA.tif");
run("Duplicate...", "title=[2 nuclei]");
selectWindow("xy_8bit__PCNA.tif");
run("Duplicate...", "title=[boundary]");
selectWindow("xy_8bit__PCNA.tif");
run("Duplicate...", "title=[dots]");
selectWindow("2 nuclei");
setThreshold(5, 255);
setOption("BlackBackground", true);
selectWindow("boundary");
setThreshold(4, 4);
setOption("BlackBackground", true);
selectWindow("dots");
setThreshold(44, 255);
setOption("BlackBackground", true);
``````

## ImageJ Jython

Open image xy_8bit__PCNA.tif and

1. Find a threshold value so that there are 2 foreground nuclei.
2. Find a threshold value so that only the bright dots remain
3. Find threshold interval so that only the boundary of the nuclei remains.

## Solution

``````from ij import IJ, ImagePlus
from ij.plugin import Thresholder
# image is xy_8bit_PCNA.tif
inputImage = IJ.openImage("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__PCNA.tif")
IJ.setRawThreshold(inputImage, 5, 255, None)
binaryImage = ImagePlus('Binary image 2 nuclei', Thresholder.createMask(inputImage))
binaryImage.show()
IJ.setRawThreshold(inputImage, 4, 4, None)
binaryImage_boundary.show()
IJ.setRawThreshold(inputImage, 44, 255, None)
binaryImage_brightdots = ImagePlus('Binary bright dots', Thresholder.createMask(inputImage))
binaryImage_brightdots.show()
``````

## Solution with input parameters

``````#@ Integer (label="Lower threshold") thr1
#@ Integer (label="Upper threshold") thr2

from ij import IJ, ImagePlus
from ij.plugin import Thresholder
# image is xy_8bit_PCNA.tif should be already open
inputImage = IJ.openImage("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__PCNA.tif")
IJ.setRawThreshold(inputImage, thr1, thr2, None)
binaryImage.show()
``````

## Assessment

### Fill in the blanks

• Pixels in a binary image can have maximally ___ different values.
• If the threshold is larger than the maximal pixel value in the intensity image, all pixels in the binary image have a value of ___.

## Solution

• Pixels in a binary image can have maximally 2 different values.
• If the threshold is larger than the maximal pixel value in the intensity image, all pixels in the binary image have a value of 0.

### True or False

• There is only one correct threshold value in order to convert an intensity image into a binary image.
• Binary images are always unsigned 8-bit where the foreground is 255.

## Solution

• There is only one correct threshold value in order to convert an intensity image into a binary image. False
• Binary images are always unsigned 8-bit where the foreground is 255. False

## Follow-up material

Recommended follow-up modules: