DimasMP3
commited on
Commit
·
1764393
1
Parent(s):
9184351
feat: enhance batch prediction functionality to support multiple image uploads
Browse files- app.py +1 -1
- inference.py +31 -4
app.py
CHANGED
|
@@ -32,7 +32,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=None, analytics_enabled=False) as ifa
|
|
| 32 |
|
| 33 |
# Endpoint batch (opsional) untuk klien JSON; menjaga compat endpoint default tetap single
|
| 34 |
with gr.Accordion("Batch (opsional)", open=False):
|
| 35 |
-
files_in = gr.Files(
|
| 36 |
json_out = gr.JSON(label="Best of batch (JSON)")
|
| 37 |
batch_btn = gr.Button("Prediksi Batch")
|
| 38 |
batch_btn.click(fn=predict_batch, inputs=files_in, outputs=json_out, api_name="predict_batch")
|
|
|
|
| 32 |
|
| 33 |
# Endpoint batch (opsional) untuk klien JSON; menjaga compat endpoint default tetap single
|
| 34 |
with gr.Accordion("Batch (opsional)", open=False):
|
| 35 |
+
files_in = gr.Files(file_count="multiple", file_types=["image"], label="Unggah beberapa gambar")
|
| 36 |
json_out = gr.JSON(label="Best of batch (JSON)")
|
| 37 |
batch_btn = gr.Button("Prediksi Batch")
|
| 38 |
batch_btn.click(fn=predict_batch, inputs=files_in, outputs=json_out, api_name="predict_batch")
|
inference.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import numpy as np
|
| 2 |
from PIL import Image
|
| 3 |
import tensorflow as tf
|
| 4 |
-
from typing import List, Dict, Tuple
|
| 5 |
import time
|
| 6 |
import os
|
| 7 |
|
|
@@ -98,13 +98,40 @@ def _dict_to_payload(d: Dict[str, float]) -> Dict[str, object]:
|
|
| 98 |
return {"label": top, "confidences": confs}
|
| 99 |
|
| 100 |
|
| 101 |
-
def
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
if not model_instance:
|
| 104 |
return {"error": "Instance model tidak tersedia."}
|
| 105 |
-
if not
|
| 106 |
return {"error": "Tidak ada gambar."}
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
best_payload: Dict[str, object] = {"label": "", "confidences": []}
|
| 109 |
best_conf = -1.0
|
| 110 |
for img in images:
|
|
|
|
| 1 |
import numpy as np
|
| 2 |
from PIL import Image
|
| 3 |
import tensorflow as tf
|
| 4 |
+
from typing import List, Dict, Tuple, Any
|
| 5 |
import time
|
| 6 |
import os
|
| 7 |
|
|
|
|
| 98 |
return {"label": top, "confidences": confs}
|
| 99 |
|
| 100 |
|
| 101 |
+
def _to_pil_list(files: List[Any]) -> List[Image.Image]:
|
| 102 |
+
out: List[Image.Image] = []
|
| 103 |
+
for f in files:
|
| 104 |
+
try:
|
| 105 |
+
if isinstance(f, Image.Image):
|
| 106 |
+
out.append(f)
|
| 107 |
+
continue
|
| 108 |
+
# Gradio >=4: FileData with .path
|
| 109 |
+
path = None
|
| 110 |
+
if hasattr(f, "path") and isinstance(getattr(f, "path"), str):
|
| 111 |
+
path = getattr(f, "path")
|
| 112 |
+
elif isinstance(f, str):
|
| 113 |
+
path = f
|
| 114 |
+
elif hasattr(f, "name") and isinstance(getattr(f, "name"), str):
|
| 115 |
+
path = getattr(f, "name")
|
| 116 |
+
if path:
|
| 117 |
+
img = Image.open(path).convert("RGB")
|
| 118 |
+
out.append(img)
|
| 119 |
+
except Exception:
|
| 120 |
+
continue
|
| 121 |
+
return out
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def predict_batch(files: List[Any]) -> Dict[str, object]:
|
| 125 |
+
"""Prediksi batch: menerima FileData/paths atau PIL.Image; pilih hasil terbaik."""
|
| 126 |
if not model_instance:
|
| 127 |
return {"error": "Instance model tidak tersedia."}
|
| 128 |
+
if not files:
|
| 129 |
return {"error": "Tidak ada gambar."}
|
| 130 |
|
| 131 |
+
images = _to_pil_list(files)
|
| 132 |
+
if not images:
|
| 133 |
+
return {"error": "Tidak dapat membaca gambar."}
|
| 134 |
+
|
| 135 |
best_payload: Dict[str, object] = {"label": "", "confidences": []}
|
| 136 |
best_conf = -1.0
|
| 137 |
for img in images:
|