qonitasal commited on
Commit
ee47cdd
·
verified ·
1 Parent(s): 008b8be

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -67
app.py CHANGED
@@ -1,111 +1,89 @@
1
- #!/usr/bin/env python
2
- # coding: utf-8
3
-
4
  import gradio as gr
5
- from PIL import Image, ImageDraw, ImageFont
6
  from ultralytics import YOLO
7
  import numpy as np
8
  import os
 
 
 
 
 
 
 
9
 
10
- # === Load model safely ===
11
- try:
12
- model_path = "best.pt"
13
- if not os.path.exists(model_path):
14
- raise FileNotFoundError(f"❌ File {model_path} not found. Upload best.pt to root directory.")
15
- model = YOLO(model_path)
16
- print("✅ Model loaded successfully!")
17
- except Exception as e:
18
- print("❌ Failed to load YOLO model:", e)
19
- model = None
20
-
21
- # Mapping label (4 classes)
22
  label_map = {
23
  0: "coral",
24
  1: "pipeline",
25
  2: "ripple marks",
26
  3: "shipwreck"
27
  }
28
-
29
- # Warna RGB untuk setiap class
30
  color_map = {
31
- 0: (0, 255, 0), # hijau - coral
32
- 1: (255, 0, 0), # merah - pipeline
33
- 2: (255, 255, 0), # kuning - ripple marks
34
- 3: (0, 0, 255) # biru - shipwreck
35
  }
36
 
37
- def predict_segmentation_with_legend(image):
38
- if model is None:
39
- return Image.new("RGB", image.size, color=(255, 255, 255))
40
 
41
- image = image.convert("RGB")
42
- results = model.predict(image, conf=0.25, iou=0.5)
43
  result = results[0]
44
 
45
- print("🔍 DETECTIONS:", result.boxes)
46
- print("🎭 MASKS:", result.masks)
47
-
48
  if result.masks is None:
49
- print("⚠️ No masks detected.")
50
- return image
51
-
52
- image_np = np.array(image).copy()
53
- draw = ImageDraw.Draw(image)
54
-
55
- try:
56
- font = ImageFont.truetype("arial.ttf", 24)
57
- except:
58
- font = ImageFont.load_default()
59
 
60
  masks = result.masks.data.cpu().numpy()
61
  boxes = result.boxes.xyxy.cpu().numpy()
62
  scores = result.boxes.conf.cpu().numpy()
63
  class_ids = result.boxes.cls.cpu().numpy().astype(int)
64
 
 
 
65
  for i, mask in enumerate(masks):
66
  class_id = class_ids[i]
67
- label = label_map.get(class_id, str(class_id))
68
- color = color_map.get(class_id, (255, 255, 0))
69
  score = scores[i]
70
  box = boxes[i].astype(int)
 
71
 
72
- # Blend mask ke image
73
- color_mask = np.zeros_like(image_np)
74
  for c in range(3):
75
- color_mask[:, :, c] = mask * color[c]
76
- image_np = np.where(color_mask > 0, image_np * 0.5 + color_mask * 0.5, image_np)
77
 
78
- # Gambar bounding box dan label
79
- draw.rectangle(box.tolist(), outline=color, width=3)
80
- draw.text((box[0], box[1] - 10), f"{label}: {score:.2f}", fill="white", font=font)
81
 
82
- # Convert kembali ke PIL image
83
- final_image = Image.fromarray(image_np.astype(np.uint8))
 
84
 
85
- # Legend
86
- legend_height = 50
87
- legend = Image.new("RGB", (final_image.width, legend_height), (255, 255, 255))
88
- draw_legend = ImageDraw.Draw(legend)
 
 
 
89
  x = 10
90
  for cid, label in label_map.items():
91
- draw_legend.rectangle([x, 10, x+20, 30], fill=color_map[cid])
92
- draw_legend.text((x + 25, 10), label, fill="black", font=font)
 
93
  x += 150
94
 
95
- combined = Image.new("RGB", (final_image.width, final_image.height + legend_height))
96
- combined.paste(final_image, (0, 0))
97
- combined.paste(legend, (0, final_image.height))
98
-
99
- return combined
100
 
