ahmedxeno commited on
Commit
3ac0e79
·
verified ·
1 Parent(s): 5c01284

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -51
app.py CHANGED
@@ -11,76 +11,54 @@ from PIL import Image
11
  print("Gradio version:", gr.__version__)
12
 
13
  def musica_enhancement(image):
14
- """
15
- Enhances a 16-bit TIFF image using wavelet decomposition, CLAHE, gamma correction,
16
- and edge-preserving sharpening.
17
-
18
- Args:
19
- image (PIL.Image): Uploaded image.
20
-
21
- Returns:
22
- enhanced_image (PIL.Image): Enhanced image.
23
- histogram (PIL.Image): Histogram of the enhanced image.
24
- """
25
  # Convert PIL Image to numpy array
26
  img = np.array(image)
27
 
28
- # Handle different image modes
29
- if image.mode == 'I;16':
30
- # 16-bit image
31
- img = img.astype(np.uint16)
32
- img_norm = img.astype(np.float32) / 65535.0
33
- elif image.mode == 'I':
34
- # 32-bit integer image
35
- img = img.astype(np.int32)
36
- img_norm = img.astype(np.float32) / (2**32 - 1)
37
- elif image.mode in ['RGB', 'RGBA']:
38
- # Convert to grayscale if it's a color image
39
- img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
40
- img_norm = img.astype(np.float32) / 255.0
41
- elif image.mode == 'L':
42
- # 8-bit grayscale
43
- img_norm = img.astype(np.float32) / 255.0
44
- else:
45
- raise ValueError(f"Unsupported image mode: {image.mode}")
46
-
47
- # 1. Multi-Scale Decomposition (3-level wavelet transform)
48
  coeffs = pywt.wavedec2(img_norm, 'bior1.3', level=3)
49
  cA3, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1) = coeffs
50
-
51
- # 2. Adaptive Processing per Sub-band
52
  cD1 = pywt.threshold(cD1, 0.05 * np.max(cD1), mode='soft')
53
  cD2 = pywt.threshold(cD2, 0.07 * np.max(cD2), mode='soft')
54
  cH1 = cH1 * 1.2
55
  cV1 = cV1 * 1.2
56
-
57
- # 3. Reconstruct Enhanced Image with clipping
58
  coeffs_enhanced = [cA3, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1)]
59
  img_recon = pywt.waverec2(coeffs_enhanced, 'bior1.3')
60
- img_recon = np.clip(img_recon, 0, 1) # Critical fix
 
61
 
62
- # 4. Adaptive CLAHE
63
- entropy = -np.sum(img_recon * np.log2(img_recon + 1e-7)) # Now safe
64
- clip_limit = 0.02 if entropy > 7 else 0.05
65
- img_clahe = exposure.equalize_adapthist(img_recon, clip_limit=clip_limit, kernel_size=64)
66
 
67
- # 5. Gamma correction
68
- p5, p95 = np.percentile(img_clahe, (5, 95))
69
- gamma = 0.7 if (p95 - p5) < 0.3 else 0.9
70
- img_gamma = exposure.adjust_gamma(img_clahe, gamma=gamma)
71
 
72
- # 6. Edge-Preserving Sharpening (convert to BGR first)
73
  img_gamma_8bit = (img_gamma * 255).astype(np.uint8)
74
- img_bgr = cv2.cvtColor(img_gamma_8bit, cv2.COLOR_GRAY2BGR) # Convert to 3-channel
75
- img_sharp = cv2.detailEnhance(img_bgr, sigma_s=12, sigma_r=0.15)
76
- img_sharp = cv2.cvtColor(img_sharp, cv2.COLOR_BGR2GRAY) # Convert back to grayscale
77
 
78
- # Convert enhanced image to PIL Image
79
- enhanced_image = Image.fromarray(img_sharp)
 
80
 
81
  # Create histogram plot
82
  plt.figure(figsize=(6, 4))
83
- plt.hist(img_sharp.ravel(), bins=256, range=(0, 255), color='gray')
84
  plt.title('Enhanced Histogram')
85
  plt.xlabel('Pixel Intensity')
86
  plt.ylabel('Frequency')
@@ -93,6 +71,7 @@ def musica_enhancement(image):
93
 
94
  return enhanced_image, histogram
95
 
 
96
  # Define Gradio interface
97
  with gr.Blocks() as demo:
98
  gr.Markdown("# Musica Image Enhancement")
 
11
  print("Gradio version:", gr.__version__)
12
 
13
  def musica_enhancement(image):
 
 
 
 
 
 
 
 
 
 
 
14
  # Convert PIL Image to numpy array
15
  img = np.array(image)
16
 
17
+ # Debugging: Print image properties
18
+ print(f"Uploaded image shape: {img.shape}, dtype: {img.dtype}")
19
+ print(f"Image min: {img.min()}, max: {img.max()}")
20
+
21
+ # Check if the image is grayscale
22
+ if len(img.shape) != 2:
23
+ raise ValueError("Uploaded image must be a grayscale image.")
24
+
25
+ # Ensure the image has 16-bit depth
26
+ if img.dtype != np.uint16:
27
+ raise ValueError("Uploaded image must be a 16-bit TIFF image.")
28
+
29
+ # Normalize to [0, 1]
30
+ img_norm = img.astype(np.float32) / 65535.0
31
+ print(f"Normalized image min: {img_norm.min()}, max: {img_norm.max()}")
32
+
33
+ # Wavelet decomposition and reconstruction
 
 
 
34
  coeffs = pywt.wavedec2(img_norm, 'bior1.3', level=3)
35
  cA3, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1) = coeffs
 
 
36
  cD1 = pywt.threshold(cD1, 0.05 * np.max(cD1), mode='soft')
37
  cD2 = pywt.threshold(cD2, 0.07 * np.max(cD2), mode='soft')
38
  cH1 = cH1 * 1.2
39
  cV1 = cV1 * 1.2
 
 
40
  coeffs_enhanced = [cA3, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1)]
41
  img_recon = pywt.waverec2(coeffs_enhanced, 'bior1.3')
42
+ img_recon = np.clip(img_recon, 0, 1)
43
+ print(f"Reconstructed image min: {img_recon.min()}, max: {img_recon.max()}")
44
 
45
+ # CLAHE
46
+ img_clahe = exposure.equalize_adapthist(img_recon, clip_limit=0.02, kernel_size=64)
 
 
47
 
48
+ # Gamma correction
49
+ img_gamma = exposure.adjust_gamma(img_clahe, gamma=0.9)
 
 
50
 
51
+ # Convert to 8-bit
52
  img_gamma_8bit = (img_gamma * 255).astype(np.uint8)
53
+ print(f"Final image min: {img_gamma_8bit.min()}, max: {img_gamma_8bit.max()}")
 
 
54
 
55
+ # Convert to RGB for better viewing compatibility
56
+ img_rgb = cv2.cvtColor(img_gamma_8bit, cv2.COLOR_GRAY2RGB)
57
+ enhanced_image = Image.fromarray(img_rgb)
58
 
59
  # Create histogram plot
60
  plt.figure(figsize=(6, 4))
61
+ plt.hist(img_gamma_8bit.ravel(), bins=256, range=(0, 255), color='gray')
62
  plt.title('Enhanced Histogram')
63
  plt.xlabel('Pixel Intensity')
64
  plt.ylabel('Frequency')
 
71
 
72
  return enhanced_image, histogram
73
 
74
+
75
  # Define Gradio interface
76
  with gr.Blocks() as demo:
77
  gr.Markdown("# Musica Image Enhancement")