Skip to content

Commit 6ebe1cb

Browse files
authored
Merge pull request #10 from agfianf/docs/processor
Docs/processor
2 parents 9a6345e + 589aaac commit 6ebe1cb

File tree

16 files changed

+127
-102
lines changed

16 files changed

+127
-102
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## [v0.0.1-rc2] - 2025-02-10
4+
**Release Candidate with Full Feature Set and Documentation**
5+
This release introduces several improvements:
6+
7+
- Updated documentation to include interactive Google Colab demos and online documentation links.
8+
- Refactored the detection module by renaming the detection file and introducing the new `DetectionProcessor` class for clearer structure.
9+
- Enhanced image processing utilities with improved docstrings and comments for better code readability and maintainability.
10+
311
## [v0.0.1-rc1] - 2025-02-10
412
**Release Candidate with Full Feature Set and Documentation**
513
- Add docs page build with mkdocs-material. Read more [https://agfianf.github.io/color-correction/](https://agfianf.github.io/color-correction/)

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
[![version](https://badge.fury.io/py/color-correction.svg)](https://badge.fury.io/py/color-correction)
1111
[![downloads](https://img.shields.io/pypi/dm/color-correction)](https://pypistats.org/packages/color-correction)
1212
[![python-version](https://img.shields.io/pypi/pyversions/color-correction)](https://badge.fury.io/py/color-correction)
13-
13+
[![Try color-correction using - Google Colab](https://img.shields.io/badge/Try_color--correction_using-Google_Colab-blue?logo=googlecolab)](https://colab.research.google.com/drive/146SXHHihMmGLzaTSwdBXncVr3SU_I-Dm?usp=sharing)
14+
[![read - docs](https://img.shields.io/badge/read-docs-blue?logo=materialformkdocs)](https://agfianf.github.io/color-correction/)
1415

1516
</div>
1617

color_correction/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.0.1-rc1"
1+
__version__ = "0.0.1-rc2"
22

33
# fmt: off
44
from .constant.color_checker import reference_color_d50_bgr as REFERENCE_COLOR_D50_BGR # noqa: N812, I001

color_correction/processor/__init__.py

Whitespace-only changes.
Lines changed: 68 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import cv2
22
import numpy as np
33

4+
from color_correction.schemas.custom_types import BoundingBox, ColorPatchType, ImageBGR
45
from color_correction.schemas.det_yv8 import DetectionResult
56
from color_correction.utils.geometry_processing import (
67
extract_intersecting_patches,
@@ -12,36 +13,34 @@
1213
crop_region_with_margin,
1314
)
1415

15-
# Type aliases for better readability
16-
BoundingBox = tuple[int, int, int, int]
17-
RGB = tuple[float, float, float]
18-
BGR = tuple[float, float, float]
19-
2016

2117
class DetectionProcessor:
2218
"""
23-
A class to process color calibration card detections and extract color patches.
24-
25-
This class handles the detection and processing of color calibration cards and their
26-
individual color patches, including visualization and RGB value extraction.
19+
A class for processing detection results and transforming them using
20+
available utility methods. This class takes the output from an object
21+
detection model (e.g., YOLOv8) and provides functionality to separate,
22+
process, and visualize detected color checker cards and their patches.
2723
"""
2824

2925
@staticmethod
3026
def get_each_class_box(
3127
prediction: DetectionResult,
3228
) -> tuple[list[BoundingBox], list[BoundingBox]]:
3329
"""
34-
Separate detection boxes by class (cards and patches).
30+
Separates detection boxes into card boxes and patch boxes.
3531
3632
Parameters
3733
----------
3834
prediction : DetectionResult
39-
Detection results containing boxes and class IDs
35+
The detection output that includes bounding boxes and class IDs.
4036
4137
Returns
4238
-------
43-
Tuple[List[BoundingBox], List[BoundingBox]]
44-
Two lists containing card boxes and patch boxes respectively
39+
tuple[list[BoundingBox], list[BoundingBox]]
40+
A tuple containing:
41+
42+
- a list of card boxes (class id 1)
43+
- a list of patch boxes (class id 0).
4544
"""
4645
ls_cards = [
4746
box
@@ -66,36 +65,41 @@ def get_each_class_box(
6665
@staticmethod
6766
def print_summary(prediction: DetectionResult) -> None:
6867
"""
69-
Print a summary of detected objects.
68+
Prints a summary of the detected cards and patches.
7069
7170
Parameters
7271
----------
7372
prediction : DetectionResult
74-
Detection results to summarize
73+
The detection result to summarize.
7574
"""
7675
ls_cards, ls_patches = DetectionProcessor.get_each_class_box(prediction)
7776
print(f"Number of cards detected: {len(ls_cards)}")
7877
print(f"Number of patches detected: {len(ls_patches)}")
7978

8079
@staticmethod
8180
def process_patches(
82-
input_image: np.ndarray,
81+
input_image: ImageBGR,
8382
ordered_patches: list[tuple[BoundingBox, tuple[int, int]] | None],
84-
) -> tuple[list[RGB], np.ndarray]:
83+
) -> tuple[list[ColorPatchType], ImageBGR]:
8584
"""
86-
Process detected patches to extract RGB values and create a visualization.
85+
Processes each detected patch by extracting its region from the image,
86+
computing its mean BGR color, and building a visualization grid.
8787
8888
Parameters
8989
----------
90-
input_image : np.ndarray
91-
Input image containing the patches
92-
ordered_patches : List[Optional[BoundingBox]]
93-
List of ordered patch coordinates
90+
input_image : ImageBGR
91+
The original image containing detected patches.
92+
ordered_patches : list[tuple[BoundingBox, tuple[int, int]] | None]
93+
The list of ordered patch coordinates paired with their center
94+
points, possibly with missing entries as None.
9495
9596
Returns
9697
-------
97-
Tuple[List[RGB], np.ndarray]
98-
List of RGB values and visualization image
98+
tuple[list[ColorPatchType], ImageBGR]
99+
a tuple containing:
100+
101+
- list of mean BGR color values for each patch.
102+
- an image visualizing these patches in a grid layout.
99103
"""
100104
patch_size = (50, 50, 1)
101105
ls_bgr_mean_patch = []
@@ -129,31 +133,42 @@ def process_patches(
129133

130134
@staticmethod
131135
def extract_color_patches(
132-
input_image: np.ndarray,
136+
input_image: ImageBGR,
133137
prediction: DetectionResult,
134138
draw_processed_image: bool = False,
135-
) -> tuple[list[BGR], np.ndarray, np.ndarray | None]:
139+
) -> tuple[list[ColorPatchType], ImageBGR, ImageBGR | None]:
136140
"""
137-
Extract and process color patches from the detected calibration card.
141+
Extracts and processes color patches from detected color checker cards,
142+
transforming the detection results with available methods.
143+
144+
The method first separates detected cards and patches, generates an expected
145+
patch grid, and then matches the detected patches with this grid. If patches
146+
are missing, it attempts to auto-fill them with suggested coordinates.
147+
Finally, it computes the mean color for each patch and builds a visualization.
138148
139149
Parameters
140150
----------
141-
input_image : np.ndarray
142-
Input image containing the color calibration card
151+
input_image : ImageBGR
152+
The original image containing the color checker card.
143153
prediction : DetectionResult
144-
Detection results from YOLOv8
154+
The detection result output from the model.
145155
draw_processed_image : bool, optional
146-
Whether to create a visualization image, by default False
156+
If True, returns an additional image with visualized detections.
157+
Otherwise, only patch processing is performed. Defaults to False.
147158
148159
Returns
149160
-------
150-
Tuple[List[BGR], np.ndarray, Optional[np.ndarray]]
151-
BGR values, patch visualization, and optional detection visualization
161+
tuple[list[ColorPatchType], ImageBGR, ImageBGR | None]
162+
a tuple containing:
163+
164+
- a list of mean BGR color values for each patch.
165+
- an image visualizing these patches in a grid layout.
166+
- an optional image with visualized detection results.
152167
153168
Raises
154169
------
155170
ValueError
156-
If no cards or patches are detected
171+
If no cards or patches are detected.
157172
"""
158173
ls_cards, ls_patches = DetectionProcessor.get_each_class_box(prediction)
159174

@@ -206,30 +221,34 @@ def extract_color_patches(
206221

207222
@staticmethod
208223
def draw_preprocess(
209-
image: np.ndarray,
224+
image: ImageBGR,
210225
expected_boxes: list[BoundingBox],
211226
prediction: DetectionResult,
212227
ls_ordered_patch_bbox: list[BoundingBox | None],
213228
suggested_patches: dict[int, BoundingBox] | None = None,
214-
) -> np.ndarray:
229+
) -> ImageBGR:
215230
"""
216-
Draw detection visualizations on the image.
231+
Draws visualizations on the input image to compare the detected patches with
232+
the expected positions. It overlays expected boxes, connects detected patches to
233+
their corresponding expected boxes, and highlights individual patch detections.
217234
218235
Parameters
219236
----------
220-
image : np.ndarray
221-
Input image to draw on
222-
boxes : List[BoundingBox]
223-
List of bounding boxes to draw
224-
patch_indices : Optional[List[int]]
225-
Indices to label the patches
226-
suggested_patches : Optional[Dict[int, BoundingBox]]
227-
Additional suggested patch locations to draw
237+
image : ImageBGR
238+
The original image to draw on.
239+
expected_boxes : list[BoundingBox]
240+
List of expected bounding boxes for patches.
241+
prediction : DetectionResult
242+
The detection results containing predicted bounding boxes.
243+
ls_ordered_patch_bbox : list[BoundingBox | None]
244+
The list of ordered patch bounding boxes.
245+
suggested_patches : dict[int, BoundingBox], optional
246+
Dictionary of suggested patch coordinates for missing patches.
228247
229248
Returns
230249
-------
231-
np.ndarray
232-
Image with visualizations
250+
ImageBGR
251+
The image with drawn detection and patch visualizations.
233252
"""
234253
color_green = (0, 255, 0)
235254
color_cyan = (255, 255, 10)
@@ -249,7 +268,7 @@ def draw_preprocess(
249268
thickness=2,
250269
)
251270

252-
# draw connection lines between expected and intersecting patches
271+
# Draw connection lines between expected and detected patch boxes
253272
patch = ls_ordered_patch_bbox[idx_b]
254273
if patch is None:
255274
continue
@@ -263,7 +282,7 @@ def draw_preprocess(
263282
thickness=1,
264283
)
265284

266-
# draw all predicted boxes
285+
# Draw all predicted boxes
267286
for pbox, pids, pscore in zip(
268287
prediction.boxes,
269288
prediction.class_ids,
Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,32 @@
11
"""
2-
Images Schema Module
3-
--------------------
2+
Image Schema Module
3+
-------------------
44
This module defines type annotations for image processing.
55
66
Attributes
77
----------
88
ColorPatchType : numpy.typing.NDArray[np.uint8]
9-
Represents a color patch extracted from an image. Usually a mean of a region patch.
9+
Represents a color patch extracted from an image,
10+
typically the mean of a region patch.
1011
1112
Example
1213
-------
1314
```python
1415
np.array(
15-
[
16-
[68, 82, 115], # 1. Dark skin
17-
[128, 149, 195], # 2. Light skin
18-
[157, 123, 93], # 3. Blue sky
19-
[65, 108, 91], # 4. Foliage
20-
[175, 129, 130], # 5. Blue flower
21-
[171, 191, 99], # 6. Bluish green
22-
[46, 123, 220], # 7. Orange
23-
[168, 92, 72], # 8. Purplish blue
24-
[97, 84, 194], # 9. Moderate red
25-
[104, 59, 91], # 10. Purple
26-
[62, 189, 161], # 11. Yellow green
27-
[40, 161, 229], # 12. Orange yellow
28-
[147, 63, 42], # 13. Blue
29-
[72, 149, 72], # 14. Green
30-
[57, 50, 175], # 15. Red
31-
[22, 200, 238], # 16. Yellow
32-
[150, 84, 188], # 17. Magenta
33-
[166, 137, 0], # 18. Cyan
34-
[240, 245, 245], # 19. White 9.5
35-
[201, 202, 201], # 20. Neutral 8
36-
[162, 162, 161], # 21. Neutral 6.5
37-
[121, 121, 120], # 22. Neutral 5
38-
[85, 85, 83], # 23. Neutral 3.5
39-
[51, 50, 50], # 24. Black 2
40-
],
16+
[68, 82, 115], # 1. Dark skin
4117
)
4218
```
4319
ImageType : numpy.typing.NDArray[np.uint8]
44-
Represents an image 3D array with shape (H, W, C) in uint8 format.
20+
Represents a 3D image array with shape (H, W, C) in uint8 format.
4521
ImageBGR : numpy.typing.NDArray[np.uint8]
4622
Represents an image in BGR format (OpenCV default).
4723
ImageRGB : numpy.typing.NDArray[np.uint8]
4824
Represents an image in RGB format.
49-
25+
ImageGray : numpy.typing.NDArray[np.uint8]
26+
Represents a grayscale image.
27+
BoundingBox : tuple[int, int, int, int]
28+
Represents a bounding box as (x1, y1, x2, y2).
29+
The top-left and bottom-right corners of the detection.
5030
"""
5131

5232
from typing import Literal
@@ -68,3 +48,4 @@
6848
ImageBGR = NDArray[np.uint8]
6949
ImageRGB = NDArray[np.uint8]
7050
ImageGray = NDArray[np.uint8]
51+
BoundingBox = tuple[int, int, int, int]

color_correction/schemas/det_yv8.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@ class DetectionResult(BaseModel):
2020
A data model that encapsulates YOLOv8 detection results for a standardized color
2121
card and its color patches. The model handles two distinct classes:
2222
patches (label 0) and card (label 1). In a typical detection scenario,
23-
the model captures one color calibration card and 24 color patches.
24-
23+
the model captures one card and 24 color patches inside/outside the card.
2524
2625
Notes
2726
-----
2827
The detection typically yields 25 objects:
2928
30-
- 1 calibration card (class_id: 1)
29+
- 1 color checker card 24 Patches (class_id: 1)
3130
- 24 color patches (class_id: 0)
3231
3332
Attributes
@@ -38,7 +37,7 @@ class DetectionResult(BaseModel):
3837
Class identifiers for each detected object where:
3938
4039
- 0: represents color patches
41-
- 1: represents the calibration card
40+
- 1: represents the color checker card 24 Patches
4241
4342
scores : list[float]
4443
List of confidence scores for each detection.

color_correction/services/color_correction.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
YOLOv8CardDetector,
99
)
1010
from color_correction.core.correction import CorrectionModelFactory
11-
from color_correction.processor.det_yv8 import DetectionProcessor
11+
from color_correction.processor.detection import DetectionProcessor
1212
from color_correction.schemas.custom_types import (
1313
ColorPatchType,
1414
ImageBGR,
@@ -153,6 +153,7 @@ def _extract_color_patches(
153153
Returns
154154
-------
155155
tuple[list[ColorPatchType], ImageType, ImageType | None]
156+
156157
- List of BGR mean values for each detected patch
157158
- Grid visualization of detected patches
158159
- Debug visualization (if debug=True)

0 commit comments

Comments
 (0)