Update app.py
Browse files
app.py
CHANGED
|
@@ -128,46 +128,45 @@ def predict_digit(input_image):
|
|
| 128 |
if input_image is None:
|
| 129 |
return "Please draw a number!"
|
| 130 |
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
img = img.resize((20, 20), Image.Resampling.LANCZOS)
|
| 160 |
-
centered_img = Image.new("L", (28, 28), 0)
|
| 161 |
-
centered_img.paste(img, (4, 4)) # Taruh di tengah (bukan mepet pojok)
|
| 162 |
-
|
| 163 |
-
# 6. NORMALISASI: Masukkan ke pipeline normalisasi latihan kamu (mean & std)
|
| 164 |
-
tensor_img = transform_fn(centered_img).unsqueeze(0).to(device)
|
| 165 |
-
|
| 166 |
-
with torch.no_grad():
|
| 167 |
-
outputs = model(tensor_img)
|
| 168 |
-
probabilities = F.softmax(outputs, dim=1)[0]
|
| 169 |
|
| 170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
# --- GRADIO INTERFACE CONSTRUCTION ---
|
| 173 |
with gr.Blocks() as demo:
|
|
|
|
| 128 |
if input_image is None:
|
| 129 |
return "Please draw a number!"
|
| 130 |
|
| 131 |
+
try:
|
| 132 |
+
# 1. Ambil layer coretan pertama langsung seperti kode referensi
|
| 133 |
+
if isinstance(input_image, dict) and "layers" in input_image and len(input_image["layers"]) > 0:
|
| 134 |
+
img_array = input_image["layers"][0]
|
| 135 |
+
elif isinstance(input_image, dict) and "composite" in input_image:
|
| 136 |
+
img_array = input_image["composite"]
|
| 137 |
+
else:
|
| 138 |
+
img_array = input_image
|
| 139 |
+
|
| 140 |
+
# 2. Pastikan bentuknya 2D Grayscale
|
| 141 |
+
if len(img_array.shape) == 3:
|
| 142 |
+
if img_array.shape[-1] == 4: # Jika RGBA, ambil alpha channel (coretannya)
|
| 143 |
+
grayscale = img_array[:, :, 3]
|
| 144 |
+
else: # Jika RGB, konversi ke grayscale
|
| 145 |
+
grayscale = np.dot(img_array[...,:3], [0.2989, 0.5870, 0.1140])
|
| 146 |
+
else:
|
| 147 |
+
grayscale = img_array
|
| 148 |
+
|
| 149 |
+
# 3. Cek jika kanvas kosong
|
| 150 |
+
if np.max(grayscale) == 0:
|
| 151 |
+
return {str(i): 0.1 for i in range(10)}
|
| 152 |
+
|
| 153 |
+
# 4. Konversi ke PIL dan Resize ke 28x28 (Gaya kode referensimu)
|
| 154 |
+
img = Image.fromarray(grayscale.astype(np.uint8)).convert('L')
|
| 155 |
+
img = img.resize((28, 28), resample=Image.Resampling.BILINEAR)
|
| 156 |
+
|
| 157 |
+
# 5. Jalankan normalisasi PyTorch sesuai training LookThem V8 kamu
|
| 158 |
+
tensor_img = transform_fn(img).unsqueeze(0).to(device)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
|
| 160 |
+
# 6. Prediksi dengan Otak Sniper LookThem
|
| 161 |
+
with torch.no_grad():
|
| 162 |
+
outputs = model(tensor_img)
|
| 163 |
+
probabilities = F.softmax(outputs, dim=1)[0]
|
| 164 |
+
|
| 165 |
+
return {str(i): float(probabilities[i]) for i in range(10)}
|
| 166 |
+
|
| 167 |
+
except Exception as e:
|
| 168 |
+
return {"Error": 0.0}
|
| 169 |
+
|
| 170 |
|
| 171 |
# --- GRADIO INTERFACE CONSTRUCTION ---
|
| 172 |
with gr.Blocks() as demo:
|