Spaces:
Running
Running
File size: 4,806 Bytes
00639e5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | # src/visualizer.py
import cv2
import numpy as np
import os
from pathlib import Path
from typing import Dict, Optional
# Çoklu taş için BGR renk paleti
_STONE_COLORS = [
(60, 20, 220), # Kırmızı
(220, 100, 20), # Mavi
(20, 180, 220), # Turuncu
(180, 20, 220), # Mor
(20, 220, 120), # Yeşil-sarı
]
_BBOX_COLOR = (30, 200, 30) # Yeşil — bbox her zaman yeşil
def _stone_color(idx: int) -> tuple:
return _STONE_COLORS[idx % len(_STONE_COLORS)]
def draw_detections(
image_path: str,
detection_result: Dict,
features: Dict,
output_path: Optional[str] = None
) -> str:
"""
Görüntü üzerine her taş için:
- Yeşil bbox (detection çıktısı)
- Renkli yarı saydam mask dolgusu + kontur (segmentation çıktısı)
- Etiket: taş ID, boyut (mm), confidence
Returns:
Kaydedilen annotated görüntünün path'i
"""
image = cv2.imread(image_path)
if image is None:
raise FileNotFoundError(f"Image not found: {image_path}")
detections = detection_result.get("detections", [])
stone_features = features.get("stones", [])
# ── Adım 1: Mask dolguları ayrı overlay'de çiz ──────────────────────────
overlay = image.copy()
for idx, det in enumerate(detections):
mask_polygon = det.get("mask_polygon")
if mask_polygon:
pts = np.array(mask_polygon, dtype=np.int32)
cv2.fillPoly(overlay, [pts], _stone_color(idx))
# Yarı saydamlık uygula (dolgu görüntüyle karışsın, çizgiler keskin kalsın)
result = cv2.addWeighted(overlay, 0.30, image, 0.70, 0)
# ── Adım 2: Bbox + mask kontur + etiket üst katmanda çiz ────────────────
for idx, det in enumerate(detections):
color = _stone_color(idx)
# Bbox — yeşil ince dikdörtgen
x1, y1, x2, y2 = [int(c) for c in det["bbox"]]
cv2.rectangle(result, (x1, y1), (x2, y2), _BBOX_COLOR, 1)
# Mask kontur — taşın gerçek sınırı
mask_polygon = det.get("mask_polygon")
if mask_polygon:
pts = np.array(mask_polygon, dtype=np.int32)
cv2.polylines(result, [pts], isClosed=True, color=color, thickness=2)
# Etiket metni
size_mm = 0.0
if idx < len(stone_features):
size_mm = stone_features[idx]["size"].get("max_dimension_mm", 0.0)
conf = det["confidence"]
label = f"#{idx + 1} {size_mm}mm conf:{conf:.2f}"
# Etiket arka planı (okunabilirlik için)
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.45
thickness = 1
(tw, th), baseline = cv2.getTextSize(label, font, font_scale, thickness)
lx = x1
ly = max(y1 - 6, th + 6)
cv2.rectangle(result,
(lx, ly - th - 4),
(lx + tw + 6, ly + baseline),
_BBOX_COLOR, cv2.FILLED)
cv2.putText(result, label,
(lx + 3, ly - 1),
font, font_scale, (255, 255, 255), thickness, cv2.LINE_AA)
# Taş tespit edilmediyse küçük bir uyarı yaz
if not detections:
cv2.putText(result, "No stones detected",
(10, 30), cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0, 0, 220), 2, cv2.LINE_AA)
# ── Adım 3: Kaydet ──────────────────────────────────────────────────────
if output_path is None:
p = Path(image_path)
output_path = str(p.parent / (p.stem + "_annotated.png"))
parent_dir = os.path.dirname(output_path)
if parent_dir:
os.makedirs(parent_dir, exist_ok=True)
cv2.imwrite(output_path, result)
return output_path
if __name__ == "__main__":
# Hızlı test — gerçek model olmadan mock data ile
import numpy as np
# Siyah test görüntüsü oluştur
test_img = np.zeros((512, 512, 3), dtype=np.uint8)
cv2.imwrite("test_input.png", test_img)
mock_detection = {
"detections": [{
"bbox": [150, 180, 280, 300],
"confidence": 0.91,
"class_name": "stone",
"mask_polygon": [
[170, 190], [200, 175], [250, 185],
[270, 220], [260, 270], [220, 290],
[175, 280], [155, 245], [160, 210]
]
}]
}
mock_features = {
"stones": [{
"stone_id": 1,
"size": {"max_dimension_mm": 7.2},
"detection_confidence": 0.91
}]
}
out = draw_detections("test_input.png", mock_detection, mock_features)
print(f"Saved: {out}")
|