![imea logo](https://git.rwth-aachen.de/ants/sensorlab/imea/raw/main/media/imea.png "imea logo")
[![status](https://joss.theoj.org/papers/b34442455601ccd0b474b814c417a531/status.svg)](https://joss.theoj.org/papers/b34442455601ccd0b474b814c417a531)
[![PyPI license](https://img.shields.io/pypi/l/ansicolortags.svg)](https://pypi.python.org/pypi/imea/)
[![PyPI version shields.io](https://img.shields.io/pypi/v/imea.svg)](https://pypi.python.org/pypi/imea/)
[![Documentation Status](https://readthedocs.org/projects/imea/badge/?version=latest)](https://imea.readthedocs.io/en/latest/?badge=latest)
## Introduction
Quantitative measurement of 2D and 3D shapes based on images are used in many research fields, for example chemistry (Lau et al. 2013), mineral engineering (Andersson et al. 2012), medicine (Nguyen et al. 2005), biology (Smith et al. 1996) or environmental engineering (Kandlbauer et al. 2021; Weissenbach & Sarc 2021). Furthermore, a variety of different shape measurements is proposed in scientific literature (e.g. DIN ISO 9276-6; Pahl et al. 1973a, 1973b, 1973c; Pabst & Gregorova 2007; Steuer 2010).

In contrast, existing Python packages for image analysis like [`scikit-image`](https://www.scikit-image.org/) (Walt et al. 2014) or [`opencv`](https://www.opencv.org/) (Itseez, 2015) cover only a few of the 2D and 3D shape measurements proposed in scientific literature. To utilize different shape measurements researchers often have to combine results of different libaries which means dealing with different coordinate systems, data formats and conventions or implement shape measurements on their own. Both scenarios lead to unnecessary "reinventing the wheel" and can cause significant frustrations and/or potential errors in the results.

[`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) solves this problem: Based on binary images (2D case) or grayscale images where the grayvalue of each pixel represents its height (3D case), 53 different 2D shape measurements and 13 different 3D shape measurements are extracted and returned as an [`pandas`](https://www.pandas.pydata.org/) dataframe (McKinney, 2010). With [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) shape measurements can be extracted with a single line of code:

```python
# 2D case
df_2d = imea.shape_measurements_2d(bw, spatial_resolution_xy)

# 3D case
df_2d, df_3d = imea.shape_measurements_3d(img_3d, threshold_mm, spatial_resolution_xy, spatial_resolution_z)
```
In the background [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) deals with different coordinate systems and conventions to utilize the implementations of existing functions for shape measurements in [`scikit-image`](https://www.scikit-image.org/) and [`opencv`](https://www.opencv.org/). Furthermore, custom implementations based on [`NumPy`](https://www.numpy.org/) and [`SciPy`](https://www.scipy.org/) are integrated in [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) for shape measurements that have not been implemented in those libaries yet.

## Citation
If you use [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea), please cite our [JOSS paper](https://doi.org/10.21105/joss.03091):

```bibtex
@article{Kroell2021,
  doi = {10.21105/joss.03091},
  url = {https://doi.org/10.21105/joss.03091},  
  year = {2021},
  publisher = {The Open Journal},
  volume = {6},
  number = {60},
  pages = {3091},
  author = {Nils Kroell},
  title = {imea: A Python package for extracting 2D and 3D shape measurements from images},
  journal = {Journal of Open Source Software}
}
```

## Documentation

For detailed documentation and the API references of [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) please visit our documentation site:
[**imea.readthedocs.io**](https://imea.readthedocs.io/)

## Installation
We recommend using [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) in an [Anaconda](https://www.anaconda.com/) enviroment.

### Install with pip (recommended)
You can install [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) using the [`pip package manager`](https://pypi.org/project/pip/):

```bash
pip install imea
```
### Install from sources
An other option is to clone the [`imea` repository](https://git.rwth-aachen.de/ants/sensorlab/imea) and install it manually:

```bash
git clone https://git.rwth-aachen.de/ants/sensorlab/imea
cd imea
pip install .
```

### Dependencies
[`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) is tested in Python **3.7+**. To use [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) the following packages are required:

  * [`numpy>=1.18`](https://www.numpy.org/)
  * [`scipy>=1.10`](https://www.scipy.org/)
  * [`scikit-image>=0.16`](https://www.scikit-image.org/)
  * [`opencv-python>=4.5`](https://www.opencv.org/)
  * [`pandas>=1.0.5`](https://www.pandas.pydata.org/)
  * [`matplotlib>=3.2`](https://matplotlib.org/) *(only for visualization in demo notebooks)*
  * [`pytest>=5.4`](https://pytest.org) *(only for running tests)*

Requierements are also listed in [`requirements.txt`](./requirements.txt) (for using [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea)) and [`requirements-dev.txt`](./requirements-dev.txt) (for development and running tests).

### Tests

Unit tests are available in the [tests](./tests) folder. To execute the tests with [`pytest`](https://pytest.org) you can run the following command:

```bash
  python -m pytest tests
```

## Usage
You can use [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) either to extract 2D shape measurements from 2D binary images or to extract 2D as well as 3D shape measurements from grayscale images (heightmaps). Under the folder [**demo**](https://git.rwth-aachen.de/ants/sensorlab/imea/-/tree/main/demo) you can find two Jupyter notebooks that demonstrate the usage of [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea), as well as several [**example images**](https://git.rwth-aachen.de/ants/sensorlab/imea/-/tree/main/demo/example_imgs).

### 2D measurements
For 2D shape measurements insert a binary image `bw` and the spatial resolution in xy-direction (`spatial_resolution_xy`) in [mm/px] into the function `extract_df_2d`:

```python
df_2d = imea.shape_measurements_2d(bw, spatial_resolution_xy)
```

As a result you get a [`pandas`](https://www.pandas.pydata.org/) dataframe, in which each row represents one particle in the binary image and each column an extracted shape measurement.

**Image calibration and spatial resolution:** If your image is not calibrated (i.e. no "square" pixels) you may use [`skimage.transform.rescale`](https://scikit-image.org/docs/dev/api/skimage.transform.html#skimage.transform.rescale) to calibrate your image. If you want your results just in pixels then set `spatial_resolution_xy=1`.

**Optional parameters:** Optional parameters include the rotation stepsize `dalpha` (in degrees) for determinating statistical length and two boolean variables for experts to return the original distribution of statistical lengths (set `return_statistical_lengths=True`) and all chords (set `return_all_chords=True`).

### 3D measurements
For 3D shape measurements insert a 3D grayscale image (`img_3d`), define a threshold (`threshold_mm` in [mm]) and the spatial resolution of one pixel in x/y-direction (`spatial_resolution_xy` in [mm/Pixel]) and z-direction (`spatial_resolution_z` in [mm/Grayvalue]). Pixels with heights lower then `threshold_mm` are treated as background, the other ones are considered as objects. With the following function call you can extract 2D and 3D shape measurements from a 3D grayscale image (`img_3d`):

```python
df_2d, df_3d = imea.shape_measurements_3d(img_3d, threshold_mm, spatial_resolution_xy, spatial_resolution_z)
```

As a result you get two [`pandas`](https://www.pandas.pydata.org/) dataframes `df_2d` and `df_3d`, in which each row represents one particle in the binary image and each column an extracted shape measurement.

**Image calibration and spatial resolution:** You can define the spatial resolution of your image with the parameters `spatial_resolution_xy` and `spatial_resolution_z`. For calibration and spatial resolution the same recommandations as for the 2D case apply (see above).

**Optional parameters:** Optional parameters include the rotation stepsize `dalpha` for determinating shape measurements like the feret diameter, the minimum number of pixels per object to be considered (`min_object_area`) and the maximum number of objects `n_objects_max` you want to extract from `img_3d`. Set `n_objects_max=-1` if you want to extract all objects, for `n_objects_max > 0` the `n_objects_max` largest objects (determinated by area) are extracted.

## License
[`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) is published under the [MIT](https://en.wikipedia.org/wiki/MIT_License)-License.

## Contribution
If you want to contribute to [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea), feel free to contact Nils Kroell via [nils.kroell@ants.rwth-aachen.de](mailto:nils.kroell@ants.rwth-aachen.de). Moreover, you can do so by reporting bugs and/or suggesting new shape measurements.

### Reporting bugs
If you encounter any issues or inconsistent results using [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea): Please report them via our [issue tracker](https://git.rwth-aachen.de/ants/sensorlab/imea/-/issues), so we can work on them. Please give details on the used version of Python and other dependencies as well as provide exemplary data together with the output of [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) and your expected output, so we can reproduce your error.

### Suggesting new shape measurements
If you miss any 2D or 3D shape measurement feel free to open an issue providing the following details:

 * Scientific paper, where the shape measurement is introduced and defined,
 * evidence why this shape measurement is of scientific relevance (cite at least three scientific papers where the shape measurement is used),
 * suggestions and/or references for implementation (optional).


## Current available shape measurements
### 2D shape measurements
Currently, 53 twodimensional shape measurements are implemented in [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea), as shown in the tables below. According to DIN ISO 9276-6 these are structured in macro-, meso- and microdescriptors as well as statistical lengths, as illustrated below.

![macro-, meso- and micromeasurements](https://git.rwth-aachen.de/ants/sensorlab/imea/raw/main/media/macro_meso_micro_measurements.png "macro-, meso- and micromeasurements")

#### Macro measurements (`imea.measure_2d.macro`)
Macrodescriptors represent the overall, external shape of a particle. The following macrodescriptors are currently available in [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea):
| Naming   in imea | Description | Implementation | Reference |
|-|-|-|-|
| `perimeter` | Perimeter. | `skimage.measure.regionprops` | (DIN ISO 9276-6) |
| `convex_perimeter` | Perimeter of the convex hull. | custom based on `skimage.measure.regionprops` | (DIN ISO 9276-6) |
| `area_projection` | Projection area. | `skimage.measure.regionprops` | (DIN ISO 9276-6) |
| `area_filled` | Filled projection area. | `skimage.measure.regionprops` | (DIN ISO 9276-6) |
| `area_convex` | Area of the convex hull. | `skimage.measure.regionprops` | (DIN ISO 9276-6) |
| `major_axis_length` | Major axis length of the   legendre ellipse of inertia (ellipse that has the same normalized second   central moments as the particle shape). | `skimage.measure.regionprops` | (DIN ISO 9276-6) |
| `minor_axis_length` | Minor axis length of the   legendre ellipse of inertia. | `skimage.measure.regionprops` | (DIN ISO 9276-6) |
| `diameter_max_inclosing_circle` | Diameter of the maximum   incircle<br>     of the projection area. | based on `cv2.distanceTransform` | (Pahl et al. 1973a) |
| `diameter_min_enclosing_circle` | Diameter of the minimum   circumference<br>     of the projection area. | `cv2.minEnclosingCircle` | (Pahl et al. 1973a) |
| `diameter_circumscribing_circle` | Diameter of the circumcircle   with<br>     same center as the<br>     particle contour and maximum<br>     area, which touches the particle contour<br>     from the inside. | custom based on `spatial.distance.cdist` | (Li et al. 2020) |
| `diameter_inscribing_circle` | Diameter of the circumcircle   with<br>     same center as the<br>     particle contour and minimum<br>     area, which touches the particle contour<br>     from the outside. | custom based on `spatial.distance.cdist` | (Li et al. 2020) |
| `diameter_equal_area` | Diameter of a circle of   equal<br>     projection area. | custom based on DIN ISO 9276-6 | (DIN ISO 9276-6) |
| `diameter_equal_perimeter` | Diameter of a circle of   equal<br>     perimeter. | custom based on DIN ISO 9276-6 | (DIN ISO 9276-6) |
| `x_max` | Maximum<br>     longest chord. | custom | (Steuer 2010) |
| `y_max` | Longest chord orthogonal to   `y_max` | custom | (Steuer 2010) |
| `width_min_bb` | Width of minimal 2D bounding   box. | `cv2.minAreaRect` | (Steuer 2010) |
| `length_min_bb` | Length of minimal 2D bounding   box (`width_min_bb <= length_min_bb`). | `cv2.minAreaRect` | (Steuer 2010) |
| `geodeticlength` | Geodetic length. | custom based on DIN ISO 9276-6 | (DIN ISO 9276-6; Pons et al. 1999) |
| `thickness` | Thickness. | custom based on DIN ISO 9276-6 | (DIN ISO 9276-6; Pons et al. 1999) |

#### Meso measurements (`imea.measure_2d.meso`)
Mesodescriptors describe details in the particle shape and/or surface structure whose magnitude are not much smaller than the particle proportions. The following mesodescriptors are currently available in [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea):
| Naming   in imea | Description | Implementation | Reference |
|-|-|-|-|
| `n_erosions` | Number of pixel erosions   to<br>     completely erase the silhouette of a particle in the binary image. | custom based on `skimage.morphology.binary_erosion` | (DIN ISO 9276-6) |
| `n_erosions_complement` | Number of pixel erosions to   completely<br>     erase the complement between convex hull and object. | custom based on `skimage.morphology.binary_erosion` | (DIN ISO 9276-6) |

#### Micro measurements (`imea.measure_2d.micro`)
Microdescriptors describe the roughness of particle contours. The following microdescriptors are currently available in [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea):
| Naming   in imea | Description | Implementation | Reference |
|-|-|-|-|
| `fractal_dimension_boxcounting_method` | Fractal dimension determined by the box counting method | custom based on (So et al. 2017) | (So et al. 2017) |
| `fractal_dimension_perimeter_method` | Fractal dimension determined by   the perimeter method according to DIN ISO 9276-6 (evenly structured gait). | custom based on DIN ISO 9276-6 | (DIN ISO 9276-6) |

#### Statistical lengths (`imea.measure_2d.statistical_length`)
Statistical lengths are macrodescriptors that are evaluated at different rotation angles of the shape. Based on the resulting distribution of statistical length different metrics like the minimum or maximum value can be obtained. The following statistical length are currently available in [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea):
| Naming   in imea | Description | Implementation | Reference |
|-|-|-|-|
| `feret_max` | Maximum Feret diameter. | custom | (Pahl et al. 1973a) |
| `feret_min` | Minimum Feret diameter. | custom | (Pahl et al. 1973a) |
| `feret_median` | Median of all Feret diameters. | custom | (Pahl et al. 1973a) |
| `feret_mean` | Arithmetic mean of all Feret   diameters. | custom | (Pahl et al. 1973a) |
| `feret_mode` | Mode of all Feret diameters. | custom | (Pahl et al. 1973a) |
| `feret_std` | Standard deviation of all Feret   diameters. | custom | (Pahl et al. 1973a) |
| `martin_max` | Maximum Martin diameter. | custom | (Pahl et al. 1973a) |
| `martin_min` | Minimum Martin diameter. | custom | (Pahl et al. 1973a) |
| `martin_median` | Median of all Martin diameters. | custom | (Pahl et al. 1973a) |
| `martin_mean` | Arithmetic mean of all Martin   diameters. | custom | (Pahl et al. 1973a) |
| `martin_mode` | Mode of all Martin diameters. | custom | (Pahl et al. 1973a) |
| `martin_std` | Standard deviation of all Martin   diameters. | custom | (Pahl et al. 1973a) |
| `nassenstein_max` | Maximum Nassenstein diameter. | custom | (Pahl et al. 1973a) |
| `nassenstein_min` | Minimum Nassenstein diameter. | custom | (Pahl et al. 1973a) |
| `nassenstein_median` | Median of all Nassenstein   diameters. | custom | (Pahl et al. 1973a) |
| `nassenstein_mean` | Arithmetic mean of all   Nassenstein diameters. | custom | (Pahl et al. 1973a) |
| `nassenstein_mode` | Mode of all Nassenstein   diameters. | custom | (Pahl et al. 1973a) |
| `nassenstein_std` | Standard deviation of all   Nassenstein diameters. | custom | (Pahl et al. 1973a) |
| `maxchords_max` | Maximum of max chords (max chord   = max of all chords for one particle rotation). | custom | (Pahl et al. 1973a) |
| `maxchords_min` | Minimum of max chords. | custom | (Pahl et al. 1973a) |
| `maxchords_median` | Median of max chords. | custom | (Pahl et al. 1973a) |
| `maxchords_mean` | Mean of max chords. | custom | (Pahl et al. 1973a) |
| `maxchords_mode` | Mode of max chords. | custom | (Pahl et al. 1973a) |
| `maxchords_std` | Standard deviation of max   chords. | custom | (Pahl et al. 1973a) |
| `allchords_max` | Maximum of all chords for all   rotations. | custom | (Pahl et al. 1973a) |
| `allchords_min` | Minimum of all chords for all   rotations. | custom | (Pahl et al. 1973a) |
| `allchords_median` | Median of all chords for all   rotations. | custom | (Pahl et al. 1973a) |
| `allchords_mean` | Mean of all chords for all   rotations. | custom | (Pahl et al. 1973a) |
| `allchords_mode` | Mode of all chords for all   rotations. | custom | (Pahl et al. 1973a) |
| `allchords_std` | Standard deviation of all chords   for all rotations. | custom | (Pahl et al. 1973a) |

### 3D shape measurements
For 3D recordings, there are 13 threedimensional shape measurements implemented in [`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea), as shown in the table below.

| Naming   in imea | Description | Implementation | Reference |
|-|-|-|-|
| `volume` | Volume. | `np.sum`  | (Pahl et al. 1973a) |
| `volume_convexhull` | Volume of convex hull. | `scipy.spatial.ConvexHull` | - |
| `surface_area` | Surface area (determined by convex hull). | `scipy.spatial.ConvexHull` | (Pahl et al. 1973a) |
| `diameter_volume_equivalent` | Diameter of a volume-equivalent sphere. | custom based on (Stieß 2009) | (Stieß 2009) |
| `diameter_surfacearea_equivalent` | Diameter of a sphere with the same surface area. | custom based on (Stieß 2009) | (Stieß 2009) |
| `width_3d_bb` | Width of minimal 3D bounding box   (equal to minimal 2D bounding box, as minimum 3D bounding box is assumed to   lay on conveyer surface). | `cv2.minAreaRect` | (Steuer 2010) |
| `length_3d_bb` | Length of minimal 3D bounding   box (`width_3d_bb <= length_3d_bb`, ). | `cv2.minAreaRect` | (Steuer 2010) |
| `height_3d_bb` | Height of minimal 3D bounding   box in z-direction. | `np.max`  | (Steuer 2010) |
| `feret_3d_max` | Maximum 3D feret diameter. | custom based on `scipy.spatial.ConvexHull` | (Pahl et al. 1973a) |
| `feret_3d_min` | Minimum 3D feret diameter. | custom based on `scipy.spatial.ConvexHull` | (Pahl et al. 1973a) |
| `x_max_3d` | Maximum particle dimension   (equal to `feret_3d_max`) | custom | (Steuer 2010) |
| `y_max_3d` | Mean particle dimension   (`y_max_3d >= x_max_3d`, `y_max_3d` orthogonal to  `x_max_3d`) | custom | (Steuer 2010) |
| `z_max_3d` | M particle dimension   (`z_max_3d <= y_max_3d`, `z_max_3d` orthogonal to  `y_max_3d` and  `x_max_3d`) | custom | (Steuer 2010) |

## Conventions

### Coordinate system
[`imea`](https://git.rwth-aachen.de/ants/sensorlab/imea) uses right hand cardesian coordinate system, which is also used in [`scikit-image`](https://www.scikit-image.org/) (`o`: origin of coordinate system):

```python
# (row, col, channel)
# 
#      o ----------> y
#     /|
#    / |
#   /  |
# z    |
#      v
#      x
```

## Literature
T. Andersson, M. J. Thurley and J. E. Carlson  (2012). "A machine vision system for estimation of size distributions by weight of limestone particles". In: *Minerals Engineering*, 25(1), pp. 38–46. https://doi.org/10.1016/j.mineng.2011.10.001                                       

Deutsches Institut für Normung e. V. (2012). *DIN ISO 9276-6 - Darstellung der Ergebnisse von Par-tikelgrößenanalysen: Teil 6: Deskriptive und quantitative Darstellung der Form und Morphologie von Partikeln*.

Itseez (2015). Open source computer vision library. https://github.com/opencv/opencv.

L. Kandlbauer, K. Khodier, D. Ninevski, R. Sarc (2021). "Sensor-based Particle Size Determination of Shredded MixedCommercial Waste based on two-dimensional Images". In: *Waste Management*, 120, pp. 794-794. https://doi.org/10.1016/j.wasman.2020.11.003                                 

Y. M. Lau, N. G. Deen and J. A. M. Kuipers (2013). "Development of an image measurement technique for size distribution in dense bubbly flows". In: *Chemical Engineering Science*, 94, pp. 20–29. https://doi.org/10.1016/j.ces.2013.02.043                                       

X. Li, Z. Wen, H. Zhu, Z. Guo and Y. Liu (2020). "An improved algorithm for evaluation of the
minimum circumscribed circle and maximum inscribed circle based on the local minimax
radius". In: *The Review of scientific instruments* 91(3), pp. 035103. DOI: https://doi.org/10.1063/5.0002233                 

W. McKinney (2010). "Data Structures for Statistical Computing in Python". In: Stéfan
54 van der Walt & Jarrod Millman (Eds.): *Proceedings of the 9th Python in Science Conference*. (pp. 56–61). https://doi.org/10.25080/Majora-92bf1922-00a              

T. M. Nguyen and R. M. Rangayyan (2005). "Shape Analysis of Breast Masses in Mammograms via the Fractal Dimension". In: *2005 IEEE Engineering in Medicine and Biology 27th Annual Conference*, Shanghai, pp. 3210-3213. https://doi.org/10.1109/IEMBS.2005.1617159                                      

W. Pabst und E. Gregorova (2007). *Characterization of particles and particle systems*.

M. Pahl, G. Schädel und H. Rumpf (1973a). "Zusammenstellung von Teilchenformbeschreibungs-methoden: 1. Teil". In: *Aufbereitungstechnik*, 14(5), pp. 257–264.

M. Pahl, G. Schädel und H. Rumpf (1973b). "Zusammenstellung von Teilchenformbeschreibungs-methoden: 2. Teil". In: *Aufbereitungstechnik*, 14(10), pp. 672–683.

M. Pahl, G. Schädel und H. Rumpf (1973c). "Zusammenstellung von Teilchenformbeschreibungs-methoden: 3. Teil". In: *Aufbereitungstechnik*, 14(11) , pp. 759–764.

T. G. Smith, G. D. Lange and W. B. Marks (1996). "Fractal methods and results in cellular morphology — dimensions, lacunarity and multifractals". In: *Journal of Neuroscience Methods*, 69(2), pp. 123–136. https://doi.org/10.1016/s0165-0270(96)00080-5                                          
  
M. Steuer (2010). "Serial classification". In: *AT Mineral Processing* 51(1).

M. Stieß (2009). *Mechanische Verfahrenstechnik - Partikeltechnologie 1*. 3rd edition. Springer-Verlag: Berlin, Heidelberg. http://doi.org/10.1007/978/3-540-32552-9        

G.-B. So, H.-R. So, G.-G. Jin (2017): "Enhancement of the Box-Counting Algorithm for fractal dimension estimation". In: *Pattern Recognition Letters*, 98, pp. 53-58. https://doi.org/10.1016/j.patrec.2017.08.022                 
   
S. Walt, J. Schönberger, J. Nunez-Iglesias, F. Boulogne, J. Warner, N. Yager, E. Gouillart, T. Yu and the scikit-image contributors (2014). "scikit-image: Image processing in Python". In: *PeerJ* 2:e453  https://doi.org/10.7717/peerj.453                                     

T. Weissenbach, R. Sarc (2021). "Investigation of particle-specific characteristics of non-hazardous, fine shredded mixed waste". In: *Waste Management*, 119, pp. 162-171. https://doi.org/10.1016/j.wasman.2020.09.033                                 
