Skip to content

35 region of interests #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
75e6de7
docs wip give structure to roi analysis
EscapedGibbon Nov 1, 2023
389c586
Merge remote-tracking branch 'origin/main' into 35-region-of-interests
EscapedGibbon Nov 9, 2023
3698838
docs wip commit of unfinished roi files
EscapedGibbon Nov 15, 2023
afa3d15
docs wip add explanation on feret convex hull and mbr
EscapedGibbon Nov 20, 2023
f60f582
Merge remote-tracking branch 'origin/main' into 35-region-of-interests
EscapedGibbon Nov 22, 2023
2418324
docs wip make analysis page and add fill ratio, solidity,sphericity
EscapedGibbon Nov 24, 2023
90e4bb9
docs wip add more explanation on current and add new features
EscapedGibbon Nov 29, 2023
5c2e899
docs wip finalize analysis part
EscapedGibbon Nov 30, 2023
a7822bc
docs: add spelling exception
EscapedGibbon Nov 30, 2023
d5f6ead
docs: remove unused component
EscapedGibbon Nov 30, 2023
340d4e0
docs: add more properties, finalize feret and convexHull
EscapedGibbon Dec 1, 2023
b5ed8dd
docs: add mbr implementation explanation
EscapedGibbon Dec 1, 2023
9872adf
docs: finalize roi section
EscapedGibbon Dec 1, 2023
f542c42
docs: add tables for feret,mbr,convex
EscapedGibbon Dec 1, 2023
b6f0537
docs: add images to showcase properties
EscapedGibbon Dec 1, 2023
fb9b05f
docs: improve documentation of return types for convex,feret and mbr
EscapedGibbon Dec 4, 2023
ebf98bd
docs: improve precision and clarity of roi properties
EscapedGibbon Dec 6, 2023
1a9cb3b
docs: add github.io links
EscapedGibbon Dec 6, 2023
29dd5fc
docs: resolve faulty link
EscapedGibbon Dec 6, 2023
42646e8
docs: fix links in analysis front page
EscapedGibbon Dec 6, 2023
d250f39
docs: rename analysis section
EscapedGibbon Dec 7, 2023
93b1536
Merge branch 'main' into 35-region-of-interests
stropitek Dec 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/Features/Regions of interest/Centroid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
sidebar_position: 70
---

_Center of mass of the current ROI._

