Skip to content

Commit 4471353

Browse files
docs: implement feedback to getting started and basic section (#99)
1 parent 34eec4c commit 4471353

File tree

8 files changed

+53
-74
lines changed

8 files changed

+53
-74
lines changed

docs/Basics/Working with Images.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import ImageDemo from './image.demo.tsx'
66

77
In the context of digital technology and computing, images are represented as a grid of pixels, with each pixel containing information about color and intensity.
88

9+
<ImageDemo />
10+
911
### Types of images supported by ImagesJS
1012

1113
- Currently ImageJS supports images with these characteristics:
@@ -43,15 +45,17 @@ In ImageJS main properties of an image are:
4345

4446
- data: typed array with information about image's pixels.
4547

46-
- [Color model](../Glossary.md#color-model 'internal link on glossary'): the abstract model of how pixel colors are formed.
48+
- [Color model](../Glossary.md#color-model 'internal link on color model'): the abstract model of how pixel colors are formed.
4749

48-
- [Bit depth](../Glossary.md#bit-depth 'internal link on glossary'): number of bits allocated to each channel.
50+
- [Bit depth](../Glossary.md#bit-depth 'internal link on bit depth'): number of bits allocated to each channel.
4951

50-
- [Number of channels/components](../Glossary.md#channel 'internal link on glossary'): number of color channels that each pixel has. Grey image has one, RGB-type of image has three.
52+
- [Number of channels](../Glossary.md#channel 'internal link on channels'): number of color channels that each pixel has. Grey image has one, RGB-type of image has three.
5153

52-
- [Metadata](../Glossary.md#metadata 'internal link on metadata'): data about data.
54+
- [Number of components](../Glossary.md#component 'internal link on components'): number of color channels that each pixel has but without alpha channel.
5355

54-
The latter ones matter most in features that involve two images, like [hypotenuse method](../Features/Comparison/Hypotenuse.md 'internal link on hypotenuse') or [subtraction method](../Features/Comparison/Subtraction.md 'internal link on subtraction method'). It simply will not work if images are not compatible by bit depth, color model or size.
56+
- [Alpha channel](../Glossary.md#alpha-channel 'internal link on alpha-channel'): channel that represents the transparency or opacity levels of pixels.
57+
58+
- [Metadata](../Glossary.md#metadata 'internal link on metadata'): data about data. A basic example would be date and time when an image was taken
5559

5660
### Features
5761

@@ -65,4 +69,4 @@ Currently, there are several ways of processing an image:
6569

6670
- [Morphology](../Features/Morphology/Morphology.md 'internal link on morphology'): enables shape analysis and shape identification.
6771

68-
<ImageDemo />
72+
- [ROI analysis](../Features/Regions%20of%20interest/Regions%20of%20interest.md 'internal link on roi analysis'): these features allow targeting and extracting relevant information from specific regions of interest.

docs/Basics/Working with Masks.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const mask = new Mask(500, 500); // Creates a simple mask filled with 0s of size
2424
Another approach is to obtain a mask by using [`threshold` method](../Features/Operations/Threshold.md 'internal link on threshold') on an image.
2525

2626
```ts
27-
image = image.threshold(); // returns a mask
27+
const mask = image.threshold(); // returns a mask
2828
```
2929

3030
In most cases, thresholding is your go-to method to get a mask from an image.
@@ -40,7 +40,7 @@ In most cases, thresholding is your go-to method to get a mask from an image.
4040
There is also a third way to get a mask. It is to use [`cannyEdgeDetector` method](../Features/Morphology/Canny%20Edge%20Detector.md).
4141

4242
```ts
43-
image = image.cannyEdgeDetector(); // returns a mask
43+
const mask = image.cannyEdgeDetector(); // returns a mask
4444
```
4545

4646
<CannyMaskDemo />

docs/Basics/Working with ROIs.md

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { fromMask } from 'image-js';
1515
const rois = fromMask(mask).getRois();
1616
```
1717

18-
In general you don't need to worry about the intermediate object returned by `fromMask()`. You will mostly be working with the list of ROIs returned by `getRois()`. It contains all the useful properties which characterize the regions of interest, such as surface, perimeter, centroid etc.
18+
In general you don't need to worry about the intermediate object returned by `fromMask()`. You will mostly be working with the list of ROIs returned by `getRois()`. It contains all the properties which characterize the region of interest, such as surface, perimeter, fill ratio, etc.
1919

2020
:::tip
2121
In the options parameter,`getRois()` has a `kind` option which tells what kind of regions to return.
@@ -28,7 +28,8 @@ In the options parameter,`getRois()` has a `kind` option which tells what kind o
2828

2929
:::
3030
Let's take a look at a real life example.
31-
Here you have an image of particles under electron microscopy magnified where 1px = 0.2727 nm. Let's say we want to get the data about all the regions presented on the image and calculate their Feret diameters.
31+
Here you have an image of particles under electron microscopy magnified at 1px = 0.2727 nm. Let's say we want to sort the data by size and observe its distribution.
32+
It can be use in various fields, whether it is for quality control to see if all products have the same features and characteristics or for physical properties of material such as surface area and reactivity.
3233

3334
![input image](./roiImages/inputImage.png)
3435

@@ -37,27 +38,41 @@ It can be done with with following code:
3738
```ts
3839
import { Image, fromMask } from 'image-js';
3940

40-
//Convert image to grayscale, then apply a blur on it. This will smooth out the noise and avoid creating many small ROIs in the next steps(image 1).
41+
//Convert image to grayscale, then apply a blur on it. This will
42+
// smooth out the noise and avoid creating many small ROIs in the next steps(image 1).
4143
const image = sourceImage.grey().blur({ width: 5, height: 5 });
42-
//Use threshold to convert the grayscale image to a Mask. The default threshold algorithm is Otsu which will automatically determine the threshold between black and white pixels by minimizing intra-class intensity variance(image 2).
43-
const mask = image.threshold();
44+
//Clear border excludes border regions from mask if they don't
45+
//fit completely on an image.
46+
const mask = clearBorder(image.threshold(), { color: 'black' });
4447

4548
//Receive all the regions of interest from mask(colored on image 3).
4649
const roiMap = fromMask(mask);
4750
const rois = roiMap.getRois({ kind: 'black' });
4851

49-
for (const roi of rois) {
50-
//Get Feret diameters for each ROI(colored on image 4)
51-
const feret = roi.feret;
52+
//Distribute regions by size(surface).
53+
//First we find limits and intervals for our size classes.
54+
const maxSurface = Math.max(...rois.map((roi) => roi.surface));
55+
const minSurface = Math.min(...rois.map((roi) => roi.surface));
56+
const span = maxSurface - minSurface;
57+
const interval = Math.round(span / Math.sqrt(rois.length));
58+
59+
const bySizeDistribution = new Map();
60+
//We count number of regions that belong to each interval separately.
61+
for (let i = minSurface; i < maxSurface; i += interval) {
62+
const count = rois.filter((roi) => {
63+
return roi.surface >= i && roi.surface < i + interval;
64+
}).length;
65+
const intervalString = i + '-' + (i + interval - 1);
66+
67+
bySizeDistribution.set(intervalString, {
68+
frequency: count,
69+
percentage: ((count / rois.length) * 100).toFixed(2),
70+
});
5271
}
5372
```
5473

55-
Each region of interest possesses many properties and characteristics (ROIs are highlighted in blue on Image 3).
56-
Feret diameter is a rather advanced property, but there are also more general and basic ones, like surface or perimeter.
74+
This will give us a map with stored number of regions per each size interval. This may be a basic example but such analysis is widely used in biology and medicine. It can provide valuable information about predominant cell size or find abnormalities in cells ratio.
5775

58-
![combination of images](./roiImages/comboImage.png)
76+
![Combination of images](./roiImages/comboImage2.png)
5977

60-
If you need a further insight on ROIs level of elongation and shape, however, you can use Feret diameter by calling it with `roi.feret`.
61-
In our current example, they are represented as two green segments(Image 4).
62-
63-
Properties shown here only represent a part of what ImageJS analysis is capable of. To learn more about our analysis tools you can visit Analysis section.
78+
To learn more about our analysis tools you can visit our ROI Analysis section.

docs/Basics/roi.demo.tsx

Lines changed: 0 additions & 15 deletions
This file was deleted.

docs/Basics/roiImages/comboImage2.png

295 KB
Loading

docs/Features/Fill.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

docs/Features/Regions of interest/Regions of interest.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
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.
1+
This section is dedicated to regions' analysis of mask and its specific regions. Regions of Interest (ROI) are areas or regions within an image that are selected for further analysis, processing, or attention due to their relevance to a particular task or objective. ImageJS can be 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.
22

33
### Methods
44

docs/Getting started.md

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,23 @@ Local loading uses `readSync` function with indicated filepath:
3939
```ts
4040
import { readSync } from 'image-js';
4141

42-
let parsedImage = readSync('../example.jpg');
42+
const parsedImage = readSync('../example.jpg');
4343
```
4444

45-
It gets an image
4645
:::tip
4746
Node.js can also load an image via `fetch` function. To get more information take a look at "Browser" part of this section.
4847
:::
4948

50-
Once the image is loaded, it returns an instance of the `Image` class, so its methods can be applied. For example, if you want to apply an [invert filter](/Features/Filters/Invert.md 'internal link on invert filter') you can use the invert method:
49+
Once the image is loaded, it returns an instance of the `Image` class, so its methods can be applied.
5150

5251
```ts
53-
image = image.invert();
52+
const image = parsedImage.invert();
5453
```
5554

5655
To save an image use `writeSync` function:
5756

5857
```ts
59-
writeSync('example.jpg', image);
58+
writeSync('../example.jpg', image);
6059
```
6160

6261
Image format is automatically identified based on the extension typed by the user. In this case it's `'.jpg'`.
@@ -66,9 +65,9 @@ So, in the end you should get a code like this.
6665
```ts
6766
import { readSync, writeSync, Image } from 'image-js';
6867

69-
let image = readSync('../example.jpg');
70-
image = image.invert();
71-
writeSync('example.jpg', image);
68+
const parsedImage = readSync('../example.jpg');
69+
const image = parsedImage.invert();
70+
writeSync('../example.jpg', image);
7271
```
7372

7473
### Loading your first image in browser
@@ -78,23 +77,14 @@ To load an image via browser, in order to instantiate it, you need to get an `ar
7877
```ts
7978
const data = await fetch('https:://example.com/image.jpg');
8079
const bufferedData = await data.arrayBuffer();
81-
const image = decode(new DataView(bufferedData)); // image is ready for usage
80+
let image = decode(new DataView(bufferedData)); // image is ready for usage
8281

8382
image = image.grey();
8483
```
8584

85+
:::info
8686
To see more methods visit ["Features"](./Features/Features.md 'internal link on features') category.
87-
88-
An image can also be loaded from a local host through a local filepath. You can use the `read` function
89-
90-
```ts
91-
import { read } from 'image-js';
92-
93-
const data = async () => {
94-
const data = await read('file:///path/to/file.jpg');
95-
data = image.invert();
96-
};
97-
```
87+
:::
9888

9989
### Bundling your image with Vite
10090

@@ -144,7 +134,6 @@ In the `<body>` part of your code insert your `image-js` script. For instance, h
144134
let image = decode(new DataView(bufferedData)); // image is ready for usage
145135
146136
image = image.grey();
147-
console.log(Image);
148137
const canvas = document.getElementById('my_canvas');
149138
writeCanvas(image, canvas);
150139
</script>

0 commit comments

Comments
 (0)