101
- # === Gradio Interface ===
102
  iface = gr.Interface(
103
- fn=predict_segmentation_with_legend,
104
  inputs=gr.Image(type="pil"),
105
  outputs=gr.Image(type="pil"),
106
- title="YOLOv8 Segmentasi (4 Kelas: Coral, Pipeline, Ripple Marks, Shipwreck)",
107
- description="Upload citra sonar. Hasil segmentasi akan ditampilkan dengan mask, bounding box, skor, dan legenda warna."
108
  )
109
 
110
  if __name__ == "__main__":
111
- iface.launch()
 
 
 
 
1
  import gradio as gr
2
+ from PIL import Image, ImageFont, ImageDraw
3
  from ultralytics import YOLO
4
  import numpy as np
5
  import os
6
+ import cv2
7
+
8
+ # === Load model ===
9
+ model_path = "best.pt"
10
+ if not os.path.exists(model_path):
11
+ raise FileNotFoundError("❌ File model best.pt tidak ditemukan.")
12
+ model = YOLO(model_path)
13
 
14
+ # Label dan warna
 
 
 
 
 
 
 
 
 
 
 
15
  label_map = {
16
  0: "coral",
17
  1: "pipeline",
18
  2: "ripple marks",
19
  3: "shipwreck"
20
  }
 
 
21
  color_map = {
22
+ 0: (0, 255, 0), # green
23
+ 1: (255, 0, 0), # red
24
+ 2: (255, 255, 0), # yellow
25
+ 3: (0, 0, 255) # blue
26
  }
27
 
28
+ def predict_segmentation(image_pil):
29
+ image_pil = image_pil.convert("RGB")
30
+ image_np = np.array(image_pil)
31
 
32
+ results = model.predict(image_pil, conf=0.25, iou=0.5)
 
33
  result = results[0]
34
 
 
 
 
35
  if result.masks is None:
36
+ return image_pil
 
 
 
 
 
 
 
 
 
37
 
38
  masks = result.masks.data.cpu().numpy()
39
  boxes = result.boxes.xyxy.cpu().numpy()
40
  scores = result.boxes.conf.cpu().numpy()
41
  class_ids = result.boxes.cls.cpu().numpy().astype(int)
42
 
43
+ overlay = image_np.copy()
44
+
45
  for i, mask in enumerate(masks):
46
  class_id = class_ids[i]
47
+ color = color_map.get(class_id, (255, 255, 255))
 
48
  score = scores[i]
49
  box = boxes[i].astype(int)
50
+ label = label_map.get(class_id, str(class_id))
51
 
52
+ # Warnai area mask (semi-transparent)
 
53
  for c in range(3):
54
+ overlay[:, :, c] = np.where(mask > 0, overlay[:, :, c] * 0.5 + color[c] * 0.5, overlay[:, :, c])
 
55
 
56
+ # Gambar bounding box
57
+ cv2.rectangle(overlay, (box[0], box[1]), (box[2], box[3]), color, 2)
 
58
 
59
+ # Label + score
60
+ text = f"{label} {score:.2f}"
61
+ cv2.putText(overlay, text, (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
62
 
63
+ # Tambah legend
64
+ legend_height = 60
65
+ h, w, _ = overlay.shape
66
+ combined = np.ones((h + legend_height, w, 3), dtype=np.uint8) * 255
67
+ combined[:h] = overlay
68
+
69
+ # Gambar legenda
70
  x = 10
71
  for cid, label in label_map.items():
72
+ color = color_map[cid]
73
+ cv2.rectangle(combined, (x, h + 10), (x + 20, h + 30), color, -1)
74
+ cv2.putText(combined, label, (x + 30, h + 27), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 1)
75
  x += 150
76
 
77
+ return Image.fromarray(combined)
 
 
 
 
78
 
79
+ # Gradio app
80
  iface = gr.Interface(
81
+ fn=predict_segmentation,
82
  inputs=gr.Image(type="pil"),
83
  outputs=gr.Image(type="pil"),
84
+ title="YOLOv8 Segmentasi Sonar",
85
+ description="Upload citra Side Scan Sonar. Akan ditampilkan: mask, bounding box, confidence score, dan legenda kelas."
86
  )
87
 
88
  if __name__ == "__main__":
89
+ iface.launch()