[🔎 ROI options and parameters of `centroid` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#centroid 'github.io link')

In image processing, centroid is the weighted average of all the coordinates that belong to the region of interest.

Centroids can be useful for determining the location of an object within an image as well as for tracking the movement of objects over time.

In ImageJS centroid is a ROI class accessor that returns a point:

```ts
const centroid = roi.centroid;
```
50 changes: 50 additions & 0 deletions docs/Features/Regions of interest/Convex Hull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
sidebar_position: 0
---

_Smallest convex polygon or polyhedron that contains region of interest._

[🎭 Mask options and parameters `getConvexHull` method](https://image-js.github.io/image-js-typescript/classes/Mask.html#getConvexHull 'github.io link')
[🔎 ROI options and parameters of `convexHull` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#convexHull 'github.io link')

[Convex Hull](https://en.wikipedia.org/wiki/Convex_hull 'wikipedia link on convex hull') is a way of characterizing the shape of an image by determining which pixels are adjacent to other pixels of the same intensity. This is a good way to find convex features in an image.

![Image input](./img/convexHull.svg)

:::tip
To understand what convex hull is, picture a rubber band wrapped around your object. The shape of this rubber band will be the shape of your convex hull.
:::

In ImageJS convex hull is a ROI class accessor that returns a `ConvexHull` object.

| Property name | Description | Property type |
| -------------------------------------------------------------------------------------------------- | ---------------------------- | ------------- |
| [`points`](https://image-js.github.io/image-js-typescript/interfaces/ConvexHull.html#points) | points that form convex hull | `Point[]` |
| [`surface`](https://image-js.github.io/image-js-typescript/interfaces/ConvexHull.html#surface) | convex hull's surface | `number` |
| [`perimeter`](https://image-js.github.io/image-js-typescript/interfaces/ConvexHull.html#perimeter) | convex hull's perimeter | `number` |

```ts
const convexHull = roi.convexHull;
```

It can also be a Mask method to calculate its convex hull:

```ts
const convexHull = mask.getConvexHull();
```

<details><summary><b>Implementation</b></summary>

Here's how convex hull algorithm is implemented in ImageJS:

_Calculate border points_: ImageJS uses an algorithm to identify points that constitute regions' borders.

_Sorting points lexicographically_: After finding border points, they get sorted in ascending order.

_Build the lower hull_: Traverse the sorted list of points to build the lower hull of the convex hull. Use a stack to keep track of the points in the lower hull. For each point, check whether it forms a left or right turn with the previous two points in the stack. If it forms a right turn, pop the last point from the stack until a left turn is formed. Then push the current point onto the stack.

_Build the upper hull_: Traverse the sorted list of points in reverse order to build the upper hull of the convex hull. Use the same stack as before. Again, ensure that the points in the stack form a convex hull.

_Combine the lower and upper hulls_: The combined result of the lower and upper hulls is the convex hull of the entire set of points.

</details>
24 changes: 24 additions & 0 deletions docs/Features/Regions of interest/EQPC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
sidebar_position: 60
---

_Diameter of a circle that has the same area as the projection area of the region of interest._

[🔎 ROI options and parameters of `eqpc` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#eqpc 'github.io link')

EQPC represents a circle of equal projection area. This means that it is a diameter of a circle that has the same area as an object of interest.
It is widely used for the evaluation of particles sizes from the projection area A of a non-spherical particle.

![roi image](./img/roi.svg)

The formula finds diameter from potential circle's surface:

$$
EQPC = 2\sqrt{\frac{Surface}{\pi}}
$$

In ImageJS EQPC is a ROI class accessor that returns a diameter length in pixels:

```ts
const eqpcResult = roi.eqpc;
```
62 changes: 62 additions & 0 deletions docs/Features/Regions of interest/Feret Diameters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
sidebar_position: 10
---

_The longest and shortest distances between two parallel lines that touch a region of interest._

[🎭 Mask options and parameters of `getFeret` method](https://image-js.github.io/image-js-typescript/classes/Mask.html#getFeret 'github.io link')
[🔎 ROI options and parameters of `feret` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#feret 'github.io link')

[Feret diameters](https://en.wikipedia.org/wiki/Feret_diameter 'wikipedia link on feret diameter') are determined by measuring the minimum and the maximum distances between two parallel tangents that touch the boundary of the region of interest.
This measurement is commonly employed for the analysis of shapes and structures in images.

:::tip
Feret diameters can be defined by the points as if the object was measured by [caliper](https://en.wikipedia.org/wiki/Calipers 'wikipedia link on caliper'). Therefore its other name, caliper diameter.
:::

![Feret output](./img/feret.svg)

In ImageJS Feret diameters are a ROI class accessor that return a Feret object:

| Property name | Description | Property type |
| ------------------------------------------------------------------------------------------------- | ------------------------------ | --------------- |
| [`minDiameter`](https://image-js.github.io/image-js-typescript/interfaces/Feret.html#minDiameter) | minimum diameter | `FeretDiameter` |
| [`maxDiameter`](https://image-js.github.io/image-js-typescript/interfaces/Feret.html#maxDiameter) | maximum diameter | `FeretDiameter` |
| [`aspectRatio`](https://image-js.github.io/image-js-typescript/interfaces/Feret.html#aspectRatio) | ratio between diameter lengths | `number` |

```ts
const feret = roi.feret;
```

It can also be a Mask method to calculate its feret's diameters:

```ts
const feret = mask.getFeret();
```

:::info
Each diameter in itself is also an object which has its own properties:

| Property name | Description | Property type |
| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------- |
| [`angle`](https://image-js.github.io/image-js-typescript/interfaces/FeretDiameter.html#angle) | Angle between the diameter and a horizontal line in degrees. | `number` |
| [`calliperLines`](https://image-js.github.io/image-js-typescript/interfaces/FeretDiameter.html#calliperLines) | Calliper lines that pass by endpoints of Feret diameters. | `[[Point, Point], [Point, Point]]` |
| [`length`](https://image-js.github.io/image-js-typescript/interfaces/FeretDiameter.html#length) | length of the diameter | `number` |
| [`points`](https://image-js.github.io/image-js-typescript/interfaces/FeretDiameter.html#points) | start and end points of the diameter | `[Point, Point]` |

:::

<details><summary><b>Implementation</b></summary>

Here's how Feret diameter is implemented in ImageJS:

_Finding convex hull points_: an algorithm is based on the fact that one of the lines is aligned with one of the convex hull sides. This significantly facilitates Feret's diameter's search. Here, a preexisting convex hull method is implemented.(see [convex hull page](./Convex%20Hull.md 'internal link on convex hull') for more information).

_Rotating an object_: an object gets rotated parallel to the X-axis. It allows finding tilt angles of the diameters. It also simplifies search for points. After all the data is found, it just gets rotated back by the same angle to get actual result.

_Calculating maximum distance between points_: the algorithm iterates through each point and looks for the biggest distance between other points of convex hull. For the minimum diameter it also compares it with the previous maximum value and if it is smaller, it becomes new current minimum diameter.
For maximum diameter it just calculates the maximum distance between points of convex hull.

_Finding caliper lines_: First, region's extreme values are found among rotated points. For minimum these are X values, for maximum - Y values. After that, lines can be found rather easily. For minimum caliper lines lines have a common Y coordinate with feret points and they are situated at the extremities of an object, which is also easy to obtain, since the object is rotated. Same process for maximum diameter, but this time, it's an X coordinate which is common.

</details>
23 changes: 23 additions & 0 deletions docs/Features/Regions of interest/Fill ratio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
sidebar_position: 80
---

[🔎 ROI options and parameters of `fillRatio` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#fillRatio 'github.io link')

_Ratio of the actual filled space to the total available space._

Fill ratio represents the ratio of how much of region's surface is filled with holes. Basically it helps understanding the actual ROI shape and how it is affected by holes in it. For example, if an object does not have holes or cavities in it the fill ratio will be equal to 1.

The ratio is calculated in a simple manner:

$$
fill Ratio = \frac{Surface}{Surface + HolesInfo.surface}
$$

Where $$HolesInfo.surface$$ is the surface property of the method that specifically calculates the information about ROI's holes.

In ImageJS fill ratio is a ROI class accessor that returns a ratio:

```ts
const fillRatio = roi.fillRatio;
```
48 changes: 48 additions & 0 deletions docs/Features/Regions of interest/MBR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
sidebar_position: 20
---

_Smallest rectangle that fully encloses a region of interest, providing a bounding box with minimal area._

[🎭 Mask options and parameters of `getMbr` method](https://image-js.github.io/image-js-typescript/classes/Mask.html#getMbr 'github.io link')
[🔎 ROI options and parameters of `mbr` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#mbr 'github.io link')

Minimum Bounding Rectangle(MBR) is the smallest rectangle which can fit the region of interest in question.

![MBR output](./img/mbr.svg)

MBR is relevant for such things as extracting features, detecting collisions or simply localizing objects.

In ImageJS minimum bounding rectangle is a ROI class accessor that returns a `Mbr` object.

| Property name | Description | Property type |
| ----------------------------------------------------------------------------------------------- | ------------------------------------ | ------------- |
| [`points`](https://image-js.github.io/image-js-typescript/interfaces/Mbr.html#points) | points that form MBR | `Point[]` |
| [`perimeter`](https://image-js.github.io/image-js-typescript/interfaces/Mbr.html#perimeter) | MBR's perimeter | `number` |
| [`surface`](https://image-js.github.io/image-js-typescript/interfaces/Mbr.html#surface) | MBR's surface | `number` |
| [`height`](https://image-js.github.io/image-js-typescript/interfaces/Mbr.html#height) | MBR's height | `number` |
| [`width`](https://image-js.github.io/image-js-typescript/interfaces/Mbr.html#width) | MBR's width | `number` |
| [`angle`](https://image-js.github.io/image-js-typescript/interfaces/Mbr.html#angle) | MBR's angle | `number` |
| [`aspectRatio`](https://image-js.github.io/image-js-typescript/interfaces/Mbr.html#aspectRatio) | ratio between MBR's width and height | `number` |

```ts
const mbr = roi.mbr;
```

It can also be a Mask method to calculate its mbr:

```ts
const mbr = mask.getMbr();
```

<details><summary><b>Implementation</b></summary>

Here's how Minimum Bounding Rectangle is calculated in ImageJS:

_Finding convex hull_:an algorithm is based on the fact that one of the MBR sides is aligned with one of the convex hull sides.

_Rotating an object_: an object gets rotated parallel to the X-axis. It allows finding tilt angles of the diameters. It also facilitates calculation of the points. After all the data is found, it just gets rotated back by the same angle to get actual result.

_Finding extremities_: since the object is rotated, it means that vertical lines will be perpendicular to the hull side in question. Therefore, for each side, algorithm finds extremities which in turn calculate into points, width and surface.

</details>
24 changes: 24 additions & 0 deletions docs/Features/Regions of interest/PED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
sidebar_position: 50
---

_Diameter of a circle that has the same perimeter as the region of interest._

[🔎 ROI options and parameters of `ped` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#ped 'github.io link')

PED represents a diameter of a circle that has the same perimeter as the particle image.
Similarly to [EQPC](./EQPC.md 'internal link on eqpc') it is used to evaluate ROI's sizes albeit from its perimeter and not surface.

![roi image](./img/roi.svg)

The formula is simple:

$$
PED = \frac{Perimeter}{\pi};
$$

In ImageJS PED is a ROI class accessor that returns a diameter in pixels:

```ts
const pedResult = roi.ped;
```
31 changes: 31 additions & 0 deletions docs/Features/Regions of interest/Perimeter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
sidebar_position: 40
---

_Total length of the object's outer borders._

[🔎 ROI options and parameters of `perimeter` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#perimeter 'github.io link')

Although perimeter might seem like a straight-forward sum of border pixels this is not the case.
In ImageJS each pixel's perimeter gets calculated depending on the number of sides that the pixel is exposed to externally.

This means:

We count all the pixel sides that are outside the ROI (each side counts as 1).
If a pixel has 1 external side, this pixel's perimeter is equal to **1**.

If a pixel has 2 external sides, we remove from the sum **(2 - √2) = ~0.59**.
Thus this **pixel's perimeter is equal to 2 - 0.59 = ~1.41**.

If a pixel has 3 external sides, we remove from the sum **2 \* (2 - √2) = ~1.17**.
So this **pixel's perimeter is equal to 3 - 1.17 = ~1.83**.

![Image](./img/download.svg)

It is a basic tool that provides insight to region's size and length.

In ImageJS Perimeter is a ROI accessor that returns a perimeter in pixels:

```ts
const perimeter = roi.perimeter;
```
17 changes: 17 additions & 0 deletions docs/Features/Regions of interest/Regions of interest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
This section is dedicated to analysis of mask and its specific regions. ImageJS is first and foremost an analyzer of particles and analysis of regions of interest. Therefore there are tools that help detecting particles as well as determining their size, shape position and direction.

### Methods

| Can be applied on | ROIs | Masks |
| ----------------------------------------------------------------------------------- | ------- | -------- |
| [Convex Hull(`convexHull`)](./Convex%20Hull.md 'internal link on convex hull') | &#9989; | &#9989; |
| [Feret diameter(`feret`)](./Feret%20Diameters.md 'internal link on feret diameter') | &#9989; | &#9989; |
| [Minimum Bounding Rectangle( `mbr` )](./MBR.md 'internal link on mbr') | &#9989; | &#9989; |
| [Perimeter(`perimeter`)](./Perimeter.md 'internal link on perimeter') | &#9989; | &#10060; |
| [EQPC(`eqpc`)](./EQPC.md 'internal link on eqpc') | &#9989; | &#10060; |
| [PED(`ped`)](./PED.md 'internal link on ped') | &#9989; | &#10060; |
| [Centroid(`centroid`)](./Centroid.md 'internal link on centroid') | &#9989; | &#10060; |
| [Fill ratio(`fillRatio`)](./Fill%20ratio.md 'internal link on fill ratio') | &#9989; | &#10060; |
| [Solidity(`solidity`)](./Solidity.md 'internal link on solidity') | &#9989; | &#10060; |
| [Roundness(`roundness`)](./Roundness.md 'internal link on roundness') | &#9989; | &#10060; |
| [Sphericity(`sphericity`)](./Sphericity.md 'internal link on sphericity') | &#9989; | &#10060; |
23 changes: 23 additions & 0 deletions docs/Features/Regions of interest/Roundness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
sidebar_position: 100
---

_Quantifies the deviation of an object's shape from a perfect circle._

[🔎 ROI options and parameters of `roundness` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#roundness 'github.io link')

Roundness is the measure of how closely the shape of an object approaches that of a mathematically perfect circle.
To compute it the formula is this:

$$
Roundness = \frac{4*Surface}{\pi * FeretDiameter_{Max}^2}
$$

Where $$FeretDiameter_{Max}$$ is the length of a maximum feret diameter.
Using roundness as a metric allows for consistent and objective comparisons between different shapes, facilitating research and analysis across various disciplines.

In ImageJS roundness is a ROI class accessor that returns a ratio:

```ts
const roundness = roi.roundness;
```
25 changes: 25 additions & 0 deletions docs/Features/Regions of interest/Solidity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
sidebar_position: 90
---

_Measure of the compactness of a region or object._

[🔎 ROI options and parameters of `solidity` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#solidity 'github.io link')

The solidity describes the extent to which a shape is convex or concave.
It is calculated through this formula.

$$
Solidity = \frac{Surface}{ConvexHull.surface};
$$

Where $ConvexHull.surface$ is the surface of ROIs convex hull.

It provides insights into the shape irregularity and concavity of the structure.
The solidity of a completely convex shape is 1, the farther it deviates from 1, the greater the extent of concavity in the shape of the ROI.

In ImageJS solidity is a ROI class accessor that returns a solidity index:

```ts
const solidity = roi.solidity;
```
22 changes: 22 additions & 0 deletions docs/Features/Regions of interest/Sphericity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
sidebar_position: 110
---

_Ratio that assesses how closely an object approaches the shape of a perfect sphere._

[🔎 ROI options and parameters of `sphericity` accessor](https://image-js.github.io/image-js-typescript/classes/Roi.html#sphericity 'github.io link')

Sphericity is a measure of the degree to which a particle approximates the shape of a sphere, and is independent of its size. The value is always between 0 and 1. The less spheric the ROI is the smaller is the number.
It is calculated through this formula:

$$
Sphericity =\frac{ 2*\sqrt{Surface*\pi}}{Perimeter};
$$

Sphericity has a similar role as [roundness](./Roundness.md 'internal link to roundness') and can be used as a reference for shape comparison.

In ImageJS sphericity is a ROI class accessor that returns a sphericity index:

```ts
const sphericity = roi.sphericity;
```
Loading