phenotypic 0.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. phenotypic/__init__.py +38 -0
  2. phenotypic/abstract/__init__.py +27 -0
  3. phenotypic/abstract/_docstring_metaclass.py +22 -0
  4. phenotypic/abstract/_feature_measure.py +43 -0
  5. phenotypic/abstract/_grid_corrector.py +25 -0
  6. phenotypic/abstract/_grid_finder.py +27 -0
  7. phenotypic/abstract/_grid_map_modifier.py +19 -0
  8. phenotypic/abstract/_grid_measure.py +23 -0
  9. phenotypic/abstract/_grid_operation.py +2 -0
  10. phenotypic/abstract/_image_corrector.py +35 -0
  11. phenotypic/abstract/_image_enhancer.py +45 -0
  12. phenotypic/abstract/_image_operation.py +47 -0
  13. phenotypic/abstract/_map_modifier.py +51 -0
  14. phenotypic/abstract/_object_detector.py +49 -0
  15. phenotypic/abstract/_threshold_detector.py +8 -0
  16. phenotypic/core/__init__.py +7 -0
  17. phenotypic/core/_grid_image.py +6 -0
  18. phenotypic/core/_image.py +16 -0
  19. phenotypic/core/_imread.py +16 -0
  20. phenotypic/core/accessors/__init__.py +122 -0
  21. phenotypic/core/accessors/_grid_accessor.py +362 -0
  22. phenotypic/core/accessors/_hsv_accessor.py +224 -0
  23. phenotypic/core/accessors/_image_accessor.py +147 -0
  24. phenotypic/core/accessors/_image_array_accessor.py +324 -0
  25. phenotypic/core/accessors/_image_data_accessor.py +24 -0
  26. phenotypic/core/accessors/_image_enh_matrix_accessor.py +220 -0
  27. phenotypic/core/accessors/_image_matrix_accessor.py +231 -0
  28. phenotypic/core/accessors/_image_objects_accessor.py +114 -0
  29. phenotypic/core/accessors/_measurement_accessor.py +106 -0
  30. phenotypic/core/accessors/_metadata_accessor.py +94 -0
  31. phenotypic/core/accessors/_objmap_accessor.py +140 -0
  32. phenotypic/core/accessors/_objmask_accessor.py +107 -0
  33. phenotypic/core/handlers/__init__.py +5 -0
  34. phenotypic/core/handlers/_image_grid_handler.py +174 -0
  35. phenotypic/core/handlers/_image_handler.py +854 -0
  36. phenotypic/core/handlers/_image_hsv_handler.py +57 -0
  37. phenotypic/core/handlers/_image_io_handler.py +111 -0
  38. phenotypic/correction/__init__.py +5 -0
  39. phenotypic/data/__init__.py +12 -0
  40. phenotypic/data/_sample_image_data.py +47 -0
  41. phenotypic/detection/__init__.py +9 -0
  42. phenotypic/detection/_otsu_detector.py +41 -0
  43. phenotypic/detection/_triangle_detector.py +39 -0
  44. phenotypic/enhancement/__init__.py +37 -0
  45. phenotypic/enhancement/_clahe.py +34 -0
  46. phenotypic/enhancement/_contrast_streching.py +32 -0
  47. phenotypic/enhancement/_gaussian_preprocessor.py +39 -0
  48. phenotypic/enhancement/_laplace_preprocessor.py +33 -0
  49. phenotypic/enhancement/_median_preprocessor.py +31 -0
  50. phenotypic/enhancement/_rank_median_preprocessor.py +42 -0
  51. phenotypic/enhancement/_rolling_ball_preprocessor.py +21 -0
  52. phenotypic/enhancement/_white_tophat_preprocessor.py +39 -0
  53. phenotypic/grid/__init__.py +18 -0
  54. phenotypic/grid/_grid_aligner.py +106 -0
  55. phenotypic/grid/_grid_apply.py +39 -0
  56. phenotypic/grid/_grid_linreg_stats_extractor.py +73 -0
  57. phenotypic/grid/_grid_oversized_object_remover.py +61 -0
  58. phenotypic/grid/_linreg_residual_outlier_modifier.py +116 -0
  59. phenotypic/grid/_min_residual_error_reducer.py +60 -0
  60. phenotypic/grid/_object_spread_extractor.py +32 -0
  61. phenotypic/grid/_optimal_center_grid_finder.py +330 -0
  62. phenotypic/measure/__init__.py +6 -0
  63. phenotypic/measure/_boundary_extractor.py +34 -0
  64. phenotypic/measure/_color_extractor.py +144 -0
  65. phenotypic/measure/_measure_geometry.py +51 -0
  66. phenotypic/measure/_measure_intensity.py +32 -0
  67. phenotypic/morphology/__init__.py +5 -0
  68. phenotypic/morphology/_morphology_filler.py +23 -0
  69. phenotypic/morphology/_morphology_opener.py +14 -0
  70. phenotypic/morphology/_white_tophat_modifier.py +36 -0
  71. phenotypic/objects/__init__.py +11 -0
  72. phenotypic/objects/_border_object_modifier.py +36 -0
  73. phenotypic/objects/_circularity_modifier.py +61 -0
  74. phenotypic/objects/_reduction_by_center_deviation_modifier.py +45 -0
  75. phenotypic/objects/_small_object_modifier.py +14 -0
  76. phenotypic/pipeline/__init__.py +3 -0
  77. phenotypic/pipeline/_image_pipeline.py +139 -0
  78. phenotypic/transform/__init__.py +4 -0
  79. phenotypic/transform/_image_padder.py +37 -0
  80. phenotypic/transform/_image_resizer.py +174 -0
  81. phenotypic/util/__init__.py +9 -0
  82. phenotypic/util/constants_.py +120 -0
  83. phenotypic/util/exceptions_.py +277 -0
  84. phenotypic/util/funcs.py +21 -0
  85. phenotypic/util/labels.py +80 -0
  86. phenotypic-0.6.0.dist-info/METADATA +99 -0
  87. phenotypic-0.6.0.dist-info/RECORD +90 -0
  88. phenotypic-0.6.0.dist-info/WHEEL +5 -0
  89. phenotypic-0.6.0.dist-info/licenses/LICENSE +674 -0
  90. phenotypic-0.6.0.dist-info/top_level.txt +1 -0
