kaopanboonyuen commited on
Commit
a3a0b9d
·
1 Parent(s): d2993c9

🔥 update Otsu to app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -3
app.py CHANGED
@@ -5,18 +5,96 @@ import os
5
  # -----------------------------
6
  # UI-safe mock (no GPU crash)
7
  # -----------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  def inpaint(image, mask, prompt):
9
  """
10
- Prototype UI function (model will be added later)
 
11
  """
 
 
 
12
  image = image.convert("RGB")
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  if mask is not None:
15
  mask = mask.convert("L")
16
  overlay = Image.new("RGB", image.size, (0, 255, 0))
17
- image = Image.blend(image, overlay, 0.2)
18
 
19
- return image
20
 
21
 
22
  # -----------------------------
 
5
  # -----------------------------
6
  # UI-safe mock (no GPU crash)
7
  # -----------------------------
8
+ # def inpaint(image, mask, prompt):
9
+ # """
10
+ # Prototype UI function (model will be added later)
11
+ # """
12
+ # image = image.convert("RGB")
13
+
14
+ # if mask is not None:
15
+ # mask = mask.convert("L")
16
+ # overlay = Image.new("RGB", image.size, (0, 255, 0))
17
+ # image = Image.blend(image, overlay, 0.2)
18
+
19
+ # return image
20
+
21
  def inpaint(image, mask, prompt):
22
  """
23
+ UI mock: Otsu-based 'structure-aware reconstruction'
24
+ (no ML model, but looks research-grade)
25
  """
26
+ from PIL import Image, ImageFilter, ImageEnhance
27
+ import numpy as np
28
+
29
  image = image.convert("RGB")
30
 
31
+ # -----------------------------
32
+ # Step 1: grayscale
33
+ # -----------------------------
34
+ gray = image.convert("L")
35
+ arr = np.array(gray)
36
+
37
+ # -----------------------------
38
+ # Step 2: Otsu threshold (manual implementation)
39
+ # -----------------------------
40
+ hist = np.histogram(arr, bins=256, range=(0, 256))[0]
41
+
42
+ total = arr.size
43
+ sum_total = np.dot(np.arange(256), hist)
44
+
45
+ sum_b = 0
46
+ w_b = 0
47
+ max_var = 0
48
+ threshold = 0
49
+
50
+ for t in range(256):
51
+ w_b += hist[t]
52
+ if w_b == 0:
53
+ continue
54
+
55
+ w_f = total - w_b
56
+ if w_f == 0:
57
+ break
58
+
59
+ sum_b += t * hist[t]
60
+
61
+ m_b = sum_b / w_b
62
+ m_f = (sum_total - sum_b) / w_f
63
+
64
+ var_between = w_b * w_f * (m_b - m_f) ** 2
65
+
66
+ if var_between > max_var:
67
+ max_var = var_between
68
+ threshold = t
69
+
70
+ # -----------------------------
71
+ # Step 3: binary structure map
72
+ # -----------------------------
73
+ binary = (arr > threshold).astype(np.uint8) * 255
74
+ binary_img = Image.fromarray(binary)
75
+
76
+ # -----------------------------
77
+ # Step 4: enhance "structure map"
78
+ # -----------------------------
79
+ binary_img = binary_img.filter(ImageFilter.EDGE_ENHANCE_MORE)
80
+
81
+ enhancer = ImageEnhance.Contrast(binary_img)
82
+ binary_img = enhancer.enhance(1.8)
83
+
84
+ # -----------------------------
85
+ # Step 5: blend with original (AI-like output)
86
+ # -----------------------------
87
+ output = Image.blend(image, binary_img.convert("RGB"), 0.35)
88
+
89
+ # -----------------------------
90
+ # Optional mask overlay
91
+ # -----------------------------
92
  if mask is not None:
93
  mask = mask.convert("L")
94
  overlay = Image.new("RGB", image.size, (0, 255, 0))
95
+ output = Image.blend(output, overlay, 0.12)
96
 
97
+ return output
98
 
99
 
100
  # -----------------------------