ImagePRO-Python 1.2.1__tar.gz → 1.3.0__tar.gz
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_python-1.2.1/src/ImagePRO_Python.egg-info → imagepro_python-1.3.0}/PKG-INFO +43 -18
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/pyproject.toml +21 -7
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/readme.md +37 -17
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/__init__.py +2 -2
- imagepro_python-1.3.0/src/ImagePRO/human_analysis/body_analysis/__init__.py +17 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/body_analysis/body_pose_estimation.py +3 -2
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/body_analysis/hand_tracking.py +5 -3
- imagepro_python-1.3.0/src/ImagePRO/human_analysis/face_analysis/__init__.py +39 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/face_analysis/face_comparison.py +2 -2
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/face_analysis/face_detection.py +1 -1
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/face_analysis/face_mesh_analysis.py +11 -12
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/face_analysis/head_pose_estimation.py +1 -1
- imagepro_python-1.3.0/src/ImagePRO/object_analysis/__init__.py +9 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/object_analysis/object_detection.py +6 -6
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/__init__.py +6 -2
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/blur.py +10 -10
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/contrast.py +4 -7
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/crop.py +4 -5
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/dataset_generator.py +9 -10
- imagepro_python-1.3.0/src/ImagePRO/pre_processing/histogram.py +81 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/resize.py +2 -2
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/rotate.py +6 -7
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/sharpen.py +16 -13
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/utils/image.py +7 -6
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/utils/result.py +10 -7
- {imagepro_python-1.2.1 → imagepro_python-1.3.0/src/ImagePRO_Python.egg-info}/PKG-INFO +43 -18
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO_Python.egg-info/SOURCES.txt +21 -1
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO_Python.egg-info/requires.txt +6 -0
- imagepro_python-1.3.0/tests/test_blur.py +148 -0
- imagepro_python-1.3.0/tests/test_body_pose_estimation.py +80 -0
- imagepro_python-1.3.0/tests/test_contrast.py +116 -0
- imagepro_python-1.3.0/tests/test_crop.py +82 -0
- imagepro_python-1.3.0/tests/test_dataset_generator.py +72 -0
- imagepro_python-1.3.0/tests/test_eye_status_analysis.py +109 -0
- imagepro_python-1.3.0/tests/test_face_comparison.py +67 -0
- imagepro_python-1.3.0/tests/test_face_detection.py +111 -0
- imagepro_python-1.3.0/tests/test_face_mesh_analysis.py +201 -0
- imagepro_python-1.3.0/tests/test_grayscale.py +61 -0
- imagepro_python-1.3.0/tests/test_hand_tracking.py +102 -0
- imagepro_python-1.3.0/tests/test_head_pose_estimation.py +92 -0
- imagepro_python-1.3.0/tests/test_histogram.py +45 -0
- imagepro_python-1.3.0/tests/test_image.py +78 -0
- imagepro_python-1.3.0/tests/test_integration.py +102 -0
- imagepro_python-1.3.0/tests/test_object_detection.py +103 -0
- imagepro_python-1.3.0/tests/test_resize.py +45 -0
- imagepro_python-1.3.0/tests/test_result.py +169 -0
- imagepro_python-1.3.0/tests/test_rotate.py +85 -0
- imagepro_python-1.3.0/tests/test_sharpen.py +76 -0
- imagepro_python-1.2.1/src/ImagePRO/human_analysis/body_analysis/__init__.py +0 -7
- imagepro_python-1.2.1/src/ImagePRO/human_analysis/face_analysis/__init__.py +0 -16
- imagepro_python-1.2.1/src/ImagePRO/object_analysis/__init__.py +0 -6
- imagepro_python-1.2.1/src/ImagePRO/pre_processing/histogram.py +0 -93
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/LICENSE +0 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/setup.cfg +0 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/__init__.py +0 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/human_analysis/face_analysis/eye_status_analysis.py +0 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/pre_processing/grayscale.py +0 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/utils/__init__.py +0 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO_Python.egg-info/dependency_links.txt +0 -0
- {imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO_Python.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ImagePRO-Python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.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
|
|
@@ -32,14 +32,19 @@ Provides-Extra: yolo
|
|
|
32
32
|
Requires-Dist: ultralytics<9.0,>=8.2; extra == "yolo"
|
|
33
33
|
Provides-Extra: mediapipe
|
|
34
34
|
Requires-Dist: mediapipe<=0.10.11,>=0.10.0; extra == "mediapipe"
|
|
35
|
+
Requires-Dist: numpy<2.0,>=1.24; extra == "mediapipe"
|
|
35
36
|
Provides-Extra: insightface
|
|
36
37
|
Requires-Dist: insightface<0.8,>=0.7; extra == "insightface"
|
|
37
38
|
Requires-Dist: onnxruntime<2.0,>=1.16; extra == "insightface"
|
|
39
|
+
Requires-Dist: numpy<2.0,>=1.24; extra == "insightface"
|
|
38
40
|
Provides-Extra: full
|
|
39
41
|
Requires-Dist: mediapipe<=0.10.11,>=0.10.0; extra == "full"
|
|
40
42
|
Requires-Dist: ultralytics<9.0,>=8.2; extra == "full"
|
|
41
43
|
Requires-Dist: insightface<0.8,>=0.7; extra == "full"
|
|
42
44
|
Requires-Dist: onnxruntime<2.0,>=1.16; extra == "full"
|
|
45
|
+
Requires-Dist: numpy<2.0,>=1.24; extra == "full"
|
|
46
|
+
Provides-Extra: dev
|
|
47
|
+
Requires-Dist: pytest<9.0,>=8.0; extra == "dev"
|
|
43
48
|
Dynamic: license-file
|
|
44
49
|
|
|
45
50
|
# ImagePRO
|
|
@@ -50,11 +55,10 @@ Dynamic: license-file
|
|
|
50
55
|
|
|
51
56
|
Whether you're working on computer vision pipelines, preprocessing images for AI models, or simply automating batch image edits — **ImagePRO** gives you powerful tools with minimal effort.
|
|
52
57
|
|
|
53
|
-
##
|
|
58
|
+
## Features
|
|
54
59
|
|
|
55
60
|
### **Image I/O & Management**
|
|
56
61
|
- Flexible input/output handling (file paths or numpy arrays)
|
|
57
|
-
- Batch processing capabilities
|
|
58
62
|
- Multiple format support (JPEG, PNG, CSV, etc.)
|
|
59
63
|
|
|
60
64
|
### **Pre-processing & Enhancement**
|
|
@@ -71,13 +75,19 @@ Whether you're working on computer vision pipelines, preprocessing images for AI
|
|
|
71
75
|
### **Object Detection**
|
|
72
76
|
- **YOLO Integration**: Multiple accuracy levels (nano to extra-large)
|
|
73
77
|
- **Flexible Models**: Pre-trained or custom model support
|
|
74
|
-
- **Batch Processing**: Efficient handling of multiple images
|
|
75
78
|
|
|
76
|
-
##
|
|
79
|
+
## Installation
|
|
77
80
|
|
|
78
81
|
### From PyPI
|
|
79
82
|
```bash
|
|
80
83
|
pip install ImagePRO-Python
|
|
84
|
+
|
|
85
|
+
# Or with optional extras:
|
|
86
|
+
pip install "ImagePRO-Python[yolo]" # YOLO object detection
|
|
87
|
+
pip install "ImagePRO-Python[mediapipe]" # MediaPipe human analysis
|
|
88
|
+
pip install "ImagePRO-Python[insightface]" # InsightFace face comparison
|
|
89
|
+
pip install "ImagePRO-Python[full]" # Everything
|
|
90
|
+
pip install "ImagePRO-Python[dev]" # Test tooling (pytest)
|
|
81
91
|
```
|
|
82
92
|
|
|
83
93
|
### From Source
|
|
@@ -109,7 +119,7 @@ pip install -r requirements/full.txt
|
|
|
109
119
|
|
|
110
120
|
See the [Directory Structure](/PROJECT_STRUCTURE.md#directory-structure) section in [PROJECT_STRUCTURE.md](/PROJECT_STRUCTURE.md) for details on which modules need which requirements.
|
|
111
121
|
|
|
112
|
-
##
|
|
122
|
+
## Quick Start
|
|
113
123
|
|
|
114
124
|
```python
|
|
115
125
|
from ImagePRO.pre_processing.blur import apply_average_blur
|
|
@@ -126,9 +136,9 @@ image = Image.from_path("person_and_objects.jpg")
|
|
|
126
136
|
blur_result = apply_average_blur(image=image)
|
|
127
137
|
blur_result.save_as_img("blurred_output.jpg")
|
|
128
138
|
|
|
129
|
-
# Analyze face mesh (468 landmarks)
|
|
139
|
+
# Analyze face mesh (468 landmarks per detected face)
|
|
130
140
|
face_mesh_result = analyze_face_mesh(image=image)
|
|
131
|
-
print(f"Detected {len(face_mesh_result.data)} face
|
|
141
|
+
print(f"Detected {len(face_mesh_result.data)} face(s)")
|
|
132
142
|
face_mesh_result.save_as_csv("face_landmarks.csv")
|
|
133
143
|
|
|
134
144
|
# Detect body pose (33 landmarks)
|
|
@@ -138,8 +148,7 @@ print(f"Body pose data: {body_pose_result.data}")
|
|
|
138
148
|
# Detect objects with YOLO
|
|
139
149
|
object_detection_result = detect_objects(
|
|
140
150
|
image=image,
|
|
141
|
-
accuracy_level=3
|
|
142
|
-
confidence=0.5
|
|
151
|
+
accuracy_level=3 # 1=nano, 2=small, 3=medium, 4=large, 5=extra-large
|
|
143
152
|
)
|
|
144
153
|
print(f"Detected {len(object_detection_result.data)} objects")
|
|
145
154
|
object_detection_result.save_as_img("detections.jpg")
|
|
@@ -147,7 +156,7 @@ object_detection_result.save_as_img("detections.jpg")
|
|
|
147
156
|
|
|
148
157
|
> **Note**: These are basic examples. Each module contains many more functions with extensive customization options. Explore the module-specific README files for detailed documentation.
|
|
149
158
|
|
|
150
|
-
##
|
|
159
|
+
## Documentation
|
|
151
160
|
|
|
152
161
|
Each module includes comprehensive documentation with detailed examples:
|
|
153
162
|
|
|
@@ -160,7 +169,7 @@ Each module includes comprehensive documentation with detailed examples:
|
|
|
160
169
|
|
|
161
170
|
For detailed project structure and development guidelines, see [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
|
|
162
171
|
|
|
163
|
-
##
|
|
172
|
+
## Architecture
|
|
164
173
|
|
|
165
174
|
ImagePRO is built with a modular architecture designed for extensibility and maintainability:
|
|
166
175
|
|
|
@@ -172,12 +181,27 @@ ImagePRO is built with a modular architecture designed for extensibility and mai
|
|
|
172
181
|
- **Documentation**: Google-style docstrings for all functions
|
|
173
182
|
|
|
174
183
|
### Key Design Principles
|
|
175
|
-
- **
|
|
184
|
+
- **Non-Destructive Operations**: Operations never write into the input image; they return results in new `Result` objects (note: `crop_image` returns a view into the source array)
|
|
176
185
|
- **Functional Style**: Stateless functions that can be easily composed
|
|
177
186
|
- **Result Objects**: Unified return type containing image, data, and metadata
|
|
178
187
|
- **Keyword Arguments**: All optional parameters use keyword-only syntax
|
|
179
188
|
|
|
180
|
-
##
|
|
189
|
+
## Testing
|
|
190
|
+
|
|
191
|
+
The test suite uses pytest:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Install with test tooling (editable install + dev extra)
|
|
195
|
+
pip install -e ".[dev]"
|
|
196
|
+
|
|
197
|
+
# Run the suite (optional heavy dependencies are mocked; base deps are enough)
|
|
198
|
+
pytest
|
|
199
|
+
|
|
200
|
+
# Include performance smoke guards
|
|
201
|
+
pytest --run-performance
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Contributing
|
|
181
205
|
|
|
182
206
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
183
207
|
|
|
@@ -185,9 +209,10 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
185
209
|
1. Fork the repository
|
|
186
210
|
2. Create a virtual environment: `python -m venv .venv`
|
|
187
211
|
3. Install dependencies: `pip install -r requirements/full.txt`
|
|
188
|
-
4.
|
|
189
|
-
5.
|
|
190
|
-
6.
|
|
212
|
+
4. Install for development with test tooling: `pip install -e ".[dev]"`
|
|
213
|
+
5. Follow the coding standards outlined in [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md)
|
|
214
|
+
6. Add tests for new features and run `pytest`
|
|
215
|
+
7. Update documentation as needed
|
|
191
216
|
|
|
192
217
|
### Reporting Issues
|
|
193
218
|
If you encounter any bugs or have feature requests, please open an issue on the GitHub repository with:
|
|
@@ -196,5 +221,5 @@ If you encounter any bugs or have feature requests, please open an issue on the
|
|
|
196
221
|
- Expected vs. actual behavior
|
|
197
222
|
- Environment details (OS, Python version, etc.)
|
|
198
223
|
|
|
199
|
-
##
|
|
224
|
+
## License
|
|
200
225
|
This project is licensed under the MIT License – see the [LICENSE](LICENSE) file for details.
|
|
@@ -7,7 +7,7 @@ where = ["src"]
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "ImagePRO-Python"
|
|
10
|
-
version = "1.
|
|
10
|
+
version = "1.3.0"
|
|
11
11
|
description = "Professional & modular image processing library with OpenCV, MediaPipe, and YOLO integration."
|
|
12
12
|
readme = "readme.md"
|
|
13
13
|
requires-python = ">=3.9,<3.13"
|
|
@@ -54,20 +54,37 @@ yolo = [
|
|
|
54
54
|
"ultralytics>=8.2,<9.0"
|
|
55
55
|
]
|
|
56
56
|
|
|
57
|
+
# mediapipe<=0.10.11 and insightface 0.7.x ship binaries built against
|
|
58
|
+
# the NumPy 1.x ABI, so groups that include them cap numpy below 2.0.
|
|
57
59
|
mediapipe = [
|
|
58
|
-
"mediapipe>=0.10.0,<=0.10.11"
|
|
60
|
+
"mediapipe>=0.10.0,<=0.10.11",
|
|
61
|
+
"numpy>=1.24,<2.0"
|
|
59
62
|
]
|
|
60
63
|
|
|
61
64
|
insightface = [
|
|
62
65
|
"insightface>=0.7,<0.8",
|
|
63
|
-
"onnxruntime>=1.16,<2.0"
|
|
66
|
+
"onnxruntime>=1.16,<2.0",
|
|
67
|
+
"numpy>=1.24,<2.0"
|
|
64
68
|
]
|
|
65
69
|
|
|
66
70
|
full = [
|
|
67
71
|
"mediapipe>=0.10.0,<=0.10.11",
|
|
68
72
|
"ultralytics>=8.2,<9.0",
|
|
69
73
|
"insightface>=0.7,<0.8",
|
|
70
|
-
"onnxruntime>=1.16,<2.0"
|
|
74
|
+
"onnxruntime>=1.16,<2.0",
|
|
75
|
+
"numpy>=1.24,<2.0"
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
dev = [
|
|
79
|
+
"pytest>=8.0,<9.0"
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
[tool.pytest.ini_options]
|
|
83
|
+
testpaths = ["tests"]
|
|
84
|
+
pythonpath = ["src"]
|
|
85
|
+
addopts = "-ra"
|
|
86
|
+
markers = [
|
|
87
|
+
"perf: performance smoke tests (run with --run-performance)"
|
|
71
88
|
]
|
|
72
89
|
|
|
73
90
|
[project.urls]
|
|
@@ -75,6 +92,3 @@ Homepage = "https://github.com/parsasafaie/ImagePRO"
|
|
|
75
92
|
Repository = "https://github.com/parsasafaie/ImagePRO.git"
|
|
76
93
|
Documentation = "https://github.com/parsasafaie/ImagePRO#readme"
|
|
77
94
|
Issues = "https://github.com/parsasafaie/ImagePRO/issues"
|
|
78
|
-
|
|
79
|
-
[tool.hatch.build.targets.wheel]
|
|
80
|
-
packages = ["ImagePRO"]
|
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
Whether you're working on computer vision pipelines, preprocessing images for AI models, or simply automating batch image edits — **ImagePRO** gives you powerful tools with minimal effort.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Features
|
|
10
10
|
|
|
11
11
|
### **Image I/O & Management**
|
|
12
12
|
- Flexible input/output handling (file paths or numpy arrays)
|
|
13
|
-
- Batch processing capabilities
|
|
14
13
|
- Multiple format support (JPEG, PNG, CSV, etc.)
|
|
15
14
|
|
|
16
15
|
### **Pre-processing & Enhancement**
|
|
@@ -27,13 +26,19 @@ Whether you're working on computer vision pipelines, preprocessing images for AI
|
|
|
27
26
|
### **Object Detection**
|
|
28
27
|
- **YOLO Integration**: Multiple accuracy levels (nano to extra-large)
|
|
29
28
|
- **Flexible Models**: Pre-trained or custom model support
|
|
30
|
-
- **Batch Processing**: Efficient handling of multiple images
|
|
31
29
|
|
|
32
|
-
##
|
|
30
|
+
## Installation
|
|
33
31
|
|
|
34
32
|
### From PyPI
|
|
35
33
|
```bash
|
|
36
34
|
pip install ImagePRO-Python
|
|
35
|
+
|
|
36
|
+
# Or with optional extras:
|
|
37
|
+
pip install "ImagePRO-Python[yolo]" # YOLO object detection
|
|
38
|
+
pip install "ImagePRO-Python[mediapipe]" # MediaPipe human analysis
|
|
39
|
+
pip install "ImagePRO-Python[insightface]" # InsightFace face comparison
|
|
40
|
+
pip install "ImagePRO-Python[full]" # Everything
|
|
41
|
+
pip install "ImagePRO-Python[dev]" # Test tooling (pytest)
|
|
37
42
|
```
|
|
38
43
|
|
|
39
44
|
### From Source
|
|
@@ -65,7 +70,7 @@ pip install -r requirements/full.txt
|
|
|
65
70
|
|
|
66
71
|
See the [Directory Structure](/PROJECT_STRUCTURE.md#directory-structure) section in [PROJECT_STRUCTURE.md](/PROJECT_STRUCTURE.md) for details on which modules need which requirements.
|
|
67
72
|
|
|
68
|
-
##
|
|
73
|
+
## Quick Start
|
|
69
74
|
|
|
70
75
|
```python
|
|
71
76
|
from ImagePRO.pre_processing.blur import apply_average_blur
|
|
@@ -82,9 +87,9 @@ image = Image.from_path("person_and_objects.jpg")
|
|
|
82
87
|
blur_result = apply_average_blur(image=image)
|
|
83
88
|
blur_result.save_as_img("blurred_output.jpg")
|
|
84
89
|
|
|
85
|
-
# Analyze face mesh (468 landmarks)
|
|
90
|
+
# Analyze face mesh (468 landmarks per detected face)
|
|
86
91
|
face_mesh_result = analyze_face_mesh(image=image)
|
|
87
|
-
print(f"Detected {len(face_mesh_result.data)} face
|
|
92
|
+
print(f"Detected {len(face_mesh_result.data)} face(s)")
|
|
88
93
|
face_mesh_result.save_as_csv("face_landmarks.csv")
|
|
89
94
|
|
|
90
95
|
# Detect body pose (33 landmarks)
|
|
@@ -94,8 +99,7 @@ print(f"Body pose data: {body_pose_result.data}")
|
|
|
94
99
|
# Detect objects with YOLO
|
|
95
100
|
object_detection_result = detect_objects(
|
|
96
101
|
image=image,
|
|
97
|
-
accuracy_level=3
|
|
98
|
-
confidence=0.5
|
|
102
|
+
accuracy_level=3 # 1=nano, 2=small, 3=medium, 4=large, 5=extra-large
|
|
99
103
|
)
|
|
100
104
|
print(f"Detected {len(object_detection_result.data)} objects")
|
|
101
105
|
object_detection_result.save_as_img("detections.jpg")
|
|
@@ -103,7 +107,7 @@ object_detection_result.save_as_img("detections.jpg")
|
|
|
103
107
|
|
|
104
108
|
> **Note**: These are basic examples. Each module contains many more functions with extensive customization options. Explore the module-specific README files for detailed documentation.
|
|
105
109
|
|
|
106
|
-
##
|
|
110
|
+
## Documentation
|
|
107
111
|
|
|
108
112
|
Each module includes comprehensive documentation with detailed examples:
|
|
109
113
|
|
|
@@ -116,7 +120,7 @@ Each module includes comprehensive documentation with detailed examples:
|
|
|
116
120
|
|
|
117
121
|
For detailed project structure and development guidelines, see [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
|
|
118
122
|
|
|
119
|
-
##
|
|
123
|
+
## Architecture
|
|
120
124
|
|
|
121
125
|
ImagePRO is built with a modular architecture designed for extensibility and maintainability:
|
|
122
126
|
|
|
@@ -128,12 +132,27 @@ ImagePRO is built with a modular architecture designed for extensibility and mai
|
|
|
128
132
|
- **Documentation**: Google-style docstrings for all functions
|
|
129
133
|
|
|
130
134
|
### Key Design Principles
|
|
131
|
-
- **
|
|
135
|
+
- **Non-Destructive Operations**: Operations never write into the input image; they return results in new `Result` objects (note: `crop_image` returns a view into the source array)
|
|
132
136
|
- **Functional Style**: Stateless functions that can be easily composed
|
|
133
137
|
- **Result Objects**: Unified return type containing image, data, and metadata
|
|
134
138
|
- **Keyword Arguments**: All optional parameters use keyword-only syntax
|
|
135
139
|
|
|
136
|
-
##
|
|
140
|
+
## Testing
|
|
141
|
+
|
|
142
|
+
The test suite uses pytest:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Install with test tooling (editable install + dev extra)
|
|
146
|
+
pip install -e ".[dev]"
|
|
147
|
+
|
|
148
|
+
# Run the suite (optional heavy dependencies are mocked; base deps are enough)
|
|
149
|
+
pytest
|
|
150
|
+
|
|
151
|
+
# Include performance smoke guards
|
|
152
|
+
pytest --run-performance
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Contributing
|
|
137
156
|
|
|
138
157
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
139
158
|
|
|
@@ -141,9 +160,10 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
141
160
|
1. Fork the repository
|
|
142
161
|
2. Create a virtual environment: `python -m venv .venv`
|
|
143
162
|
3. Install dependencies: `pip install -r requirements/full.txt`
|
|
144
|
-
4.
|
|
145
|
-
5.
|
|
146
|
-
6.
|
|
163
|
+
4. Install for development with test tooling: `pip install -e ".[dev]"`
|
|
164
|
+
5. Follow the coding standards outlined in [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md)
|
|
165
|
+
6. Add tests for new features and run `pytest`
|
|
166
|
+
7. Update documentation as needed
|
|
147
167
|
|
|
148
168
|
### Reporting Issues
|
|
149
169
|
If you encounter any bugs or have feature requests, please open an issue on the GitHub repository with:
|
|
@@ -152,5 +172,5 @@ If you encounter any bugs or have feature requests, please open an issue on the
|
|
|
152
172
|
- Expected vs. actual behavior
|
|
153
173
|
- Environment details (OS, Python version, etc.)
|
|
154
174
|
|
|
155
|
-
##
|
|
175
|
+
## License
|
|
156
176
|
This project is licensed under the MIT License – see the [LICENSE](LICENSE) file for details.
|
|
@@ -15,7 +15,7 @@ Features:
|
|
|
15
15
|
- Real-time processing capabilities
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
__version__ = "1.
|
|
18
|
+
__version__ = "1.3.0"
|
|
19
19
|
__author__ = "Parsa Safaie"
|
|
20
20
|
__email__ = "parsasafaie.2568@proton.me"
|
|
21
21
|
|
|
@@ -27,7 +27,7 @@ from . import object_analysis
|
|
|
27
27
|
|
|
28
28
|
__all__ = [
|
|
29
29
|
"utils",
|
|
30
|
-
"pre_processing",
|
|
30
|
+
"pre_processing",
|
|
31
31
|
"human_analysis",
|
|
32
32
|
"object_analysis"
|
|
33
33
|
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Body Analysis Module
|
|
2
|
+
# Provides body pose estimation and hand tracking capabilities
|
|
3
|
+
#
|
|
4
|
+
# Both modules need the optional mediapipe dependency; they are imported
|
|
5
|
+
# guardedly so the package stays importable without it.
|
|
6
|
+
|
|
7
|
+
try: # requires mediapipe
|
|
8
|
+
from . import body_pose_estimation
|
|
9
|
+
except ImportError:
|
|
10
|
+
body_pose_estimation = None
|
|
11
|
+
|
|
12
|
+
try: # requires mediapipe
|
|
13
|
+
from . import hand_tracking
|
|
14
|
+
except ImportError:
|
|
15
|
+
hand_tracking = None
|
|
16
|
+
|
|
17
|
+
__all__ = ["body_pose_estimation", "hand_tracking"]
|
|
@@ -64,7 +64,7 @@ def detect_body_pose(
|
|
|
64
64
|
raise ValueError("'min_confidence' must be between 0.0 and 1.0")
|
|
65
65
|
|
|
66
66
|
if landmarks_idx is not None and (
|
|
67
|
-
not isinstance(landmarks_idx, list)
|
|
67
|
+
not isinstance(landmarks_idx, list)
|
|
68
68
|
or not all(isinstance(i, int) for i in landmarks_idx)
|
|
69
69
|
):
|
|
70
70
|
raise TypeError("'landmarks_idx' must be a list of integers")
|
|
@@ -97,7 +97,8 @@ def detect_body_pose(
|
|
|
97
97
|
img_copy,
|
|
98
98
|
result.pose_landmarks,
|
|
99
99
|
mp_pose.POSE_CONNECTIONS,
|
|
100
|
-
landmark_drawing_spec=mp.solutions.drawing_styles
|
|
100
|
+
landmark_drawing_spec=mp.solutions.drawing_styles
|
|
101
|
+
.get_default_pose_landmarks_style()
|
|
101
102
|
)
|
|
102
103
|
else:
|
|
103
104
|
# Draw only selected points
|
|
@@ -74,7 +74,7 @@ def detect_hands(
|
|
|
74
74
|
raise ValueError("'min_confidence' must be between 0.0 and 1.0")
|
|
75
75
|
|
|
76
76
|
if landmarks_idx is not None and (
|
|
77
|
-
not isinstance(landmarks_idx, list)
|
|
77
|
+
not isinstance(landmarks_idx, list)
|
|
78
78
|
or not all(isinstance(i, int) for i in landmarks_idx)
|
|
79
79
|
):
|
|
80
80
|
raise TypeError("'landmarks_idx' must be a list of integers")
|
|
@@ -109,8 +109,10 @@ def detect_hands(
|
|
|
109
109
|
image=img_copy,
|
|
110
110
|
landmark_list=hand_landmarks,
|
|
111
111
|
connections=mp_hands.HAND_CONNECTIONS,
|
|
112
|
-
landmark_drawing_spec=mp.solutions.drawing_styles
|
|
113
|
-
|
|
112
|
+
landmark_drawing_spec=mp.solutions.drawing_styles
|
|
113
|
+
.get_default_hand_landmarks_style(),
|
|
114
|
+
connection_drawing_spec=mp.solutions.drawing_styles
|
|
115
|
+
.get_default_hand_connections_style()
|
|
114
116
|
)
|
|
115
117
|
else:
|
|
116
118
|
# Draw only selected points
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Face Analysis Module
|
|
2
|
+
# Provides facial landmark detection, pose estimation, and eye status analysis
|
|
3
|
+
#
|
|
4
|
+
# The mediapipe-based modules and the insightface-based module are imported
|
|
5
|
+
# guardedly so that importing the package works with only the dependencies
|
|
6
|
+
# a caller actually needs; unavailable modules are set to None.
|
|
7
|
+
|
|
8
|
+
try: # requires mediapipe
|
|
9
|
+
from . import eye_status_analysis
|
|
10
|
+
except ImportError:
|
|
11
|
+
eye_status_analysis = None
|
|
12
|
+
|
|
13
|
+
try: # requires insightface
|
|
14
|
+
from . import face_comparison
|
|
15
|
+
except ImportError:
|
|
16
|
+
face_comparison = None
|
|
17
|
+
|
|
18
|
+
try: # requires mediapipe
|
|
19
|
+
from . import face_detection
|
|
20
|
+
except ImportError:
|
|
21
|
+
face_detection = None
|
|
22
|
+
|
|
23
|
+
try: # requires mediapipe
|
|
24
|
+
from . import face_mesh_analysis
|
|
25
|
+
except ImportError:
|
|
26
|
+
face_mesh_analysis = None
|
|
27
|
+
|
|
28
|
+
try: # requires mediapipe
|
|
29
|
+
from . import head_pose_estimation
|
|
30
|
+
except ImportError:
|
|
31
|
+
head_pose_estimation = None
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"eye_status_analysis",
|
|
35
|
+
"face_comparison",
|
|
36
|
+
"face_detection",
|
|
37
|
+
"face_mesh_analysis",
|
|
38
|
+
"head_pose_estimation"
|
|
39
|
+
]
|
|
@@ -85,8 +85,8 @@ def compare_faces(
|
|
|
85
85
|
|
|
86
86
|
try:
|
|
87
87
|
# Save images to disk if needed
|
|
88
|
-
path_1 = save_temp_image(image_1
|
|
89
|
-
path_2 = save_temp_image(image_2
|
|
88
|
+
path_1 = save_temp_image(image_1, 'tmp1.jpg')
|
|
89
|
+
path_2 = save_temp_image(image_2, 'tmp2.jpg')
|
|
90
90
|
|
|
91
91
|
# Load and preprocess images
|
|
92
92
|
img1 = load_rgb_image(path_1)
|
|
@@ -83,7 +83,7 @@ def analyze_face_mesh(
|
|
|
83
83
|
raise ValueError("'min_confidence' must be between 0 and 1")
|
|
84
84
|
|
|
85
85
|
if landmarks_idx is not None and (
|
|
86
|
-
not isinstance(landmarks_idx, list)
|
|
86
|
+
not isinstance(landmarks_idx, list)
|
|
87
87
|
or not all(isinstance(i, int) for i in landmarks_idx)
|
|
88
88
|
):
|
|
89
89
|
raise TypeError("'landmarks_idx' must be a list of integers")
|
|
@@ -99,11 +99,8 @@ def analyze_face_mesh(
|
|
|
99
99
|
else:
|
|
100
100
|
face_mesh = face_mesh_obj
|
|
101
101
|
|
|
102
|
-
#
|
|
103
|
-
|
|
104
|
-
img_rgb = cv2.cvtColor(img_copy, cv2.COLOR_BGR2RGB)
|
|
105
|
-
|
|
106
|
-
# Detect facial landmarks
|
|
102
|
+
# Detect facial landmarks (cvtColor allocates a new RGB array)
|
|
103
|
+
img_rgb = cv2.cvtColor(image._data, cv2.COLOR_BGR2RGB)
|
|
107
104
|
results = face_mesh.process(img_rgb)
|
|
108
105
|
|
|
109
106
|
# Handle no detections
|
|
@@ -121,11 +118,14 @@ def analyze_face_mesh(
|
|
|
121
118
|
}
|
|
122
119
|
)
|
|
123
120
|
|
|
121
|
+
# Allocate the annotation canvas only when a face was found
|
|
122
|
+
img_copy = image._data.copy()
|
|
123
|
+
|
|
124
124
|
# Use all landmarks if none specified
|
|
125
125
|
landmarks_idx = landmarks_idx or list(range(TOTAL_FACE_LANDMARKS))
|
|
126
126
|
# Process each detected face
|
|
127
127
|
landmarks = []
|
|
128
|
-
|
|
128
|
+
|
|
129
129
|
for face_id, face_landmarks in enumerate(results.multi_face_landmarks):
|
|
130
130
|
# Draw landmarks
|
|
131
131
|
if len(landmarks_idx) == TOTAL_FACE_LANDMARKS:
|
|
@@ -146,11 +146,10 @@ def analyze_face_mesh(
|
|
|
146
146
|
cv2.circle(img_copy, (cx, cy), 3, (0, 0, 255), -1)
|
|
147
147
|
|
|
148
148
|
# Extract coordinates
|
|
149
|
-
face_data = [
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
]
|
|
149
|
+
face_data = []
|
|
150
|
+
for idx in landmarks_idx:
|
|
151
|
+
lm = face_landmarks.landmark[idx]
|
|
152
|
+
face_data.append([face_id, idx, lm.x, lm.y, lm.z])
|
|
154
153
|
landmarks.append(face_data)
|
|
155
154
|
|
|
156
155
|
return Result(
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Object Analysis Module
|
|
2
|
+
# Provides object detection capabilities using YOLO models
|
|
3
|
+
|
|
4
|
+
try: # object_detection needs the optional ultralytics dependency
|
|
5
|
+
from . import object_detection
|
|
6
|
+
except ImportError:
|
|
7
|
+
object_detection = None
|
|
8
|
+
|
|
9
|
+
__all__ = ["object_detection"]
|
{imagepro_python-1.2.1 → imagepro_python-1.3.0}/src/ImagePRO/object_analysis/object_detection.py
RENAMED
|
@@ -16,10 +16,9 @@ from ImagePRO.utils.result import Result
|
|
|
16
16
|
|
|
17
17
|
# Constants
|
|
18
18
|
DEFAULT_ACCURACY_LEVEL = 1
|
|
19
|
-
DEFAULT_CONFIDENCE = 0.5
|
|
20
19
|
MODEL_MAPPING = {
|
|
21
20
|
1: "yolo11n.pt",
|
|
22
|
-
2: "yolo11s.pt",
|
|
21
|
+
2: "yolo11s.pt",
|
|
23
22
|
3: "yolo11m.pt",
|
|
24
23
|
4: "yolo11l.pt",
|
|
25
24
|
5: "yolo11x.pt"
|
|
@@ -56,6 +55,7 @@ def detect_objects(
|
|
|
56
55
|
Result object with detections and metadata:
|
|
57
56
|
- image: Original with bounding boxes drawn
|
|
58
57
|
- data: List of [class_id, [x1,y1,x2,y2], confidence]
|
|
58
|
+
with box coordinates normalized to [0, 1]
|
|
59
59
|
- meta: Operation info and model used
|
|
60
60
|
|
|
61
61
|
Raises:
|
|
@@ -73,12 +73,12 @@ def detect_objects(
|
|
|
73
73
|
f"'accuracy_level' must be in {list(MODEL_MAPPING.keys())}, "
|
|
74
74
|
f"got {accuracy_level}"
|
|
75
75
|
)
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
model_name = MODEL_MAPPING[accuracy_level]
|
|
78
78
|
model = YOLO(model=model_name)
|
|
79
79
|
|
|
80
|
-
# Run inference
|
|
81
|
-
result = model(image._data
|
|
80
|
+
# Run inference (ultralytics does not mutate the input array)
|
|
81
|
+
result = model(image._data)[0]
|
|
82
82
|
boxes = result.boxes
|
|
83
83
|
|
|
84
84
|
# Process detections
|
|
@@ -92,7 +92,7 @@ def detect_objects(
|
|
|
92
92
|
# Show visualization if requested
|
|
93
93
|
if show_result:
|
|
94
94
|
result.show()
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
return Result(
|
|
97
97
|
image=result.plot(),
|
|
98
98
|
data=detections,
|
|
@@ -4,15 +4,19 @@
|
|
|
4
4
|
from . import blur
|
|
5
5
|
from . import contrast
|
|
6
6
|
from . import crop
|
|
7
|
-
from . import dataset_generator
|
|
8
7
|
from . import grayscale
|
|
9
8
|
from . import resize
|
|
10
9
|
from . import rotate
|
|
11
10
|
from . import sharpen
|
|
12
11
|
|
|
12
|
+
try: # dataset_generator needs the optional mediapipe dependency
|
|
13
|
+
from . import dataset_generator
|
|
14
|
+
except ImportError:
|
|
15
|
+
dataset_generator = None
|
|
16
|
+
|
|
13
17
|
__all__ = [
|
|
14
18
|
"blur",
|
|
15
|
-
"contrast",
|
|
19
|
+
"contrast",
|
|
16
20
|
"crop",
|
|
17
21
|
"dataset_generator",
|
|
18
22
|
"grayscale",
|