Skip to content

Commit 1d735e9

Browse files
committed
docs: improve text and fix minor errors
1 parent fbad912 commit 1d735e9

File tree

3 files changed

+56
-54
lines changed

3 files changed

+56
-54
lines changed

docs/Tutorials/ROI analysis.md

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,21 @@ const mask = image.threshold();
99
const roiMap = fromMask(mask);
1010
```
1111

12-
or, if an image has more complex background and many small elements positioned closely to each other, use `watershed` function:
12+
or, if an image has more complex background and many small elements are positioned closely to each other, use `watershed` function:
1313

1414
```ts
1515
const roiMap = watershed(image, { points, mask });
1616
```
1717

18-
You can see a good image to use threshold (on the left) and an image for watershed (on the right).
18+
You can see a good image to use threshold on the left and an image for watershed on the right.
1919

2020
![Techniques comparison](./images/roiAnalysis/ThresholdOrWatershed.png)
2121

2222
:::caution
2323
Before taking on the analysis of regions of interest we recommend to take a look at the tutorials for `watershed` and `threshold`.
2424
:::
2525

26-
For the sake of simplicity we will use the same example as in a threshold method. However, we will put a little twist and use an image of [TIFF](https://en.wikipedia.org/wiki/TIFF 'wikipedia link on .tiff format') format. This format is great for storing and editing images. It also allows adding metadata with extensive information about an image which we will examine a bit further in this tutorial. But for now let's take one step at a time.
26+
For the sake of simplicity we will use the same example as in a threshold method. However, we will put a little twist and use an image of [TIFF](https://en.wikipedia.org/wiki/TIFF 'wikipedia link on .tiff format') format. This format is great for storing and editing images of high quality. It also allows adding metadata with extensive information about an image which we will examine a bit further in this tutorial. But for now let's take one step at a time.
2727
To get regions of interest you need to extract them from a map:
2828

2929
```ts
@@ -34,23 +34,21 @@ const rois = roiMap.getRois({ kind: 'black' });
3434

3535
:::tip
3636
For `getRois()` method you can use options `minSurface` and `maxSurface` to filter the ROIs by surface size.
37-
So in this case we can specify the minimum surface of the regions in question:
3837

3938
```ts
40-
const rois = roiMap.getRois({ kind: 'black', minSurface: 64 });
39+
const rois = roiMap.getRois({ kind: 'black', minSurface: 1000 });
4140
```
4241

4342
:::
4443

4544
Now we have all the regions identified and stored. We can work on the analysis of those regions.
4645

4746
![Get ROIs](./images/roiAnalysis/MBR.jpg)
48-
![Get ConvexHull](./images/roiAnalysis/ConvexH.jpg)
4947

50-
To do so we need to understand what kind of analysis is necessary. Depending on the answer different tools can be used. Let's say we want to find the filter regions by size and shape. Now,
51-
For the size it is rather straight-forward. You can use the `getRois()` options, as was mentioned above, or you can use region's perimeter and surface properties to filter the ROIs.
48+
To do so we need to understand what kind of analysis is necessary. Depending on the answer, different tools can be used. Let's say we want to filter regions by size and shape.
49+
For filtering by size the process is rather straight-forward. You can use the `getRois()` options, as was mentioned above, or you can use region's perimeter and surface properties to filter the ROIs. We can detect
5250
In this example let's get the regions which are above an average size of the `rois` sample.
53-
First we need to find this average. It can be done in a rather straight-forward fashion:
51+
First we need to find this average. It can be done like this:
5452

5553
```ts
5654
let surfaceSum = 0;
@@ -73,7 +71,7 @@ for (const roi of rois) {
7371

7472
![Biggest rois](./images/roiAnalysis/biggestCells.jpg)
7573

76-
The selected regions can be investigated further. For instance, we can use property like `roundness` to see how close the region's shape is to a circle. Let's put arbitrarily 0.9 as a limit (the coefficient for a perfect circle will be 1).
74+
This provides us with a certain number of regions (colored in blue). The selected regions can be investigated further. For instance, we can use property like `roundness` to see how close the region's shape is to a circle. Let's put 0.9 as a limit (the coefficient for a perfect circle will be 1).
7775

7876
```ts
7977
let roundestRois = [];
@@ -84,8 +82,6 @@ for (const roi of biggestRois) {
8482
}
8583
```
8684

87-
![Roundest rois](./images/roiAnalysis/roundAndBig.jpg)
88-
8985
This provides us with a code like this:
9086

9187
```ts
@@ -100,68 +96,74 @@ for (const roi of rois) {
10096
}
10197
const avgSurface = surfaceSum / rois.length;
10298

