selva1909 commited on
Commit
6860cad
Β·
verified Β·
1 Parent(s): 1fc154e

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +190 -0
  2. image_denoising_autoencoder.h5 +3 -0
app.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ # Silence TF logs
4
+ os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", "2")
5
+ os.environ.setdefault("TF_ENABLE_ONEDNN_OPTS", "0")
6
+
7
+ import gradio as gr
8
+ import numpy as np
9
+ import cv2
10
+ from tensorflow.keras.models import load_model
11
+ from skimage.metrics import structural_similarity as ssim
12
+
13
+ # =======================
14
+ # Load trained model
15
+ # =======================
16
+ MODEL_PATH = "image_denoising_autoencoder.h5"
17
+ model = load_model(MODEL_PATH, compile=False)
18
+
19
+ # =======================
20
+ # Utility Functions
21
+ # =======================
22
+ def preprocess_gray(image):
23
+ image = cv2.resize(image, (128, 128))
24
+ image = image.astype("float32") / 255.0
25
+ return image.reshape(128, 128, 1)
26
+
27
+ def add_noise(image, noise_factor):
28
+ noisy = image + noise_factor * np.random.normal(
29
+ loc=0.0, scale=1.0, size=image.shape
30
+ )
31
+ return np.clip(noisy, 0.0, 1.0)
32
+
33
+ def psnr(original, denoised):
34
+ mse = np.mean((original - denoised) ** 2)
35
+ if mse == 0:
36
+ return 100
37
+ return 10 * np.log10(1.0 / mse)
38
+
39
+ def interpret_psnr(value):
40
+ if value < 15:
41
+ return "Poor ❌"
42
+ elif value < 25:
43
+ return "Moderate ⚠️"
44
+ else:
45
+ return "Good βœ…"
46
+
47
+ def interpret_ssim(value):
48
+ if value < 0.5:
49
+ return "Low ❌"
50
+ elif value < 0.8:
51
+ return "Moderate ⚠️"
52
+ else:
53
+ return "High βœ…"
54
+
55
+ # =======================
56
+ # πŸ”₯ POST-PROCESSING
57
+ # =======================
58
+ def enhance_clarity(image, strength=1.0):
59
+ image_uint8 = (image * 255).astype(np.uint8)
60
+ blurred = cv2.GaussianBlur(image_uint8, (5, 5), 0)
61
+ sharpened = cv2.addWeighted(
62
+ image_uint8, 1 + strength, blurred, -strength, 0
63
+ )
64
+ return np.clip(sharpened.astype("float32") / 255.0, 0, 1)
65
+
66
+ # =======================
67
+ # Inference Function
68
+ # =======================
69
+ def denoise_image(input_image, noise_level, mode, clarity_strength):
70
+ if input_image is None:
71
+ return None, None, None, "Upload an image to start."
72
+
73
+ # -------- Grayscale --------
74
+ if mode == "Grayscale":
75
+ if input_image.ndim == 3:
76
+ gray = cv2.cvtColor(input_image, cv2.COLOR_RGB2GRAY)
77
+ else:
78
+ gray = input_image
79
+
80
+ clean = preprocess_gray(gray)
81
+ noisy = add_noise(clean, noise_level)
82
+ denoised = model.predict(noisy.reshape(1, 128, 128, 1))[0]
83
+
84
+ enhanced = enhance_clarity(
85
+ denoised.reshape(128, 128),
86
+ strength=clarity_strength
87
+ )
88
+
89
+ psnr_val = psnr(clean.reshape(128, 128), denoised.reshape(128, 128))
90
+ ssim_val = ssim(
91
+ clean.reshape(128, 128),
92
+ denoised.reshape(128, 128),
93
+ data_range=1.0
94
+ )
95
+
96
+ metrics = (
97
+ f"PSNR: {psnr_val:.2f} dB ({interpret_psnr(psnr_val)})\n"
98
+ f"SSIM: {ssim_val:.3f} ({interpret_ssim(ssim_val)})\n"
99
+ f"Clarity Strength: {clarity_strength:.2f}"
100
+ )
101
+
102
+ return (
103
+ clean.reshape(128, 128),
104
+ noisy.reshape(128, 128),
105
+ enhanced,
106
+ metrics
107
+ )
108
+
109
+ # -------- RGB --------
110
+ resized = cv2.resize(input_image, (128, 128))
111
+ resized = resized.astype("float32") / 255.0
112
+
113
+ noisy_rgb = add_noise(resized, noise_level)
114
+ denoised_rgb = np.zeros_like(noisy_rgb)
115
+
116
+ for c in range(3):
117
+ channel = noisy_rgb[:, :, c].reshape(128, 128, 1)
118
+ denoised_rgb[:, :, c] = model.predict(
119
+ channel.reshape(1, 128, 128, 1)
120
+ )[0].reshape(128, 128)
121
+
122
+ enhanced_rgb = np.zeros_like(denoised_rgb)
123
+ for c in range(3):
124
+ enhanced_rgb[:, :, c] = enhance_clarity(
125
+ denoised_rgb[:, :, c],
126
+ strength=clarity_strength
127
+ )
128
+
129
+ psnr_val = psnr(resized, denoised_rgb)
130
+ ssim_val = ssim(
131
+ resized,
132
+ denoised_rgb,
133
+ channel_axis=2,
134
+ data_range=1.0
135
+ )
136
+
137
+ metrics = (
138
+ f"PSNR: {psnr_val:.2f} dB ({interpret_psnr(psnr_val)})\n"
139
+ f"SSIM: {ssim_val:.3f} ({interpret_ssim(ssim_val)})\n"
140
+ f"Clarity Strength: {clarity_strength:.2f}"
141
+ )
142
+
143
+ return resized, noisy_rgb, enhanced_rgb, metrics
144
+
145
+ # =======================
146
+ # Gradio UI
147
+ # =======================
148
+ with gr.Blocks(title="Image Denoising Autoencoder") as demo:
149
+ gr.Markdown(
150
+ """
151
+ # 🧠 Image Denoising using U-Net Autoencoder
152
+ 🎚 Sliders update output automatically
153
+ """
154
+ )
155
+
156
+ with gr.Row():
157
+ input_image = gr.Image(label="Upload Image", type="numpy", height=320)
158
+
159
+ with gr.Column():
160
+ noise_slider = gr.Slider(0.05, 0.5, 0.3, 0.05, label="Noise Level")
161
+ clarity_slider = gr.Slider(0.0, 2.0, 1.0, 0.1, label="Clarity Strength")
162
+ mode_selector = gr.Radio(
163
+ ["Grayscale", "RGB"], value="Grayscale", label="Mode"
164
+ )
165
+
166
+ denoise_btn = gr.Button("Denoise Image πŸš€")
167
+
168
+ with gr.Row():
169
+ original_out = gr.Image(label="Original", height=260)
170
+ noisy_out = gr.Image(label="Noisy", height=260)
171
+ denoised_out = gr.Image(label="Denoised", height=260)
172
+
173
+ metrics_box = gr.Textbox(label="Quality Metrics", lines=4)
174
+
175
+ inputs = [input_image, noise_slider, mode_selector, clarity_slider]
176
+ outputs = [original_out, noisy_out, denoised_out, metrics_box]
177
+
178
+ # πŸ” AUTO UPDATE
179
+ noise_slider.change(denoise_image, inputs, outputs)
180
+ clarity_slider.change(denoise_image, inputs, outputs)
181
+ mode_selector.change(denoise_image, inputs, outputs)
182
+
183
+ # πŸ”˜ MANUAL BUTTON
184
+ denoise_btn.click(denoise_image, inputs, outputs)
185
+
186
+ # =======================
187
+ # Launch App
188
+ # =======================
189
+ if __name__ == "__main__":
190
+ demo.launch(debug=True)
image_denoising_autoencoder.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3209805b004092354c8ffbafea7a2dd2ec8cdbe39f577a46247844829ac416a0
3
+ size 22675608