ImagePRO-Python 1.3.1__py3-none-any.whl → 1.4.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.
- ImagePRO/__init__.py +5 -2
- ImagePRO/pipeline/__init__.py +9 -0
- ImagePRO/pipeline/pipeline.py +362 -0
- {imagepro_python-1.3.1.dist-info → imagepro_python-1.4.0.dist-info}/METADATA +24 -1
- {imagepro_python-1.3.1.dist-info → imagepro_python-1.4.0.dist-info}/RECORD +8 -6
- {imagepro_python-1.3.1.dist-info → imagepro_python-1.4.0.dist-info}/WHEEL +0 -0
- {imagepro_python-1.3.1.dist-info → imagepro_python-1.4.0.dist-info}/licenses/LICENSE +0 -0
- {imagepro_python-1.3.1.dist-info → imagepro_python-1.4.0.dist-info}/top_level.txt +0 -0
ImagePRO/__init__.py
CHANGED
|
@@ -12,10 +12,11 @@ Features:
|
|
|
12
12
|
- Pre-processing: resize, crop, rotate, blur, sharpen, contrast enhancement
|
|
13
13
|
- Human analysis: face mesh, pose estimation, hand tracking
|
|
14
14
|
- Object detection with YOLO models
|
|
15
|
+
- Reusable pipelines for chaining operations
|
|
15
16
|
- Real-time processing capabilities
|
|
16
17
|
"""
|
|
17
18
|
|
|
18
|
-
__version__ = "1.
|
|
19
|
+
__version__ = "1.4.0"
|
|
19
20
|
__author__ = "Parsa Safaie"
|
|
20
21
|
__email__ = "parsasafaie.2568@proton.me"
|
|
21
22
|
|
|
@@ -24,10 +25,12 @@ from . import utils
|
|
|
24
25
|
from . import pre_processing
|
|
25
26
|
from . import human_analysis
|
|
26
27
|
from . import object_analysis
|
|
28
|
+
from . import pipeline
|
|
27
29
|
|
|
28
30
|
__all__ = [
|
|
29
31
|
"utils",
|
|
30
32
|
"pre_processing",
|
|
31
33
|
"human_analysis",
|
|
32
|
-
"object_analysis"
|
|
34
|
+
"object_analysis",
|
|
35
|
+
"pipeline"
|
|
33
36
|
]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Pipeline Module
|
|
2
|
+
# Provides a reusable, ordered chain of image processing operations
|
|
3
|
+
#
|
|
4
|
+
# Uses only base dependencies (numpy); all operations handed to a Pipeline
|
|
5
|
+
# may come from any module, including those with optional backends.
|
|
6
|
+
|
|
7
|
+
from .pipeline import Pipeline, Step
|
|
8
|
+
|
|
9
|
+
__all__ = ["Pipeline", "Step"]
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, Callable, Iterator
|
|
6
|
+
|
|
7
|
+
# Add src directory to path for absolute imports
|
|
8
|
+
_file_path = Path(__file__).resolve()
|
|
9
|
+
_src_path = _file_path.parents[2] # Go up to src directory
|
|
10
|
+
if str(_src_path) not in sys.path:
|
|
11
|
+
sys.path.insert(0, str(_src_path))
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
from ImagePRO.utils.image import Image
|
|
16
|
+
from ImagePRO.utils.result import Result
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Step:
|
|
20
|
+
"""
|
|
21
|
+
A single operation in a Pipeline, with optional keyword arguments.
|
|
22
|
+
|
|
23
|
+
Wraps any callable that accepts an Image as its first positional argument
|
|
24
|
+
and returns a Result (or a numpy.ndarray, treated as the output image).
|
|
25
|
+
Keyword arguments given to the constructor are forwarded to the wrapped
|
|
26
|
+
function on every call, so a Step fully describes one stage of a pipeline.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
>>> from ImagePRO.pre_processing.blur import apply_gaussian_blur
|
|
30
|
+
>>> step = Step(apply_gaussian_blur, kernel_size=(7, 7))
|
|
31
|
+
>>> result = step(image) # Same as apply_gaussian_blur(image, kernel_size=(7, 7))
|
|
32
|
+
|
|
33
|
+
Attributes:
|
|
34
|
+
function (Callable):
|
|
35
|
+
The wrapped function to execute.
|
|
36
|
+
kwargs (dict[str, Any]):
|
|
37
|
+
Keyword-only arguments forwarded to the function on each call.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, function: Callable[..., Result], **kwargs: Any) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Create a Step from a function and its keyword arguments.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
function (Callable):
|
|
46
|
+
Function to wrap. Must be callable and accept an Image as its
|
|
47
|
+
first positional argument.
|
|
48
|
+
**kwargs (Any):
|
|
49
|
+
Keyword-only arguments forwarded to the function on every call.
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
TypeError: If function is not callable.
|
|
53
|
+
"""
|
|
54
|
+
if not callable(function):
|
|
55
|
+
raise TypeError("'function' must be a callable.")
|
|
56
|
+
self.function = function
|
|
57
|
+
self.kwargs: dict[str, Any] = dict(kwargs)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def name(self) -> str:
|
|
61
|
+
"""
|
|
62
|
+
Human-readable name of the wrapped function, used in pipeline metadata.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
str: The function's __name__ when available, otherwise the name
|
|
66
|
+
of its type (e.g. 'partial' for functools.partial objects).
|
|
67
|
+
"""
|
|
68
|
+
return getattr(self.function, "__name__", type(self.function).__name__)
|
|
69
|
+
|
|
70
|
+
def __call__(self, image: Image) -> Result:
|
|
71
|
+
"""
|
|
72
|
+
Execute the wrapped function on an image.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
image (Image):
|
|
76
|
+
Input image passed to the wrapped function.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Result: Whatever the wrapped function returns.
|
|
80
|
+
|
|
81
|
+
Raises:
|
|
82
|
+
TypeError: If image is not an Image instance (raised by the
|
|
83
|
+
wrapped function's own validation).
|
|
84
|
+
ValueError: If wrapped function arguments are invalid (raised by
|
|
85
|
+
the wrapped function's own validation).
|
|
86
|
+
"""
|
|
87
|
+
return self.function(image, **self.kwargs)
|
|
88
|
+
|
|
89
|
+
def __repr__(self) -> str:
|
|
90
|
+
"""
|
|
91
|
+
Return a readable representation of the step.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
str: Representation including the function name and arguments.
|
|
95
|
+
"""
|
|
96
|
+
args = ", ".join(f"{key}={value!r}" for key, value in self.kwargs.items())
|
|
97
|
+
return f"Step({self.name}{', ' + args if args else ''})"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class Pipeline:
|
|
101
|
+
"""
|
|
102
|
+
A reusable, ordered chain of image processing operations.
|
|
103
|
+
|
|
104
|
+
A Pipeline is defined once from a sequence of functions and can then be
|
|
105
|
+
run on any input as many times as needed. Each operation receives an
|
|
106
|
+
Image and its output image is automatically wrapped and fed to the next
|
|
107
|
+
operation; the final Result is returned with pipeline metadata attached.
|
|
108
|
+
|
|
109
|
+
Operations are the standard ImagePRO functions (which take an Image and
|
|
110
|
+
return a Result) or any custom callable following the same convention.
|
|
111
|
+
A custom function may also return a plain numpy.ndarray, which is treated
|
|
112
|
+
as the output image. Per-operation keyword arguments are configured with
|
|
113
|
+
Step, or fluently via apply().
|
|
114
|
+
|
|
115
|
+
Pipelines are immutable: apply() returns a new Pipeline and leaves the
|
|
116
|
+
original untouched, and run() never mutates the pipeline, so a single
|
|
117
|
+
Pipeline instance is safe to reuse across many inputs.
|
|
118
|
+
|
|
119
|
+
Example:
|
|
120
|
+
>>> from ImagePRO.pre_processing.blur import apply_gaussian_blur
|
|
121
|
+
>>> from ImagePRO.pre_processing.grayscale import convert_to_grayscale
|
|
122
|
+
>>> from ImagePRO.pre_processing.resize import resize_image
|
|
123
|
+
>>>
|
|
124
|
+
>>> pipeline = Pipeline([
|
|
125
|
+
... Step(apply_gaussian_blur, kernel_size=(7, 7)),
|
|
126
|
+
... convert_to_grayscale,
|
|
127
|
+
... Step(resize_image, new_size=(800, 600)),
|
|
128
|
+
... ])
|
|
129
|
+
>>> result = pipeline.run("photo.jpg") # Any Image, ndarray or path
|
|
130
|
+
>>> result.save_as_img("processed.jpg")
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
def __init__(self, *operations: Any) -> None:
|
|
134
|
+
"""
|
|
135
|
+
Create a Pipeline from one or more operations.
|
|
136
|
+
|
|
137
|
+
Operations can be passed as separate arguments or as a single
|
|
138
|
+
list/tuple. Passing another Pipeline as an operation nests it: the
|
|
139
|
+
inner pipeline runs as a single step.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
*operations (Callable | Step | list | tuple):
|
|
143
|
+
Functions to execute in order. Each element must be callable;
|
|
144
|
+
Step instances carry their keyword arguments. A single
|
|
145
|
+
list/tuple of operations is also accepted.
|
|
146
|
+
|
|
147
|
+
Raises:
|
|
148
|
+
TypeError: If any operation is not callable.
|
|
149
|
+
"""
|
|
150
|
+
if len(operations) == 1 and isinstance(operations[0], (list, tuple)):
|
|
151
|
+
operations = tuple(operations[0])
|
|
152
|
+
|
|
153
|
+
steps: list[Step] = []
|
|
154
|
+
for operation in operations:
|
|
155
|
+
if not callable(operation):
|
|
156
|
+
raise TypeError(
|
|
157
|
+
"All pipeline operations must be callable; got "
|
|
158
|
+
f"{type(operation).__name__}. Wrap keyword arguments with "
|
|
159
|
+
"Step, e.g. Step(resize_image, new_size=(800, 600))."
|
|
160
|
+
)
|
|
161
|
+
steps.append(operation if isinstance(operation, Step) else Step(operation))
|
|
162
|
+
self._operations = steps
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def operations(self) -> tuple[Step, ...]:
|
|
166
|
+
"""
|
|
167
|
+
The ordered steps of this pipeline.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
tuple[Step, ...]: Step objects in execution order.
|
|
171
|
+
"""
|
|
172
|
+
return tuple(self._operations)
|
|
173
|
+
|
|
174
|
+
def apply(self, function: Callable[..., Result], **kwargs: Any) -> Pipeline:
|
|
175
|
+
"""
|
|
176
|
+
Return a new Pipeline with one more operation appended.
|
|
177
|
+
|
|
178
|
+
The current pipeline is not modified, following ImagePRO's
|
|
179
|
+
non-destructive design principle.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
function (Callable):
|
|
183
|
+
Function to append. Must be callable and accept an Image as
|
|
184
|
+
its first positional argument.
|
|
185
|
+
**kwargs (Any):
|
|
186
|
+
Keyword-only arguments forwarded to the function on every run.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
Pipeline: New pipeline containing all existing steps plus this one.
|
|
190
|
+
|
|
191
|
+
Raises:
|
|
192
|
+
TypeError: If function is not callable.
|
|
193
|
+
|
|
194
|
+
Example:
|
|
195
|
+
>>> pipeline = Pipeline(apply_gaussian_blur).apply(
|
|
196
|
+
... resize_image, new_size=(800, 600)
|
|
197
|
+
... )
|
|
198
|
+
"""
|
|
199
|
+
return Pipeline(*self._operations, Step(function, **kwargs))
|
|
200
|
+
|
|
201
|
+
def run(self, image: Image | np.ndarray | str | Path) -> Result:
|
|
202
|
+
"""
|
|
203
|
+
Execute all pipeline operations in order on the given input.
|
|
204
|
+
|
|
205
|
+
The input is first normalized to an Image (file paths are loaded and
|
|
206
|
+
NumPy arrays are wrapped, assuming BGR for 3-channel and GRAY for 2D
|
|
207
|
+
arrays). Each operation then receives an Image built from the previous
|
|
208
|
+
operation's output; 2D intermediates are tagged as GRAY and
|
|
209
|
+
multi-channel ones keep the incoming colorspace.
|
|
210
|
+
|
|
211
|
+
The returned Result carries the final operation's image and data. Its
|
|
212
|
+
metadata contains the pipeline information (operation, steps,
|
|
213
|
+
step_meta, source) merged over the final operation's own metadata.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
image (Image | np.ndarray | str | Path):
|
|
217
|
+
Input to process. Can be an Image instance, a NumPy array
|
|
218
|
+
(BGR for 3-channel, GRAY for 2D), or a path to an image file.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
Result: Result object of the final operation.
|
|
222
|
+
- image (np.ndarray | list[np.ndarray] | None): Final output image(s)
|
|
223
|
+
- data (Any): Structured data of the final operation
|
|
224
|
+
- meta (dict): Final operation metadata plus pipeline info:
|
|
225
|
+
'operation' ("pipeline"), 'steps' (list of step names),
|
|
226
|
+
'step_meta' (per-step metadata list), 'source' (input Image)
|
|
227
|
+
|
|
228
|
+
Raises:
|
|
229
|
+
TypeError: If image is not an Image, ndarray, or path.
|
|
230
|
+
TypeError: If an operation returns an unsupported type.
|
|
231
|
+
ValueError: If the pipeline has no operations.
|
|
232
|
+
ValueError: If a non-final operation returns no image, so the
|
|
233
|
+
chain cannot continue.
|
|
234
|
+
TypeError/ValueError: As raised by the operations themselves for
|
|
235
|
+
invalid inputs or arguments.
|
|
236
|
+
"""
|
|
237
|
+
# Normalize input to an Image (cheap validation before any step runs)
|
|
238
|
+
if isinstance(image, Image):
|
|
239
|
+
current = image
|
|
240
|
+
elif isinstance(image, np.ndarray):
|
|
241
|
+
colorspace = "GRAY" if image.ndim == 2 else "BGR"
|
|
242
|
+
current = Image.from_array(image, colorspace=colorspace)
|
|
243
|
+
elif isinstance(image, (str, Path)):
|
|
244
|
+
current = Image.from_path(image)
|
|
245
|
+
else:
|
|
246
|
+
raise TypeError(
|
|
247
|
+
"'image' must be an Image instance, a numpy.ndarray, or a "
|
|
248
|
+
"file path (str or pathlib.Path)."
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
if not self._operations:
|
|
252
|
+
raise ValueError(
|
|
253
|
+
"Cannot run an empty pipeline. Add operations at construction "
|
|
254
|
+
"or with apply()."
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
source = current
|
|
258
|
+
step_names: list[str] = []
|
|
259
|
+
step_metas: list[dict[str, Any]] = []
|
|
260
|
+
final_image: Any = None
|
|
261
|
+
final_data: Any = None
|
|
262
|
+
final_meta: dict[str, Any] = {}
|
|
263
|
+
|
|
264
|
+
for index, step in enumerate(self._operations):
|
|
265
|
+
is_last = index == len(self._operations) - 1
|
|
266
|
+
output = step(current)
|
|
267
|
+
|
|
268
|
+
# Normalize the step output (Result is the convention; a plain
|
|
269
|
+
# ndarray from custom functions is accepted as the output image)
|
|
270
|
+
if isinstance(output, Result):
|
|
271
|
+
final_image = output.image
|
|
272
|
+
final_data = output.data
|
|
273
|
+
final_meta = dict(output.meta)
|
|
274
|
+
elif isinstance(output, np.ndarray):
|
|
275
|
+
final_image = output
|
|
276
|
+
final_data = None
|
|
277
|
+
final_meta = {}
|
|
278
|
+
else:
|
|
279
|
+
raise TypeError(
|
|
280
|
+
f"Step {index} ('{step.name}') returned "
|
|
281
|
+
f"{type(output).__name__}; pipeline operations must "
|
|
282
|
+
"return a Result object or a numpy.ndarray."
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
step_names.append(step.name)
|
|
286
|
+
step_metas.append(final_meta)
|
|
287
|
+
|
|
288
|
+
if is_last:
|
|
289
|
+
break
|
|
290
|
+
|
|
291
|
+
# Prepare the input of the next operation
|
|
292
|
+
if final_image is None:
|
|
293
|
+
raise ValueError(
|
|
294
|
+
f"Step {index} ('{step.name}') returned no image, so the "
|
|
295
|
+
"pipeline cannot continue. Only the final step of a "
|
|
296
|
+
"pipeline may return a result without an image."
|
|
297
|
+
)
|
|
298
|
+
if not isinstance(final_image, np.ndarray):
|
|
299
|
+
raise ValueError(
|
|
300
|
+
f"Step {index} ('{step.name}') did not return a single "
|
|
301
|
+
"image array, so the pipeline cannot continue. Only the "
|
|
302
|
+
"final step of a pipeline may return multi-image results."
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
colorspace = "GRAY" if final_image.ndim == 2 else current.colorspace
|
|
306
|
+
current = Image.from_array(final_image, colorspace=colorspace)
|
|
307
|
+
|
|
308
|
+
meta = dict(final_meta)
|
|
309
|
+
meta.update({
|
|
310
|
+
"source": source,
|
|
311
|
+
"operation": "pipeline",
|
|
312
|
+
"steps": step_names,
|
|
313
|
+
"step_meta": step_metas,
|
|
314
|
+
})
|
|
315
|
+
return Result(image=final_image, data=final_data, meta=meta)
|
|
316
|
+
|
|
317
|
+
def __call__(self, image: Image | np.ndarray | str | Path) -> Result:
|
|
318
|
+
"""
|
|
319
|
+
Run the pipeline on an input; shorthand for run().
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
image (Image | np.ndarray | str | Path):
|
|
323
|
+
Input to process, as accepted by run().
|
|
324
|
+
|
|
325
|
+
Returns:
|
|
326
|
+
Result: Result object of the final operation.
|
|
327
|
+
|
|
328
|
+
Raises:
|
|
329
|
+
TypeError: If image is not an Image, ndarray, or path.
|
|
330
|
+
ValueError: If the pipeline has no operations or a non-final
|
|
331
|
+
operation returns no image.
|
|
332
|
+
"""
|
|
333
|
+
return self.run(image)
|
|
334
|
+
|
|
335
|
+
def __len__(self) -> int:
|
|
336
|
+
"""
|
|
337
|
+
Return the number of operations in the pipeline.
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
int: Number of steps.
|
|
341
|
+
"""
|
|
342
|
+
return len(self._operations)
|
|
343
|
+
|
|
344
|
+
def __iter__(self) -> Iterator[Step]:
|
|
345
|
+
"""
|
|
346
|
+
Iterate over the pipeline's steps in execution order.
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
Iterator[Step]: Iterator of Step objects.
|
|
350
|
+
"""
|
|
351
|
+
return iter(self._operations)
|
|
352
|
+
|
|
353
|
+
def __repr__(self) -> str:
|
|
354
|
+
"""
|
|
355
|
+
Return a readable representation of the pipeline.
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
str: Representation listing the step names in order.
|
|
359
|
+
"""
|
|
360
|
+
if not self._operations:
|
|
361
|
+
return "Pipeline(<empty>)"
|
|
362
|
+
return f"Pipeline({' -> '.join(step.name for step in self._operations)})"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ImagePRO-Python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Professional & modular image processing library with OpenCV, MediaPipe, and YOLO integration.
|
|
5
5
|
Author-email: Parsa Safaie <parsasafaie.2568@proton.me>
|
|
6
6
|
License: MIT
|
|
@@ -76,6 +76,11 @@ Whether you're working on computer vision pipelines, preprocessing images for AI
|
|
|
76
76
|
- **YOLO Integration**: Multiple accuracy levels (nano to extra-large)
|
|
77
77
|
- **Flexible Models**: Pre-trained or custom model support
|
|
78
78
|
|
|
79
|
+
### **Pipelines**
|
|
80
|
+
- **Reusable Operation Chains**: Define a sequence of functions once, then run it on any input (Image, NumPy array, or file path)
|
|
81
|
+
- **Flexible Steps**: Any ImagePRO function or custom callable; per-step keyword arguments via `Step`
|
|
82
|
+
- **Pipeline Metadata**: Every result lists the executed steps and each step's parameters
|
|
83
|
+
|
|
79
84
|
## Installation
|
|
80
85
|
|
|
81
86
|
### From PyPI
|
|
@@ -154,6 +159,22 @@ object_detection_result = detect_objects(
|
|
|
154
159
|
)
|
|
155
160
|
print(f"Detected {len(object_detection_result.data)} objects")
|
|
156
161
|
object_detection_result.save_as_img("detections.jpg")
|
|
162
|
+
|
|
163
|
+
# Chain operations into a reusable pipeline
|
|
164
|
+
from ImagePRO.pipeline import Pipeline, Step
|
|
165
|
+
from ImagePRO.pre_processing.grayscale import convert_to_grayscale
|
|
166
|
+
from ImagePRO.pre_processing.resize import resize_image
|
|
167
|
+
|
|
168
|
+
pipeline = Pipeline([
|
|
169
|
+
Step(apply_gaussian_blur, kernel_size=(7, 7)),
|
|
170
|
+
convert_to_grayscale,
|
|
171
|
+
Step(resize_image, new_size=(800, 600)),
|
|
172
|
+
])
|
|
173
|
+
|
|
174
|
+
# Run it on any input: an Image, a NumPy array, or a file path
|
|
175
|
+
pipeline_result = pipeline.run("person_and_objects.jpg")
|
|
176
|
+
pipeline_result.save_as_img("processed_output.jpg")
|
|
177
|
+
print(pipeline_result.meta["steps"]) # Executed step names
|
|
157
178
|
```
|
|
158
179
|
|
|
159
180
|
> **Note**: These are basic examples. Each module contains many more functions with extensive customization options. Explore the module-specific README files for detailed documentation.
|
|
@@ -167,6 +188,7 @@ Each module includes comprehensive documentation with detailed examples:
|
|
|
167
188
|
- [Face Analysis](src/ImagePRO/human_analysis/face_analysis/README.md): Face mesh, pose estimation, eye status, comparison
|
|
168
189
|
- [Body Analysis](src/ImagePRO/human_analysis/body_analysis/README.md): Body pose and hand tracking
|
|
169
190
|
- **[Object Analysis](src/ImagePRO/object_analysis/README.md)**: YOLO-based object detection
|
|
191
|
+
- **[Pipeline](src/ImagePRO/pipeline/README.md)**: Reusable chains of image processing operations
|
|
170
192
|
- **[Utils](src/ImagePRO/utils/README.md)**: Shared utilities and I/O handling
|
|
171
193
|
|
|
172
194
|
For detailed project structure and development guidelines, see [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
|
|
@@ -178,6 +200,7 @@ ImagePRO is built with a modular architecture designed for extensibility and mai
|
|
|
178
200
|
- **Clean Separation of Concerns**: Each module handles a specific domain
|
|
179
201
|
- **Consistent API Patterns**: All functions follow the same input/output conventions
|
|
180
202
|
- **Shared Utilities**: Common `Image` and `Result` classes for unified I/O
|
|
203
|
+
- **Reusable Pipelines**: Chain any operations into a `Pipeline` and run it on any input
|
|
181
204
|
- **Lazy Optional Imports**: Heavy AI dependencies (MediaPipe, Ultralytics, InsightFace) are only imported inside the functions that use them, keeping `import ImagePRO` fast and independent of installed extras
|
|
182
205
|
- **Professional Error Handling**: Comprehensive validation with clear error messages
|
|
183
206
|
- **Type Safety**: Full type hints throughout the codebase
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
ImagePRO/__init__.py,sha256=
|
|
1
|
+
ImagePRO/__init__.py,sha256=3B8cQH4zhV6EEAvVMKYMsJHok_hpGLTgu4QfP33DV08,1081
|
|
2
2
|
ImagePRO/human_analysis/__init__.py,sha256=uSU0lM1p1HM6TNGv6u0nPHWy9QY505v43lqTkhClddM,190
|
|
3
3
|
ImagePRO/human_analysis/body_analysis/__init__.py,sha256=uUWG5eOxLQjZoYddmNkRlF66l6vSVyJpUFz1wDddXkk,374
|
|
4
4
|
ImagePRO/human_analysis/body_analysis/body_pose_estimation.py,sha256=yqEV18ZEZwV__Oqt1Hi72EGmbTNes-mrY068SBT9RbU,6245
|
|
@@ -11,6 +11,8 @@ ImagePRO/human_analysis/face_analysis/face_mesh_analysis.py,sha256=rv08Mx_IBB-hj
|
|
|
11
11
|
ImagePRO/human_analysis/face_analysis/head_pose_estimation.py,sha256=2_ZVpwavyIzCIH4x3d2bvCPvv-X5gpmSYxtk5jlgCYw,7688
|
|
12
12
|
ImagePRO/object_analysis/__init__.py,sha256=eVQpYlHO89RYKT0CHjPfJjjif5X_Jx3AtAUpR5m0Yms,292
|
|
13
13
|
ImagePRO/object_analysis/object_detection.py,sha256=1qPd3Xfo2Vi4JnBs5wD8-k3WR6ZkYNdT9tco2Ze1ICQ,3385
|
|
14
|
+
ImagePRO/pipeline/__init__.py,sha256=-32hbR492qwxutXau7EfnysXbhW8fKKMywkV0ejIMFE,301
|
|
15
|
+
ImagePRO/pipeline/pipeline.py,sha256=-CRWfWXB_lFdjrqg3gdyYFFvq0vZAednrJnod6b4WYA,13802
|
|
14
16
|
ImagePRO/pre_processing/__init__.py,sha256=pw6-J5sdbkdBG4RlTxOzQKaspGnlPIGo3m_NXH2bVCE,559
|
|
15
17
|
ImagePRO/pre_processing/blur.py,sha256=3zNTNpvLZPdrtRtBziB6X8ys8M7cIvyPDhojTqR63jo,7950
|
|
16
18
|
ImagePRO/pre_processing/contrast.py,sha256=4UT78ggW1rh_iaEI8FObDB4kpEmRRFWjdJES60SnHDM,5064
|
|
@@ -24,8 +26,8 @@ ImagePRO/pre_processing/sharpen.py,sha256=hOkY7QhzgMp9LXQwt56AP4enn24ntXlmFLe57B
|
|
|
24
26
|
ImagePRO/utils/__init__.py,sha256=McVd-o9KtKOpAVYbLi19KxsatPPFFF-Qbt0gdgY3Ln8,170
|
|
25
27
|
ImagePRO/utils/image.py,sha256=Y64mD97rTiJb8_uNYlyG227VZodeb4U1aGezMkj7MnM,4025
|
|
26
28
|
ImagePRO/utils/result.py,sha256=ToQaOmUlTtobJkC65BG0YO_6BkBleMBn-0Qydko7cZc,6138
|
|
27
|
-
imagepro_python-1.
|
|
28
|
-
imagepro_python-1.
|
|
29
|
-
imagepro_python-1.
|
|
30
|
-
imagepro_python-1.
|
|
31
|
-
imagepro_python-1.
|
|
29
|
+
imagepro_python-1.4.0.dist-info/licenses/LICENSE,sha256=sehkHN7dbe5umrINZJyJjIf9VTemZSgTfJlq6iIsbJQ,1069
|
|
30
|
+
imagepro_python-1.4.0.dist-info/METADATA,sha256=POgVUYD-3fKBCKxkjSgKTZqCt5BWjvtfDBqlrn7Qg9I,11121
|
|
31
|
+
imagepro_python-1.4.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
32
|
+
imagepro_python-1.4.0.dist-info/top_level.txt,sha256=UOuPzsoWrVKXgUupOSI96shJ6wE8Fhz-8bm8oMlLC3s,9
|
|
33
|
+
imagepro_python-1.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|