phenotypic/__init__.py ADDED
@@ -0,0 +1,38 @@
1
+ __version__ = "0.6.0"
2
+
3
+ from .core._image import Image
4
+ from .core._imread import imread
5
+ from .core._grid_image import GridImage
6
+
7
+ from . import (
8
+ data,
9
+ detection,
10
+ measure,
11
+ grid,
12
+ abstract,
13
+ objects,
14
+ morphology,
15
+ pipeline,
16
+ correction,
17
+ enhancement,
18
+ transform,
19
+ util,
20
+ )
21
+
22
+ __all__ = [
23
+ "Image", # Class imported from core
24
+ "imread", # Function imported from core
25
+ "GridImage", # Class imported from core
26
+ "data",
27
+ "detection",
28
+ "measure",
29
+ "grid",
30
+ "abstract",
31
+ "objects",
32
+ "morphology",
33
+ "pipeline",
34
+ "correction",
35
+ "enhancement",
36
+ "transform",
37
+ "util",
38
+ ]
@@ -0,0 +1,27 @@
1
+ from ._feature_measure import FeatureMeasure
2
+ from ._image_operation import ImageOperation
3
+ from ._image_enhancer import ImageEnhancer
4
+ from ._image_corrector import ImageCorrector
5
+ from ._object_detector import ObjectDetector
6
+ from ._map_modifier import MapModifier
7
+ from ._threshold_detector import ThresholdDetector
8
+ from ._grid_operation import GridOperation
9
+ from ._grid_finder import GridFinder
10
+ from ._grid_corrector import GridCorrector
11
+ from ._grid_map_modifier import GridMapModifier
12
+ from ._grid_measure import GridFeatureMeasure
13
+
14
+ __all__ = [
15
+ "FeatureMeasure",
16
+ "ImageOperation",
17
+ "ImageEnhancer",
18
+ "ImageCorrector",
19
+ "ObjectDetector",
20
+ "MapModifier",
21
+ "ThresholdDetector",
22
+ "GridOperation",
23
+ "GridFinder",
24
+ "GridCorrector",
25
+ "GridMapModifier",
26
+ "GridFeatureMeasure",
27
+ ]
@@ -0,0 +1,22 @@
1
+
2
+ class MeasureDocstringMeta(type):
3
+ """
4
+ Metaclass to automatically set the docstring of measure() to match _operate()
5
+ """
6
+
7
+ def __new__(cls, name, bases, dct):
8
+ # Set the docstring of measure() to match _operate()
9
+ if '_operate' in dct and 'measure' in dct:
10
+ dct['measure'].__doc__ = dct['_operate'].__doc__
11
+ return super().__new__(cls, name, bases, dct)
12
+
13
+ class ApplyDocstringMeta(type):
14
+ """
15
+ Metaclass to automatically set the docstring of apply() to match _operate()
16
+ """
17
+
18
+ def __new__(cls, name, bases, dct):
19
+ # Set the docstring of measure() to match _operate()
20
+ if '_operate' in dct and 'measure' in dct:
21
+ dct['measure'].__doc__ = dct['_operate'].__doc__
22
+ return super().__new__(cls, name, bases, dct)
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING: from phenotypic import Image
5
+
6
+ import numpy as np
7
+ import pandas as pd
8
+
9
+ from ._docstring_metaclass import MeasureDocstringMeta
10
+ from ._image_operation import ImageOperation
11
+ from phenotypic.util.exceptions_ import OperationFailedError, InterfaceError
12
+
13
+
14
+ # <<Interface>>
15
+ class FeatureMeasure:
16
+ """
17
+ A FeatureExtractor is an abstract object intended to calculate measurements on the values within detected objects of
18
+ the image array. The __init__ constructor & _operate method are meant to be the only parts overloaded in inherited classes. This is so
19
+ that the main measure method call can contain all the necessary type validation and output validation checks to streamline development.
20
+ """
21
+
22
+ def measure(self, image: Image) -> pd.DataFrame:
23
+ try:
24
+ imcopy: Image = image.copy()
25
+
26
+ measurement = self._operate(image)
27
+
28
+ # TODO: Fix checks
29
+ # if not np.array_equal(imcopy.matrix[:], image.matrix[:]): raise ValueError(ARRAY_CHANGE_ERROR_MSG)
30
+ # if not np.array_equal(imcopy.enh_matrix[:], image.enh_matrix[:]): raise ValueError(ENHANCED_ARRAY_CHANGE_ERROR_MSG)
31
+ # if not np.array_equal(imcopy.omask[:], image.omask[:]): raise ValueError(MASK_CHANGE_ERROR_MSG)
32
+ # if not np.array_equal(imcopy.omap[:], image.omap[:]): raise ValueError(MAP_CHANGE_ERROR_MSG)
33
+
34
+ return measurement
35
+ except Exception as e:
36
+ raise OperationFailedError(operation=self.__class__.__name__,
37
+ image_name=image.name,
38
+ err_type=type(e),
39
+ message=str(e)
40
+ )
41
+
42
+ def _operate(self, image: Image) -> pd.DataFrame:
43
+ raise InterfaceError
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ import pandas as pd
5
+
6
+ if TYPE_CHECKING: from phenotypic import GridImage
7
+
8
+ from phenotypic.abstract import ImageCorrector
9
+ from phenotypic.abstract import GridOperation
10
+ from phenotypic.util.exceptions_ import GridImageInputError, OutputValueError
11
+
12
+
13
+ class GridCorrector(ImageCorrector, GridOperation):
14
+ def __init__(self, n_rows: int, n_cols: int):
15
+ self.n_rows = n_rows
16
+ self.n_cols = n_cols
17
+
18
+ def apply(self, image: GridImage, inplace=False) -> GridImage:
19
+ from phenotypic import GridImage
20
+
21
+ if not isinstance(image, GridImage): raise GridImageInputError
22
+ output = super().apply(image, inplace=inplace)
23
+ if not isinstance(output, GridImage): raise OutputValueError("GridImage")
24
+ return output
25
+
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING: from phenotypic import Image
5
+
6
+ import pandas as pd
7
+
8
+ from phenotypic.abstract import FeatureMeasure
9
+ from phenotypic.abstract import GridOperation
10
+
11
+
12
+ class GridFinder(FeatureMeasure, GridOperation):
13
+ """
14
+ GridFinder measures grid information from the objects in various ways. Using the names here allow for streamlined integration.
15
+ Unlike other Grid series interfaces, GridExtractors can work on regular images, and should not be dependent on the GridImage class.
16
+
17
+ Parameters:
18
+ nrows (int): Number of rows in the grid.
19
+ ncols (int): Number of columns in the grid.
20
+
21
+ """
22
+ def __init__(self, nrows: int, ncols: int):
23
+ self.nrows = nrows
24
+ self.ncols = ncols
25
+
26
+ def _operate(self, image: Image) -> pd.DataFrame:
27
+ pass
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING: from phenotypic import GridImage
5
+
6
+ from phenotypic.abstract import MapModifier
7
+ from phenotypic.abstract import GridOperation
8
+ from phenotypic.util.exceptions_ import GridImageInputError, InterfaceError
9
+
10
+
11
+ class GridMapModifier(MapModifier, GridOperation):
12
+ def apply(self, image: GridImage, inplace: bool = False) -> GridImage:
13
+ from phenotypic import GridImage
14
+ if not isinstance(image, GridImage): raise GridImageInputError()
15
+ output = super().apply(image=image, inplace=inplace)
16
+ return output
17
+
18
+ def _operate(self, image: GridImage) -> GridImage:
19
+ raise InterfaceError()
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+ if TYPE_CHECKING: from phenotypic import GridImage
4
+
5
+ import pandas as pd
6
+
7
+
8
+ from phenotypic.abstract import FeatureMeasure
9
+ from phenotypic.abstract import GridOperation
10
+ from phenotypic.util.exceptions_ import GridImageInputError, OutputValueError
11
+
12
+
13
+ class GridFeatureMeasure(FeatureMeasure, GridOperation):
14
+ def __init__(self, n_rows: int, n_cols: int):
15
+ self.n_rows = n_rows
16
+ self.n_cols = n_cols
17
+
18
+ def measure(self, image: GridImage) -> pd.DataFrame:
19
+ from phenotypic import GridImage
20
+ if not isinstance(image, GridImage): raise GridImageInputError()
21
+ output = super().measure(image)
22
+ if not isinstance(output, pd.DataFrame): raise OutputValueError("pandas.DataFrame")
23
+ return output
@@ -0,0 +1,2 @@
1
+ class GridOperation:
2
+ pass
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING: from phenotypic import Image
5
+
6
+ from typing import Union, Dict
7
+
8
+ from ._image_operation import ImageOperation
9
+ from phenotypic.util.exceptions_ import InterfaceError, OperationFailedError
10
+
11
+
12
+ class ImageCorrector(ImageOperation):
13
+ """ImageCorrectors are for general operations that alter every image component such as rotating. These have no integrity checks.
14
+
15
+ """
16
+
17
+ def __init__(self):
18
+ pass
19
+
20
+ def apply(self, image: Image, inplace=False) -> Union[Image, Dict[str, Image]]:
21
+ try:
22
+ if inplace:
23
+ output = self._operate(image)
24
+ else:
25
+ output = self._operate(image.copy())
26
+ return output
27
+ except Exception as e:
28
+ raise OperationFailedError(operation=self.__class__.__name__,
29
+ image_name=image.name,
30
+ err_type=type(e),
31
+ message=str(e)
32
+ )
33
+
34
+ def _operate(self, image: Image) -> Image:
35
+ raise InterfaceError
@@ -0,0 +1,45 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING: from phenotypic import Image
5
+
6
+ import numpy as np
7
+ from ._image_operation import ImageOperation
8
+ from phenotypic.util.exceptions_ import InterfaceError, DataIntegrityError, OperationFailedError
9
+ from phenotypic.util.constants_ import IMAGE_FORMATS
10
+
11
+
12
+ class ImageEnhancer(ImageOperation):
13
+ def __init__(self):
14
+ pass
15
+
16
+ def apply(self, image: Image, inplace: bool = False) -> Image:
17
+ try:
18
+ # Make a copy for post checking
19
+ imcopy = image.copy()
20
+
21
+ # Reset the object map in case the inherited class forgets to do so
22
+ image.objmap.reset()
23
+
24
+ if inplace:
25
+ output = self._operate(image)
26
+ else:
27
+ output = self._operate(image.copy())
28
+
29
+ if image._image_format.is_array():
30
+ if not np.array_equal(output.array[:], imcopy.array[:]):
31
+ raise DataIntegrityError(component='array', operation=self.__class__.__name__)
32
+
33
+ if not np.array_equal(output.matrix[:], imcopy.matrix[:]):
34
+ raise DataIntegrityError(component='matrix', operation=self.__class__.__name__)
35
+
36
+ return output
37
+ except Exception as e:
38
+ raise OperationFailedError(operation=self.__class__.__name__,
39
+ image_name=image.name,
40
+ err_type=type(e),
41
+ message=str(e)
42
+ )
43
+
44
+ def _operate(self, image: Image) -> Image:
45
+ raise InterfaceError
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING: from phenotypic import Image
5
+
6
+ from ..util.exceptions_ import InterfaceError
7
+
8
+ class ImageOperation:
9
+ """
10
+ Represents an abstract base class for image operations.
11
+
12
+ This class provides a common abstract for applying transformations or
13
+ operations to images. It defines a method to apply the operation and
14
+ enforces the implementation of the specific operation in a subclass.
15
+ Users can apply operations either in-place or on a copy of the image.
16
+
17
+ """
18
+ def apply(self, image, inplace=False) -> Image:
19
+ """
20
+ Applies a certain operation to an image, either in-place or on a copy.
21
+
22
+ Args:
23
+ image (Image): The input image to apply the operation on.
24
+ inplace (bool): If True, modifies the image in place; otherwise,
25
+ operates on a copy of the image.
26
+
27
+ Returns:
28
+ Image: The modified image after applying the operation.
29
+ """
30
+ if inplace:
31
+ return self._operate(image)
32
+ else:
33
+ return self._operate(image.copy())
34
+
35
+ def _operate(self, image: Image) -> Image:
36
+ """
37
+ A placeholder for the subfunction for an image operator for processing image objects.
38
+
39
+ This method is called from apply and must be implemented in a subclass. This allows for checks for data integrity to be made.
40
+
41
+ Args:
42
+ image (Image): The image object to be processed by internal operations.
43
+
44
+ Raises:
45
+ InterfaceError: Raised if the method is not implemented in a subclass.
46
+ """
47
+ raise InterfaceError
@@ -0,0 +1,51 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING: from phenotypic import Image
5
+
6
+ import numpy as np
7
+
8
+ from ._image_operation import ImageOperation
9
+ from ..util.constants_ import IMAGE_FORMATS
10
+ from phenotypic.util.exceptions_ import OperationFailedError, InterfaceError, DataIntegrityError
11
+
12
+
13
+ # <<Interface>>
14
+ class MapModifier(ImageOperation):
15
+ """Map modifiers edit the object map and are used for removing, combining, and re-ordering objects."""
16
+
17
+ def apply(self, image: Image, inplace: bool = False) -> Image:
18
+ try:
19
+ imcopy = image.copy()
20
+
21
+ if inplace:
22
+ output = self._operate(image)
23
+ else:
24
+ output = self._operate(image.copy())
25
+
26
+ # TODO: Fix this check
27
+ if output._image_format.is_array():
28
+ if not np.array_equal(imcopy.array[:], output.array[:]): raise DataIntegrityError(
29
+ component='array', operation=self.__class__.__name__, image_name=image.name
30
+ )
31
+
32
+ # TODO: Fix this check
33
+ # if not np.array_equal(imcopy.matrix[:], output.matrix[:]): raise DataIntegrityError(
34
+ # component='matrix', operation=self.__class__.__name__, image_name=image.name
35
+ # )
36
+
37
+ if not np.array_equal(imcopy.enh_matrix[:], output.enh_matrix[:]): raise DataIntegrityError(
38
+ component='enh_matrix', operation=self.__class__.__name__, image_name=image.name
39
+ )
40
+ return output
41
+ except DataIntegrityError as e:
42
+ raise e
43
+ except Exception as e:
44
+ raise OperationFailedError(operation=self.__class__.__name__,
45
+ image_name=image.name,
46
+ err_type=type(e),
47
+ message=str(e)
48
+ )
49
+
50
+ def _operate(self, image: Image) -> Image:
51
+ raise InterfaceError
@@ -0,0 +1,49 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+
4
+
5
+ if TYPE_CHECKING: from phenotypic import Image
6
+
7
+ import numpy as np
8
+ from ._image_operation import ImageOperation
9
+ from phenotypic.util.exceptions_ import OperationFailedError, DataIntegrityError, InterfaceError
10
+
11
+
12
+ # <<Interface>>
13
+ class ObjectDetector(ImageOperation):
14
+ """ObjectDetectors are for detecting objects in an image. They change the image object mask and map."""
15
+
16
+ def __init__(self):
17
+ pass
18
+
19
+ def apply(self, image: Image, inplace: bool = False) -> Image:
20
+ try:
21
+ imcopy = image.copy()
22
+
23
+ if inplace:
24
+ output = self._operate(image)
25
+ else:
26
+ output = self._operate(image.copy())
27
+
28
+ # Post Operation Checks
29
+ if not np.array_equal(imcopy.matrix[:], output.matrix[:]): raise DataIntegrityError(component='matrix',
30
+ operation=self.__class__.__name__,
31
+ image_name=image.name
32
+ )
33
+ if not np.array_equal(imcopy.enh_matrix[:], output.enh_matrix[:]): raise DataIntegrityError(component='enh_matrix',
34
+ operation=self.__class__.__name__,
35
+ image_name=image.name
36
+ )
37
+ output.objmap.relabel()
38
+ return output
39
+ except DataIntegrityError as e:
40
+ raise e
41
+ except Exception as e:
42
+ raise OperationFailedError(operation=self.__class__.__name__,
43
+ image_name=image.name,
44
+ err_type=type(e),
45
+ message=str(e)
46
+ )
47
+
48
+ def _operate(self, image: Image) -> Image:
49
+ raise InterfaceError
@@ -0,0 +1,8 @@
1
+ from ._object_detector import ObjectDetector
2
+
3
+
4
+
5
+ # <<Interface>>
6
+ class ThresholdDetector(ObjectDetector):
7
+ """ThresholdDetectors are a type of ObjectDetector that use a threshold, such as Otsu's threshold, to detect objects in an image. They change the image object mask and map."""
8
+ pass
@@ -0,0 +1,7 @@
1
+ from . import accessors, handlers
2
+
3
+ # Define __all__ to include all imported objects
4
+ __all__ = [
5
+ "accessors",
6
+ "handlers"
7
+ ]
@@ -0,0 +1,6 @@
1
+ from .handlers import ImageGridHandler
2
+
3
+ class GridImage(ImageGridHandler):
4
+ pass
5
+
6
+ GridImage.__doc__ = ImageGridHandler.__doc__
@@ -0,0 +1,16 @@
1
+ from .handlers._image_hsv_handler import ImageHsvHandler
2
+
3
+
4
+ class Image(ImageHsvHandler):
5
+ """A comprehensive class for handling image processing, including manipulation, information sync, metadata management, and format conversion.
6
+
7
+ The `Image` class is designed to load, process, and manage image data using different
8
+ representation formats (e.g., arrays and matrices). This class allows for metadata editing,
9
+ schema definition, and subcomponent handling to streamline image processing tasks.
10
+
11
+ Note:
12
+ - If the input_image is 2-D, the ImageHandler leave the array form as None
13
+ - If the input_image is 3-D, the ImageHandler will automatically set the matrix component to the grayscale representation.
14
+ - Added in v0.5.0, HSV handling support
15
+ """
16
+ pass
@@ -0,0 +1,16 @@
1
+ from ._image import Image
2
+ from pathlib import Path
3
+
4
+
5
+ def imread(filepath: str):
6
+ """
7
+ Reads an image from the specified file path using the `Image().imread` method.
8
+
9
+ Args:
10
+ filepath (str): The path to the image file to be read.
11
+
12
+ Returns:
13
+ Image: An `Image` object containing the data read from the specified file.
14
+ """
15
+ filepath = Path(filepath)
16
+ return Image().imread(filepath)
@@ -0,0 +1,122 @@
1
+ """
2
+ Overview
3
+ ========
4
+
5
+ The ``accessors`` submodule provides a comprehensive set of tools and interfaces for accessing and interacting with the various data components of an image. These components range from raw pixel data and matrix representations to object masks, metadata, and high-level measurements. Additionally, it includes utilities that streamline development workflows involving image processing and analysis.
6
+
7
+ The goal is to provide efficient, standardized access to image data while enabling intuitive and flexible integration for advanced image manipulation and analysis tasks.
8
+
9
+ Image Data Containers
10
+ =====================
11
+
12
+ This category includes classes designed to offer fundamental abstractions for accessing image data in various representations:
13
+
14
+ 1. :class:`ImageArray`
15
+ Represents the multichannel pixel data of an image when provided. Useful for direct manipulation and pixel-wise operations.
16
+
17
+ 2. :class:`ImageMatrix`
18
+ Provides structured access to the image in its matrix form, offering methods suited for mathematical or analytical operations on image data. Automatically converted from RGB using weighted luminance conversion.
19
+
20
+ 3. :class:`ImageEnhancedMatrix`
21
+ An enhanceable copy of the image matrix to improve detection while maintaining the original image data integrity.
22
+
23
+ Objects and Object Mapping
24
+ ==========================
25
+
26
+ These classes manage object-level abstractions and their corresponding data mappings:
27
+
28
+ 1. :class:`ObjectMap`
29
+ Represents a mapping of detected objects or regions in the image to their associated IDs. Useful for:
30
+
31
+ - Object identification
32
+ - Bounding box management
33
+ - Spatial relationships between objects.
34
+ - Region-based calculations
35
+
36
+ 2. :class:`ObjectMask`
37
+ An abstract specialized for working with binary masks of objects. Useful for morphological operations such as erosion, dilation, and closing.
38
+
39
+ Note:
40
+ Changes to the object mask will cause relabeling of the object map
41
+
42
+ High-Level Object Interfaces
43
+ ============================
44
+
45
+ These classes provide consolidated access to manage multiple object-level and metadata components.
46
+
47
+ 1. :class:`ObjectsAccessor`
48
+ Facilitates high-level interaction with detected objects within an image. Features include:
49
+
50
+ - Feature extraction
51
+ - Object comparison
52
+ - Visualization of detected objects
53
+
54
+ 2. :class:`MeasurementContainer` *(Coming Soon!)*
55
+ Encapsulates measurements or attributes associated with objects, such as size, shape, or intensity. Organizes measurements for reproducibility and easier analysis.
56
+
57
+ 3. :class:`MetadataContainer` *(Coming Soon!)*
58
+ Responsible for storing and accessing metadata associated with the image. Examples of metadata include:
59
+
60
+ - Acquisition details
61
+ - Resolution
62
+ - Additional contextual information.
63
+
64
+ HSV (Hue, Saturation, Brightness) Interface
65
+ ===========================================
66
+
67
+ 1. :class:`HsvAccessor`
68
+ Provides detailed access to the HSV (Hue, Saturation, Brightness) color space components of an image. This abstract includes support for:
69
+
70
+ - Direct pixel access via ``__getitem__`` and ``__setitem__``.
71
+ - Advanced utilities for image visualization and object-specific manipulation in the HSV domain.
72
+
73
+ **Key Methods:**
74
+ - ``shape``: Returns the dimensions of the HSV representation.
75
+ - ``copy``: Creates and returns a full copy of the HSV data structure.
76
+ - ``histogram``: Computes a histogram for the HSV image or parts of it.
77
+ - ``show``: Displays the HSV image.
78
+ - ``show_objects``: Visualizes objects overlaid on the HSV image.
79
+ - ``extract_obj_hue``, ``extract_obj_saturation``, ``extract_obj_brightness``, ``extract_obj``:
80
+ Extract specific HSV component data for individual image objects, aiding in targeted color-based analysis.
81
+
82
+ Purpose and Use Cases
83
+ =====================
84
+
85
+ The ``accessors`` submodule is designed for developers and researchers working on advanced image processing tasks. It is particularly suited for:
86
+
87
+ - Object detection and feature extraction
88
+ - HSV color-space analysis
89
+ - Grid Analysis
90
+ - Metadata association for image datasets
91
+ - Advanced mathematical and matrix operations on image data.
92
+
93
+ """
94
+ from ._image_accessor import ImageAccessor
95
+ from ._image_data_accessor import ImageDataAccessor
96
+ from ._image_array_accessor import ImageArray
97
+ from ._image_matrix_accessor import ImageMatrix
98
+ from ._image_enh_matrix_accessor import ImageEnhancedMatrix
99
+ from ._objmap_accessor import ObjectMap
100
+ from ._objmask_accessor import ObjectMask
101
+
102
+ from ._image_objects_accessor import ObjectsAccessor
103
+ # from ._measurement_container_interface import MeasurementAccessor
104
+ from ._metadata_accessor import MetadataAccessor
105
+
106
+ from ._hsv_accessor import HsvAccessor
107
+ from ._grid_accessor import GridAccessor
108
+
109
+ # Define __all__ to include all imported objects
110
+ __all__ = [
111
+ "ImageAccessor",
112
+ "ImageDataAccessor",
113
+ "ImageArray",
114
+ "ImageMatrix",
115
+ "ImageEnhancedMatrix",
116
+ "ObjectMap",
117
+ "ObjectMask",
118
+ "ObjectsAccessor",
119
+ "HsvAccessor",
120
+ "GridAccessor",
121
+ "MetadataAccessor",
122
+ ]