Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -5,15 +5,17 @@ import gradio as gr
|
|
5 |
import pandas as pd
|
6 |
from ultralytics import YOLO
|
7 |
from pathlib import Path
|
|
|
8 |
|
9 |
# === Konfigurasi ===
|
10 |
-
model_path = "best.pt"
|
11 |
-
gt_label_dir = "data/labels"
|
12 |
class_names = ['coral or rock', 'pipeline', 'ripple marks', 'shipwreck']
|
13 |
|
|
|
14 |
model = YOLO(model_path)
|
15 |
|
16 |
-
# === Fungsi untuk menggambar
|
17 |
def draw_mask(img, segments, class_ids, color=(255, 0, 0), alpha=0.5, label_type="Pred", confs=None):
|
18 |
overlay = img.copy()
|
19 |
for i, seg in enumerate(segments):
|
@@ -22,7 +24,8 @@ def draw_mask(img, segments, class_ids, color=(255, 0, 0), alpha=0.5, label_type
|
|
22 |
polygon[:, 1] *= img.shape[0]
|
23 |
polygon = polygon.astype(np.int32)
|
24 |
|
25 |
-
|
|
|
26 |
if confs and i < len(confs):
|
27 |
label += f" ({confs[i]:.2f})"
|
28 |
|
@@ -32,14 +35,17 @@ def draw_mask(img, segments, class_ids, color=(255, 0, 0), alpha=0.5, label_type
|
|
32 |
|
33 |
return cv2.addWeighted(overlay, alpha, img, 1 - alpha, 0)
|
34 |
|
35 |
-
# === Proses
|
36 |
def process_image_and_report(image):
|
37 |
-
|
|
|
|
|
|
|
38 |
image.save(temp_path)
|
39 |
img = cv2.imread(temp_path)
|
40 |
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
41 |
|
42 |
-
# ===
|
43 |
label_path = os.path.join(gt_label_dir, Path(temp_path).with_suffix(".txt").name)
|
44 |
img_gt = img.copy()
|
45 |
if os.path.exists(label_path):
|
@@ -56,7 +62,7 @@ def process_image_and_report(image):
|
|
56 |
gt_ids.append(cls_id)
|
57 |
img_gt = draw_mask(img_gt, gt_segments, gt_ids, color=(0, 255, 0), label_type="GT")
|
58 |
|
59 |
-
# ===
|
60 |
results = model(temp_path)[0]
|
61 |
segs = [seg.xy for seg in results.masks] if results.masks else []
|
62 |
cls_ids = results.boxes.cls.tolist() if results.boxes else []
|
@@ -65,10 +71,10 @@ def process_image_and_report(image):
|
|
65 |
|
66 |
img_pred = draw_mask(img.copy(), segs, cls_ids, color=(255, 0, 0), label_type="Pred", confs=confs)
|
67 |
|
68 |
-
# === Gabung
|
69 |
combined = np.concatenate((img_gt, img_pred), axis=1)
|
70 |
|
71 |
-
# ===
|
72 |
rows = []
|
73 |
for i in range(len(cls_ids)):
|
74 |
rows.append({
|
@@ -82,15 +88,14 @@ def process_image_and_report(image):
|
|
82 |
})
|
83 |
|
84 |
df = pd.DataFrame(rows)
|
85 |
-
csv_path = "detection_report.csv"
|
86 |
df.to_csv(csv_path, index=False)
|
87 |
|
88 |
return combined, csv_path
|
89 |
|
90 |
-
# === Gradio
|
91 |
with gr.Blocks() as demo:
|
92 |
gr.Markdown("## 🧠 YOLOv8 Segmentasi Viewer + Report Generator")
|
93 |
-
gr.Markdown("Upload gambar, lihat segmentasi, dan unduh
|
94 |
|
95 |
with gr.Row():
|
96 |
with gr.Column():
|
|
|
5 |
import pandas as pd
|
6 |
from ultralytics import YOLO
|
7 |
from pathlib import Path
|
8 |
+
from datetime import datetime
|
9 |
|
10 |
# === Konfigurasi ===
|
11 |
+
model_path = "best.pt" # pastikan file ini ada di root repo Hugging Face
|
12 |
+
gt_label_dir = "data/labels" # sesuaikan dengan struktur foldermu
|
13 |
class_names = ['coral or rock', 'pipeline', 'ripple marks', 'shipwreck']
|
14 |
|
15 |
+
# Load model
|
16 |
model = YOLO(model_path)
|
17 |
|
18 |
+
# === Fungsi untuk menggambar segmentasi ===
|
19 |
def draw_mask(img, segments, class_ids, color=(255, 0, 0), alpha=0.5, label_type="Pred", confs=None):
|
20 |
overlay = img.copy()
|
21 |
for i, seg in enumerate(segments):
|
|
|
24 |
polygon[:, 1] *= img.shape[0]
|
25 |
polygon = polygon.astype(np.int32)
|
26 |
|
27 |
+
cls_id = int(class_ids[i]) # FIX: pastikan integer
|
28 |
+
label = f"{label_type}: {class_names[cls_id]}"
|
29 |
if confs and i < len(confs):
|
30 |
label += f" ({confs[i]:.2f})"
|
31 |
|
|
|
35 |
|
36 |
return cv2.addWeighted(overlay, alpha, img, 1 - alpha, 0)
|
37 |
|
38 |
+
# === Proses prediksi + simpan CSV ===
|
39 |
def process_image_and_report(image):
|
40 |
+
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
|
41 |
+
temp_path = f"/tmp/temp_{timestamp}.jpg"
|
42 |
+
csv_path = f"/tmp/detection_report_{timestamp}.csv"
|
43 |
+
|
44 |
image.save(temp_path)
|
45 |
img = cv2.imread(temp_path)
|
46 |
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
47 |
|
48 |
+
# === Load ground truth ===
|
49 |
label_path = os.path.join(gt_label_dir, Path(temp_path).with_suffix(".txt").name)
|
50 |
img_gt = img.copy()
|
51 |
if os.path.exists(label_path):
|
|
|
62 |
gt_ids.append(cls_id)
|
63 |
img_gt = draw_mask(img_gt, gt_segments, gt_ids, color=(0, 255, 0), label_type="GT")
|
64 |
|
65 |
+
# === Deteksi dengan YOLOv8 ===
|
66 |
results = model(temp_path)[0]
|
67 |
segs = [seg.xy for seg in results.masks] if results.masks else []
|
68 |
cls_ids = results.boxes.cls.tolist() if results.boxes else []
|
|
|
71 |
|
72 |
img_pred = draw_mask(img.copy(), segs, cls_ids, color=(255, 0, 0), label_type="Pred", confs=confs)
|
73 |
|
74 |
+
# === Gabung GT dan Prediksi
|
75 |
combined = np.concatenate((img_gt, img_pred), axis=1)
|
76 |
|
77 |
+
# === Simpan laporan ke CSV
|
78 |
rows = []
|
79 |
for i in range(len(cls_ids)):
|
80 |
rows.append({
|
|
|
88 |
})
|
89 |
|
90 |
df = pd.DataFrame(rows)
|
|
|
91 |
df.to_csv(csv_path, index=False)
|
92 |
|
93 |
return combined, csv_path
|
94 |
|
95 |
+
# === UI Gradio ===
|
96 |
with gr.Blocks() as demo:
|
97 |
gr.Markdown("## 🧠 YOLOv8 Segmentasi Viewer + Report Generator")
|
98 |
+
gr.Markdown("Upload gambar, lihat segmentasi prediksi vs GT, dan unduh laporan CSV deteksi.")
|
99 |
|
100 |
with gr.Row():
|
101 |
with gr.Column():
|