103-
//We can calculate biggest and roundest rois in one cycle,
104-
//but we split the logic between the two for the sake of this
105-
//example.
99+
//We put the calculation of both biggest and
100+
//roundest rois into one loop for faster
101+
//computation.
106102
const biggestRois = [];
103+
const roundestRois = [];
107104
for (const roi of rois) {
108105
if (roi.surface >= avgSurface) {
109106
biggestRois.push(roi);
110-
}
111-
}
112-
113-
let roundestRois = [];
114-
for (const roi of biggestRois) {
115-
if (roi.roundness > 0.9) {
116-
roundestRois.push(roi);
107+
if (roi.roundness > 0.9) {
108+
roundestRois.push(roi);
109+
}
117110
}
118111
}
119112
```
120113

114+
![Roundest rois](./images/roiAnalysis/roundAndBig.jpg)
115+
121116
An image above highlights the ROIs that we found. Dark blue regions represent the particles that were above the average that we calculated. The light blue particles are the particles with an above average size and roundness above 0.9.
122-
This is just a fraction of tools that ImageJS possesses. There are multiple properties that you can discover more about in our [API features](../Features/Regions%20of%20interest/Regions%20of%20interest.md) section. Here is an example of the properties that you can use with each region of interest.
123-
124-
| Feature | Type | Value |
125-
| --------------- | ------------ | -------------------------------------------------------- |
126-
| `id` | `number` | -128 |
127-
| `origin` | `Point` | `{ row: 1547, column: 1602 }` |
128-
| `height` | `number` | 48 |
129-
| `width` | `number` | 50 |
130-
| `surface` | `number` | 1814 |
131-
| `eqpc` | `number` | 48.05888611016266 |
132-
| `ped` | `number` | 50.64165599181419 |
133-
| `feret` | `Feret` | |
134-
| `fillRatio` | `number` | 1 |
135-
| `sphericity` | `number` | 0.9489991029900559 |
136-
| `roundness` | `number` | 0.8948688625143686, |
137-
| `solidity` | `number` | 0.9674666666666667 |
138-
| `perimeter` | `number` | 159.095454429505 |
139-
| `convexHull` | `ConvexHull` | |
140-
| `mbr` | `Mbr` | |
141-
| `filledSurface` | `number` | 1814 |
142-
| `centroid` | `Point` | `{ column: 1626.577177508269, row: 1570.2546857772877 }` |
117+
This is just a fraction of tools that ImageJS possesses. There are many other properties that you can discover more about in our [API features](../Features/Regions%20of%20interest/Regions%20of%20interest.md) section. Here is an example of the properties that you can use with any region of interest:
118+
119+
| Feature | Type | Value |
120+
| --------------- | ------------ | ---------------------------------------------------------------------- |
121+
| `id` | `number` | -128 |
122+
| `origin` | `Point` | `{ row: 1547, column: 1602 }` |
123+
| `height` | `number` | 48 |
124+
| `width` | `number` | 50 |
125+
| `surface` | `number` | 1814 |
126+
| `eqpc` | `number` | 48.05888611016266 |
127+
| `ped` | `number` | 50.64165599181419 |
128+
| `feret` | `Feret` | `feret: {minDiameter, maxDiameter, aspectRatio}` |
129+
| `fillRatio` | `number` | 1 |
130+
| `sphericity` | `number` | 0.9489991029900559 |
131+
| `roundness` | `number` | 0.8948688625143686, |
132+
| `solidity` | `number` | 0.9674666666666667 |
133+
| `perimeter` | `number` | 159.095454429505 |
134+
| `convexHull` | `ConvexHull` | `convexHull: {points,perimeter,surface}` |
135+
| `mbr` | `Mbr` | `mbr: {points, surface, angle, width, height, perimeter, aspectRatio}` |
136+
| `filledSurface` | `number` | 1814 |
137+
| `centroid` | `Point` | `{ column: 1626.577177508269, row: 1570.2546857772877 }` |
143138

144139
## Getting metadata from TIFF files
145140

146-
Another aspect worth inspecting is extracting image metadata. If an image is of TIFF format, you can extract some metadata tags that can provide additional information about an image. For instance, you can get data such as image length and width or learn about image quality through bit depth(`bitsPerSample`) or X and Y Resolutions.
147-
The metadata of TIFF format is split into two parts: `tiff` and `exif` which is another image format. It can provide information about camera settings, for example. `exif`, however, is mostly used for storing metadata within image formats like JPEG. And since an `exif` part of returned metadata is empty we will focus on `tiff` part.
141+
Another aspect worth inspecting is extracting image metadata. Metadata represents information about an image itself. It can be something basic such as the date when an image was taken, or something specific like the name of the camera that the image was taken by. You can extract some metadata tags that can provide additional information about an image by using this command:
142+
143+
```ts
144+
const meta = image.meta;
145+
```
146+
147+
![Metadata](./images/roiAnalysis/metadata.png)
148+
149+
In ImageJS there are two supported formats for metadata: `exif` and `tiff`. While `exif` is a format used by digital images to store metadata, `tiff` is an image format used for high quality [raster graphics](https://en.wikipedia.org/wiki/Raster_graphics 'wikipedia link for raster graphics') images. Since our image in question is of `tiff` format and `exif` part of returned metadata is empty we will focus on `tiff` part.
148150

149151
```ts
150152
const meta = image.meta.tiff;
151153
```
152154

153-
There you will have other two parts: one part will be comprised of a map with fields and then an object of TIFF meta tags which these fields' values are attributed to.
155+
There you will have two other parts: one part will be comprised of a map with fields and then an object of TIFF meta tags which these fields' values are attributed to.
154156

155-
![Metadata](./images/roiAnalysis/metaDataScreen.png)
157+
![TIFF Metadata](./images/roiAnalysis/metadataScreen.png)
156158

157159
### Getting extra data
158160

159161
Within metadata, you might be wondering what this huge mix of letters and numbers represents:
160162

161163
![](./images/roiAnalysis/extraData.jpg)
162164

163-
These are custom fields added with additional information about an image. For instance, in this case you can get information about the microscope that was used, or the magnification level or the electrometric tension that was used while the image was taken. However, this data needs to be parsed, because it is difficult to decipher in its raw format.
164-
To do so you need to identify what is the key id of this text. In our case it is 34682, but it might not always be the case so check it beforehand.
165+
These are custom fields added with additional information about an image. For instance, in this case you can get information about the microscope that was used, or the magnification level or the electrometric tension that was used while the image was taken. However, this data needs to be parsed, as it is difficult to decipher in its raw format.
166+
To do so you need to identify what is the key id of this text. In our case it is `34682`, but it might not always be the case so check it beforehand.
165167

166168
Next thing we need to do is to parse this text.
167169

@@ -187,14 +189,14 @@ lines.forEach((a) => {
187189

188190
With this the data in the. console should look something like this.
189191

190-
![](./images/roiAnalysis/parsedExtraData.png)
192+
![Parsed extra data](./images/roiAnalysis/parsedExtraData.png)
191193

192194
### Getting pixel size
193195

194196
In this specific scenario we would also like to tell you about the way to calculate image's pixel size. It is an important aspect to deduce image's detail sharpness and display's quality.
195-
Pixel size can be one of metadata fields but if this isn't the case we would like to show you how you can calculate it from existing data.
197+
Pixel size can be one of metadata fields but if this isn't the case we would like to show you how you can calculate it from the existing data in this specific scenario.
196198

197-
If there is no such field as "Pixel size" you can calculate DPI resolution and apply it with magnification.
199+
To calculate pixel size you can calculate DPI resolution and apply it with magnification.
198200
DPI resolution represents the number of dots per inch. To calculate it we need to look at three lines in our parsed extra data: `XResolution`, `YResolution` and `ResolutionUnit`.
199201
X and Y resolutions are the number of dots per inch on X and Y axes. So, if they are equal, then DPI resolution equals to one of these values. However, this value might not be measured in inches. To check that we need to look at the value of `ResolutionUnit`.
200202
If its value equals to 2 then the X and Y resolutions are measured in inches.If it's 3 then it's in centimeters and has to be converted.
@@ -210,8 +212,8 @@ if (metaTags.XResolution == metaTags.YResolution && metaTags.XResolution) {
210212
DPIResolution = metaTags.XResolution;
211213
break;
212214
case 3:
213-
//converted from centimeters to inches
214-
DPIResolution = metaTags.XResolution*2.54;
215+
//converted from inches to centimeters
216+
DPIResolution = metaTags.XResolution/2.54;
215217
break;
216218
default:
217219
break;
-419 KB
Binary file not shown.
127 KB
Loading

0 commit comments

Comments
 (0)