image-enhancer-ai 1.0.1__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.
@@ -0,0 +1,5 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted...
@@ -0,0 +1,11 @@
1
+ include README.md
2
+ include LICENSE
3
+ recursive-include image_enhancer *.json
4
+ recursive-include image_enhancer *.yaml
5
+ recursive-include image_enhancer *.yml
6
+ recursive-include image_enhancer *.txt
7
+ recursive-include image_enhancer *.h5
8
+ recursive-include image_enhancer *.keras
9
+ recursive-include image_enhancer *.pkl
10
+ recursive-include image_enhancer *.jpg
11
+ recursive-include image_enhancer *.png
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: image-enhancer-ai
3
+ Version: 1.0.1
4
+ Summary: Reusable AI Image Enhancement Package
5
+ Author-email: Punsara Wikramarathna <punsarawikramarathna@gmail.com>
6
+ License: MIT
7
+ Keywords: image enhancement,opencv,computer vision,image processing,tensorflow,ai
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: opencv-python
15
+ Requires-Dist: numpy
16
+ Requires-Dist: tensorflow
17
+ Requires-Dist: scikit-image
18
+ Requires-Dist: PyYAML
19
+ Dynamic: license-file
20
+
21
+ # Image Enhancer
22
+
23
+ A reusable AI-powered image enhancement package.
24
+
25
+ ## Features
26
+
27
+ - Major Rotation Correction (CNN)
28
+ - Minor Rotation Correction
29
+ - Blur Detection and Correction
30
+ - Noise Reduction
31
+ - Brightness Enhancement
32
+ - Contrast Enhancement
33
+ - Quality Evaluation
34
+ - Iterative Enhancement
35
+ - Configuration Support
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install image-enhancer-punsara99
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ```python
46
+ from image_enhancer import ImageEnhancer
47
+
48
+ engine = ImageEnhancer()
49
+
50
+ output, report = engine.process("input.jpg")
51
+
52
+ engine.save(output, "output.jpg")
53
+
54
+ engine.print_report(report)
55
+ ```
56
+
57
+ ## License
58
+
59
+ MIT
@@ -0,0 +1,39 @@
1
+ # Image Enhancer
2
+
3
+ A reusable AI-powered image enhancement package.
4
+
5
+ ## Features
6
+
7
+ - Major Rotation Correction (CNN)
8
+ - Minor Rotation Correction
9
+ - Blur Detection and Correction
10
+ - Noise Reduction
11
+ - Brightness Enhancement
12
+ - Contrast Enhancement
13
+ - Quality Evaluation
14
+ - Iterative Enhancement
15
+ - Configuration Support
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install image-enhancer-punsara99
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```python
26
+ from image_enhancer import ImageEnhancer
27
+
28
+ engine = ImageEnhancer()
29
+
30
+ output, report = engine.process("input.jpg")
31
+
32
+ engine.save(output, "output.jpg")
33
+
34
+ engine.print_report(report)
35
+ ```
36
+
37
+ ## License
38
+
39
+ MIT
@@ -0,0 +1 @@
1
+ from .enhancer import ImageEnhancer
File without changes
@@ -0,0 +1,390 @@
1
+ import cv2
2
+ import os
3
+
4
+ from config.config_loader import load_config
5
+
6
+ from utils.blur_module import (
7
+ detect_blur,
8
+ fix_blur
9
+ )
10
+
11
+ from utils.noise_module import (
12
+ remove_noise
13
+ )
14
+
15
+ from utils.brightness_module import (
16
+ enhance_brightness_contrast
17
+ )
18
+
19
+ from utils.quality_module import (
20
+ quality_score
21
+ )
22
+
23
+ from utils.rotation_module import (
24
+ detect_minor_rotation,
25
+ correct_minor_rotation,
26
+ rotation_direction,
27
+ rotation_level
28
+ )
29
+
30
+ from training.predict_rotation import predict_rotation
31
+
32
+ from utils.quality_metrics import (
33
+ improvement,
34
+ quality_report
35
+ )
36
+
37
+
38
+ # ==========================================================
39
+ # Major Rotation Correction
40
+ # ==========================================================
41
+
42
+ def fix_rotation(image, angle):
43
+
44
+ angle = int(float(angle))
45
+
46
+ if angle == 90:
47
+ return cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
48
+
49
+ elif angle == 180:
50
+ return cv2.rotate(image, cv2.ROTATE_180)
51
+
52
+ elif angle == 270:
53
+ return cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
54
+
55
+ return image
56
+
57
+
58
+ # ==========================================================
59
+ # Configuration Helper
60
+ # ==========================================================
61
+
62
+ def _enabled(config, section):
63
+
64
+ value = config.get(section, {})
65
+
66
+ if isinstance(value, dict):
67
+ return value.get("enabled", False)
68
+
69
+ return bool(value)
70
+
71
+
72
+ # ==========================================================
73
+ # Run One Enhancement Cycle
74
+ # ==========================================================
75
+
76
+ def run_pipeline(image, config):
77
+
78
+ report = []
79
+
80
+ output = image.copy()
81
+
82
+ # ---------------------------------------
83
+ # Blur
84
+ # ---------------------------------------
85
+
86
+ if _enabled(config, "blur"):
87
+
88
+ blur_score = detect_blur(output)
89
+
90
+ output, _, blur_level, motion, _ = fix_blur(output)
91
+
92
+ report.append(f"Blur Score : {blur_score:.2f}")
93
+ report.append(f"Blur Level : {blur_level}")
94
+ report.append(f"Motion Blur : {motion}")
95
+
96
+ # ---------------------------------------
97
+ # Noise
98
+ # ---------------------------------------
99
+
100
+ if _enabled(config, "noise"):
101
+
102
+ output, noise_score, noise_level, noise_type = remove_noise(output)
103
+
104
+ report.append(f"Noise Score : {noise_score:.2f}")
105
+ report.append(f"Noise Level : {noise_level}")
106
+ report.append(f"Noise Type : {noise_type}")
107
+
108
+ # ---------------------------------------
109
+ # Brightness
110
+ # ---------------------------------------
111
+
112
+ if _enabled(config, "brightness"):
113
+
114
+ output, brightness, b_level, contrast, c_level = \
115
+ enhance_brightness_contrast(output)
116
+
117
+ report.append(f"Brightness : {brightness:.2f}")
118
+ report.append(f"Brightness Level : {b_level}")
119
+
120
+ report.append(f"Contrast : {contrast:.2f}")
121
+ report.append(f"Contrast Level : {c_level}")
122
+
123
+ return output, report
124
+
125
+ # ==========================================================
126
+ # Image Enhancement Engine
127
+ # ==========================================================
128
+
129
+ def enhance_image(image):
130
+
131
+ if image is None:
132
+ raise ValueError("Invalid image.")
133
+
134
+ config = load_config()
135
+
136
+ os.makedirs("output", exist_ok=True)
137
+
138
+ original = image.copy()
139
+ output = image.copy()
140
+
141
+ report = []
142
+
143
+ # ---------------------------------------------
144
+ # Track whether image orientation changed
145
+ # ---------------------------------------------
146
+
147
+ rotation_changed = False
148
+
149
+ # =====================================================
150
+ # Major Rotation
151
+ # =====================================================
152
+
153
+ if _enabled(config, "rotation"):
154
+
155
+ angle, confidence = predict_rotation(output)
156
+
157
+ report.append(f"Major Rotation : {angle}")
158
+ report.append(f"Confidence : {confidence:.3f}")
159
+
160
+ threshold = config["rotation"]["confidence_threshold"]
161
+
162
+ if confidence >= threshold and angle != 0:
163
+
164
+ output = fix_rotation(output, angle)
165
+
166
+ rotation_changed = True
167
+
168
+ report.append("Major Rotation Fixed")
169
+
170
+ elif angle == 0:
171
+
172
+ report.append("No Rotation Needed")
173
+
174
+ else:
175
+
176
+ report.append("Rotation Ignored (Low Confidence)")
177
+
178
+ # =====================================================
179
+ # Minor Rotation
180
+ # =====================================================
181
+
182
+ if _enabled(config, "minor_rotation"):
183
+
184
+ minor_angle = detect_minor_rotation(output)
185
+
186
+ direction = rotation_direction(minor_angle)
187
+
188
+ level = rotation_level(minor_angle)
189
+
190
+ report.append(f"Minor Rotation : {minor_angle:.2f}")
191
+ report.append(f"Direction : {direction}")
192
+ report.append(f"Rotation Level : {level}")
193
+
194
+ if abs(minor_angle) > 2:
195
+
196
+ output = correct_minor_rotation(output, minor_angle)
197
+
198
+ rotation_changed = True
199
+
200
+ report.append("Minor Rotation Fixed")
201
+
202
+ # Save rotation result
203
+
204
+ if _enabled(config, "save_steps"):
205
+
206
+ cv2.imwrite("output/1_rotation.jpg", output)
207
+
208
+ # =====================================================
209
+ # Iterative Enhancement
210
+ # =====================================================
211
+
212
+ iteration_cfg = config["iteration"]
213
+
214
+ max_iterations = iteration_cfg["max_iterations"]
215
+
216
+ target_quality = iteration_cfg["quality_threshold"]
217
+
218
+ best_quality = -1
219
+
220
+ best_output = output.copy()
221
+
222
+ best_iteration = 0
223
+
224
+ # =====================================================
225
+ # Enhancement Loop
226
+ # =====================================================
227
+
228
+ if iteration_cfg["enabled"]:
229
+
230
+ for i in range(max_iterations):
231
+
232
+ report.append("")
233
+ report.append(f"========== Iteration {i+1} ==========")
234
+
235
+ output, temp_report = run_pipeline(output, config)
236
+
237
+ report.extend(temp_report)
238
+
239
+ current_quality, grade = quality_score(output)
240
+
241
+ report.append(f"Current Quality : {current_quality:.2f}")
242
+
243
+ # Save intermediate image
244
+
245
+ if _enabled(config, "save_steps"):
246
+
247
+ cv2.imwrite(
248
+ f"output/iteration_{i+1}.jpg",
249
+ output
250
+ )
251
+
252
+ # Keep the best result
253
+
254
+ # -----------------------------------------
255
+ # Keep the Best Result
256
+ # -----------------------------------------
257
+
258
+ if current_quality > best_quality:
259
+
260
+ best_quality = current_quality
261
+ best_output = output.copy()
262
+ best_iteration = i + 1
263
+
264
+ else:
265
+
266
+ report.append("Quality decreased.")
267
+ report.append("Stopping iterations.")
268
+
269
+ break
270
+
271
+ # Stop if target reached
272
+
273
+ if current_quality >= target_quality:
274
+
275
+ report.append("Target Quality Reached")
276
+
277
+ break
278
+
279
+ # Use the best enhanced image
280
+
281
+ output = best_output.copy()
282
+
283
+ final_quality = best_quality
284
+
285
+ # =====================================================
286
+ # Final Quality
287
+ # =====================================================
288
+
289
+ report.append("")
290
+ report.append("==============================")
291
+ report.append(" FINAL IMAGE QUALITY ")
292
+ report.append("==============================")
293
+
294
+ report.append(f"Quality Score : {final_quality:.2f}")
295
+
296
+ _, grade = quality_score(output)
297
+
298
+ report.append(f"Quality Grade : {grade}")
299
+
300
+ report.append(f"Iterations Used : {best_iteration}")
301
+
302
+ report.append(f"Target Quality : {target_quality}")
303
+
304
+ # =====================================================
305
+ # Quality Metrics
306
+ # =====================================================
307
+
308
+ report.append("")
309
+ report.append("==============================")
310
+ report.append(" QUALITY METRICS ")
311
+ report.append("==============================")
312
+
313
+ if rotation_changed:
314
+
315
+ report.append("Skipped")
316
+ report.append(
317
+ "Reason : Image orientation changed after rotation correction."
318
+ )
319
+ report.append(
320
+ "PSNR/SSIM require identical image orientation."
321
+ )
322
+
323
+ else:
324
+
325
+ metrics = quality_report(original, output)
326
+
327
+ report.append(f"MSE : {metrics['mse']:.2f}")
328
+ report.append(f"PSNR : {metrics['psnr']:.2f} dB")
329
+ report.append(f"SSIM : {metrics['ssim']:.4f}")
330
+ report.append(f"Image Quality : {metrics['grade']}")
331
+
332
+ # =====================================================
333
+ # Improvement Report
334
+ # =====================================================
335
+
336
+ report.append("")
337
+ report.append("==============================")
338
+ report.append(" IMPROVEMENT REPORT ")
339
+ report.append("==============================")
340
+
341
+ before, after, gain = improvement(original, output)
342
+
343
+ report.append(f"Before Quality : {before:.2f}")
344
+ report.append(f"After Quality : {after:.2f}")
345
+
346
+ if gain >= 0:
347
+
348
+ report.append(f"Improvement : +{gain:.2f}")
349
+
350
+ else:
351
+
352
+ report.append(f"Improvement : {gain:.2f}")
353
+
354
+ # =====================================================
355
+ # Save Final Image
356
+ # =====================================================
357
+
358
+ if _enabled(config, "save_steps"):
359
+
360
+ cv2.imwrite("output/6_final.jpg", output)
361
+
362
+ # =====================================================
363
+ # Completion Summary
364
+ # =====================================================
365
+
366
+ report.append("")
367
+ report.append("========================================")
368
+ report.append(" Image Enhancement Completed ")
369
+ report.append("========================================")
370
+
371
+ report.append(f"Quality Score : {final_quality:.2f}")
372
+ report.append(f"Iterations Used : {best_iteration}")
373
+ report.append("")
374
+ report.append("Module Status")
375
+ report.append("---------------------------")
376
+
377
+ report.append("[OK] Rotation")
378
+ report.append("[OK] Blur")
379
+ report.append("[OK] Noise")
380
+ report.append("[OK] Brightness")
381
+ report.append("[OK] Quality")
382
+
383
+ report.append("")
384
+ report.append("Output Saved Successfully")
385
+
386
+ # =====================================================
387
+ # Return
388
+ # =====================================================
389
+
390
+ return output, report
@@ -0,0 +1,109 @@
1
+ import cv2
2
+ import os
3
+ from config.config_loader import load_config
4
+ from .enhance_engine import enhance_image
5
+
6
+
7
+ class ImageEnhancer:
8
+
9
+ def __init__(self):
10
+
11
+ self.config = load_config()
12
+
13
+ print("Image Enhancer Initialized")
14
+
15
+ # -----------------------------------------
16
+ # Show Current Configuration
17
+ # -----------------------------------------
18
+
19
+ def show_configuration(self):
20
+
21
+ print("\n========== CURRENT CONFIGURATION ==========\n")
22
+
23
+ for key, value in self.config.items():
24
+
25
+ print(f"{key} : {value}")
26
+
27
+ print()
28
+
29
+ # -----------------------------------------
30
+ # Process Image
31
+ # -----------------------------------------
32
+
33
+ def process(self, image_path):
34
+
35
+ image = cv2.imread(image_path)
36
+
37
+ if image is None:
38
+ raise FileNotFoundError(image_path)
39
+
40
+ output, report = enhance_image(image)
41
+
42
+ return output, report
43
+
44
+ # -----------------------------------------
45
+ # Save Image
46
+ # -----------------------------------------
47
+
48
+ def process_and_save(self, image_path, output_path="output/final.jpg"):
49
+
50
+ output, report = self.process(image_path)
51
+
52
+ cv2.imwrite(output_path, output)
53
+
54
+ return report
55
+
56
+ # -----------------------------------------
57
+ # Save Image
58
+ # -----------------------------------------
59
+
60
+ def save(self, image, output_path):
61
+
62
+
63
+
64
+ folder = os.path.dirname(output_path)
65
+
66
+ if folder != "":
67
+ os.makedirs(folder, exist_ok=True)
68
+
69
+ cv2.imwrite(output_path, image)
70
+
71
+ print(f"Image saved to {output_path}")
72
+ # -----------------------------------------
73
+ # Print Report
74
+ # -----------------------------------------
75
+
76
+ def print_report(self, report):
77
+
78
+ print("\n========== REPORT ==========\n")
79
+
80
+ for line in report:
81
+ print(line)
82
+
83
+
84
+ # -----------------------------------------
85
+ # Batch Processing
86
+ # -----------------------------------------
87
+
88
+ def process_folder(self, input_folder, output_folder="output/results"):
89
+
90
+ import os
91
+
92
+ os.makedirs(output_folder, exist_ok=True)
93
+
94
+ for file in os.listdir(input_folder):
95
+
96
+ path = os.path.join(input_folder, file)
97
+
98
+ if not os.path.isfile(path):
99
+ continue
100
+
101
+ output, report = self.process(path)
102
+
103
+ save_path = os.path.join(output_folder, file)
104
+
105
+ cv2.imwrite(save_path, output)
106
+
107
+ print(file, "Completed")
108
+
109
+ print("\nBatch Processing Finished")
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: image-enhancer-ai
3
+ Version: 1.0.1
4
+ Summary: Reusable AI Image Enhancement Package
5
+ Author-email: Punsara Wikramarathna <punsarawikramarathna@gmail.com>
6
+ License: MIT
7
+ Keywords: image enhancement,opencv,computer vision,image processing,tensorflow,ai
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: opencv-python
15
+ Requires-Dist: numpy
16
+ Requires-Dist: tensorflow
17
+ Requires-Dist: scikit-image
18
+ Requires-Dist: PyYAML
19
+ Dynamic: license-file
20
+
21
+ # Image Enhancer
22
+
23
+ A reusable AI-powered image enhancement package.
24
+
25
+ ## Features
26
+
27
+ - Major Rotation Correction (CNN)
28
+ - Minor Rotation Correction
29
+ - Blur Detection and Correction
30
+ - Noise Reduction
31
+ - Brightness Enhancement
32
+ - Contrast Enhancement
33
+ - Quality Evaluation
34
+ - Iterative Enhancement
35
+ - Configuration Support
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install image-enhancer-punsara99
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ```python
46
+ from image_enhancer import ImageEnhancer
47
+
48
+ engine = ImageEnhancer()
49
+
50
+ output, report = engine.process("input.jpg")
51
+
52
+ engine.save(output, "output.jpg")
53
+
54
+ engine.print_report(report)
55
+ ```
56
+
57
+ ## License
58
+
59
+ MIT
@@ -0,0 +1,18 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ image_enhancer/__init__.py
6
+ image_enhancer/config.py
7
+ image_enhancer/enhance_engine.py
8
+ image_enhancer/enhancer.py
9
+ image_enhancer_ai.egg-info/PKG-INFO
10
+ image_enhancer_ai.egg-info/SOURCES.txt
11
+ image_enhancer_ai.egg-info/dependency_links.txt
12
+ image_enhancer_ai.egg-info/requires.txt
13
+ image_enhancer_ai.egg-info/top_level.txt
14
+ tests/test_blur.py
15
+ tests/test_noise.py
16
+ tests/test_quality.py
17
+ tests/test_quality_metrics.py
18
+ tests/test_rotation.py
@@ -0,0 +1,5 @@
1
+ opencv-python
2
+ numpy
3
+ tensorflow
4
+ scikit-image
5
+ PyYAML
@@ -0,0 +1 @@
1
+ image_enhancer
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=65", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "image-enhancer-ai"
7
+ version = "1.0.1"
8
+
9
+ description = "Reusable AI Image Enhancement Package"
10
+
11
+ readme = "README.md"
12
+
13
+ requires-python = ">=3.9"
14
+
15
+ license = { text = "MIT" }
16
+
17
+ authors = [
18
+ { name = "Punsara Wikramarathna", email = "punsarawikramarathna@gmail.com" }
19
+ ]
20
+
21
+ keywords = [
22
+ "image enhancement",
23
+ "opencv",
24
+ "computer vision",
25
+ "image processing",
26
+ "tensorflow",
27
+ "ai"
28
+ ]
29
+
30
+ classifiers = [
31
+ "Programming Language :: Python :: 3",
32
+ "License :: OSI Approved :: MIT License",
33
+ "Operating System :: OS Independent"
34
+ ]
35
+
36
+ dependencies = [
37
+ "opencv-python",
38
+ "numpy",
39
+ "tensorflow",
40
+ "scikit-image",
41
+ "PyYAML"
42
+ ]
43
+
44
+ [tool.setuptools]
45
+ include-package-data = true
46
+
47
+ [tool.setuptools.packages.find]
48
+ include = ["image_enhancer*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,19 @@
1
+ import cv2
2
+
3
+ from utils.blur_module import *
4
+
5
+ img = cv2.imread("input/test.png")
6
+
7
+ output,score,level,motion,confidence=fix_blur(img)
8
+
9
+ print("\n========== BLUR REPORT ==========\n")
10
+
11
+ print("Blur Score :",round(score,2))
12
+
13
+ print("Blur Level :",level)
14
+
15
+ print("Motion Blur :",motion)
16
+
17
+ print("Confidence :",confidence)
18
+
19
+ cv2.imwrite("../output/test_blur.jpg",output)
File without changes
File without changes
@@ -0,0 +1,27 @@
1
+ import cv2
2
+
3
+ from utils.quality_metrics import *
4
+
5
+ original = cv2.imread("input/test.png")
6
+
7
+ enhanced = cv2.imread("output/6_final.jpg")
8
+
9
+ report = quality_report(original, enhanced)
10
+
11
+ print()
12
+
13
+ print("==============================")
14
+
15
+ print(" IMAGE QUALITY REPORT ")
16
+
17
+ print("==============================")
18
+
19
+ print("MSE :", round(report["mse"],2))
20
+
21
+ print("PSNR :", round(report["psnr"],2),"dB")
22
+
23
+ print("SSIM :", round(report["ssim"],4))
24
+
25
+ print("Grade :", report["grade"])
26
+
27
+ print("==============================")
@@ -0,0 +1,13 @@
1
+ import cv2
2
+
3
+ from utils.rotation_module import detect_minor_rotation, rotate_image
4
+
5
+ img=cv2.imread("input/test.png")
6
+
7
+ angle=detect_minor_rotation(img)
8
+
9
+ print("Detected Angle :",round(angle,2))
10
+
11
+ corrected=rotate_image(img,angle)
12
+
13
+ cv2.imwrite("output/minor_rotation.jpg",corrected)