Skip to content

Commit 4515b03

Browse files
docs: add threshold roi tutorial (#85)
--------- Co-authored-by: Daniel Kostro <[email protected]>
1 parent dd5973a commit 4515b03

File tree

8 files changed

+1256
-0
lines changed

8 files changed

+1256
-0
lines changed

docs/Glossary.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ hysteresis image.
4242

4343
[Image noise](https://en.wikipedia.org/wiki/Image_noise 'wikipedia link on image noise') refers to random variations in pixel values within an image, which can lead to unwanted visual artifacts and reduced image quality. It is often caused by various factors during image acquisition, transmission, or processing. Image noise can obscure details, reduce contrast, and make it harder to extract meaningful information from an image.
4444

45+
### Image segmentation
46+
47+
[Image segmentation](https://en.wikipedia.org/wiki/Image_segmentation 'wikipedia link on image segmentation') is a technique that divides an image into multiple regions or parts. The goal of segmentation is to simplify and/or change the representation of an image into more meaningful and easier-to-analyze parts. Each region typically corresponds to objects or meaningful areas within the image, such as distinct shapes, colors, or textures.
48+
4549
### Intensity
4650

4751
[Intensity](https://en.wikipedia.org/wiki/Color_histogram 'wikipedia link on histogram') refers to the brightness or darkness of a pixel or region within an image. It quantifies the amount of light or energy that a pixel or area emits, reflects, or transmits. Intensity values are typically represented numerically and can be single-channel (grayscale) or multi-channel (color) depending on whether the image is grayscale or color.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
In this tutorial we are going to cover the threshold operation and how to get a map of regions from the threshold's mask.
2+
3+
## Synopsis
4+
5+
Here is a quick summary of this tutorial.
6+
Threshold is used for [image segmentation](../Glossary.md#image-segmentation) to locate specific regions of interest (ROI) by separating background and foreground of the image. By doing so, we can create a map of regions, a `RoiMapManager` object.
7+
8+
Once threshold is applied, you will get a mask, which will allow you to localize and extract specific objects or regions of interest situated on the image.
9+
10+
```ts
11+
//If an image's color model is not `grey` then it first needs to be grayscaled.
12+
//Threshold algorithm works only if an image has one channel.
13+
if (image.colorModel !== 'GREY') {
14+
image = image.grey();
15+
}
16+
const mask = image
17+
//Before proceeding with threshold application it is recommended
18+
//to blur the image. Do not overdo it. With a kernel too big,
19+
//regions' borders start to deteriorate.
20+
.blur({ width: 3, height: 3 })
21+
//Try several algorithms to see which one fits your
22+
//needs the best.
23+
.threshold({ algorithm: 'otsu' });
24+
const roiMapManager = fromMask(mask);
25+
```
26+
27+
## What is threshold and where it is used
28+
29+
One of the ImageJS features is the ability to extract and analyze specific regions of the image(regions of interest or ROI).
30+
However, to get these regions you need to localize them first. This is where thresholding comes in.
31+
32+
Thresholding is an [image segmentation](../Glossary.md#image-segmentation) technique. It separates image's foreground objects from their background based on pixel intensity value. It works especially well when background is rather simple and well-defined.
33+
For instance here is an image of particles under electronic microscopy.
34+
35+
![Particles image](./images/threshold/greys.png)
36+
37+
Each object is well-defined and separated from each other, while the background is basically a gray-colored canvas. In this case threshold algorithm will fit perfectly.
38+
39+
## Choosing an algorithm
40+
41+
There are two ways of using threshold: by calling an algorithm name or by directly using a threshold value.
42+
If you want to use threshold by a threshold value of one of the algorithms, you can use `computeThreshold` function:
43+
44+
```ts
45+
const value = computeThreshold(image, 'otsu');
46+
// computeThreshold computes the intensity value, but threshold function accepts it
47+
//as a ratio between 0 and 1. So a division on maximum value is necessary.
48+
const mask = image.threshold({ threshold: value / image.maxValue });
49+
```
50+
51+
The output result will be identical to a result with a threshold algorithm as a parameter.
52+
53+
![Otsu histogram](./images/threshold/OtsuVisualization.png)
54+
55+
The default algorithm is [`otsu`](https://en.wikipedia.org/wiki/Otsu%27s_method 'wikipedia link on otsu'). It is a popular technique that uses weighted variance between two classes of pixels.
56+
In ImageJS we use [cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function 'wikipedia link to cumulative distribution function') to compute cumulative probability of encountering pixel intensities up to a certain level. This allows calculating between-class variance between the two created classes and find an optimal threshold value.
57+
After that it checks each pixel whether its intensity value is smaller or bigger than the calculated threshold. You can see a histogram of otsu's output above.
58+
59+
![Different algorithm outputs](./images/threshold/MaskCombosThreshold.png)
60+
61+
As you can see, `otsu` algorithm defines regions quite well.
62+
However, an output of each algorithm will vary from one image to another. ImageJS possesses multiple threshold algorithms.
63+
So we strongly recommend to try several variants to see which one fits your needs better.
64+
65+
By using threshold method you convert an image into a `Mask` class object which is a binary image. In this case it clearly separates objects from the background.
66+
67+
```ts
68+
// Algorithm is otsu by default but
69+
// we added the parameter here explicitly to
70+
// show how the parameter is used.
71+
const mask = image.threshold({ algorithm: 'otsu' });
72+
```
73+
74+
![Otsu output](./images/threshold/OTSU.png)
75+
76+
## Finding ROI map
77+
78+
Now all is left is to locate and store those objects by creating a `RoiMap` object. `RoiMap` is an object that stores all the data about regions of interest situated on the image.
79+
To get this map you need to apply `fromMask()` function:
80+
81+
```ts
82+
import fromMask from 'image-js';
83+
84+
const roiMap = fromMask(mask);
85+
```
86+
87+
In the end you should be able to get a map of all the regions of interest (black ROIs are colored here):
88+
![Black ROIs](./images/threshold/ROIsColored.jpg)
89+
90+
:::info
91+
It is worth mentioning an `allowCorners` option of `fromMask` function. You can specify if regions connected by corners should be considered as two separate regions or as one whole region.
92+
This option is set to `false` by default (Different ROIs are colored in different colors).
93+
94+
![Allowing corners](./images/threshold/allowingCorners.svg)
95+
:::
107 KB
Loading
7.67 KB
Loading
39 KB
Loading
409 KB
Loading

0 commit comments

Comments
 (0)