Update sam_module.py
Browse files- sam_module.py +13 -13
sam_module.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
def create_sam_mask(self, image, bbox_coords, mode):
|
| 2 |
"""
|
| 3 |
ERWEITERTE Funktion: Erstellt präzise Maske mit SAM 2
|
| 4 |
-
Restrukturierte Version mit klaren Blöcken pro Modus
|
| 5 |
"""
|
| 6 |
try:
|
| 7 |
print("#" * 80)
|
|
@@ -40,11 +39,11 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 40 |
# Der Prozessor von SAM erwartet ein NumPy-Array kein PIL
|
| 41 |
image_np = np.array(image.convert("RGB"))
|
| 42 |
|
| 43 |
-
#
|
| 44 |
input_boxes = [[[x1, y1, x2, y2]]]
|
| 45 |
|
| 46 |
-
# Aufruf des SAM-Prozessors mit
|
| 47 |
-
# in die für
|
| 48 |
inputs = self.sam_processor(
|
| 49 |
image_np,
|
| 50 |
input_boxes=input_boxes,
|
|
@@ -58,7 +57,7 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 58 |
print("🧠 SAM 2 INFERENZ (Vorhersage)")
|
| 59 |
with torch.no_grad():
|
| 60 |
print(" Führe Vorhersage durch...")
|
| 61 |
-
outputs = self.sam_model(**inputs)
|
| 62 |
print(f"✅ Vorhersage abgeschlossen")
|
| 63 |
print(f" Anzahl der Vorhersagemasken: {outputs.pred_masks.shape[2]}")
|
| 64 |
|
|
@@ -77,8 +76,8 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 77 |
align_corners=False
|
| 78 |
).squeeze()
|
| 79 |
|
| 80 |
-
mask_np = resized_mask.sigmoid().cpu().numpy()
|
| 81 |
-
all_masks.append(mask_np)
|
| 82 |
|
| 83 |
|
| 84 |
bbox_center = ((x1 + x2) // 2, (y1 + y2) // 2)
|
|
@@ -195,7 +194,7 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 195 |
fb_x2 = int(x2 * scale_x)
|
| 196 |
fb_y2 = int(y2 * scale_y)
|
| 197 |
|
| 198 |
-
# Schwarzes Rechteck für Person
|
| 199 |
cv2.rectangle(mask_array, (fb_x1, fb_y1), (fb_x2, fb_y2), 0, -1)
|
| 200 |
|
| 201 |
# Damit wird die Rohmaske für die UI-Anzeige gespeichert
|
|
@@ -203,7 +202,8 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 203 |
|
| 204 |
print("🌳 ENVIRONMENT-CHANGE POSTPROCESSING")
|
| 205 |
|
| 206 |
-
#
|
|
|
|
| 207 |
if image.size != original_image.size:
|
| 208 |
print(f" ⚠️ Bildgröße angepasst: {image.size} → {original_image.size}")
|
| 209 |
temp_mask = Image.fromarray(mask_array).convert("L")
|
|
@@ -224,7 +224,7 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 224 |
# DEBUG nach MORPH_OPEN
|
| 225 |
print(f" Nach MORPH_OPEN - Weiße Pixel: {np.sum(mask_array > 127)}")
|
| 226 |
|
| 227 |
-
# Morphologische Operationen für saubere Umgebung
|
| 228 |
print("🔧 Verbessere Umgebungsmaske...")
|
| 229 |
kernel_close = np.ones((5, 5), np.uint8)
|
| 230 |
mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_CLOSE, kernel_close)
|
|
@@ -235,7 +235,7 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 235 |
|
| 236 |
# Weiche Ränder für bessere Integration der Person
|
| 237 |
print("🌈 Erstelle weiche Übergänge...")
|
| 238 |
-
mask_array = cv2.GaussianBlur(mask_array, (9, 9), 2.0)
|
| 239 |
print(" ✅ Gaussian Blur für weiche Übergänge")
|
| 240 |
|
| 241 |
# DEBUG nach Gaussian Blur
|
|
@@ -247,8 +247,8 @@ def create_sam_mask(self, image, bbox_coords, mode):
|
|
| 247 |
mask_array = mask_array.astype(np.float32) / 255.0
|
| 248 |
print(f" Konvertiert zu Float32: Min={mask_array.min():.3f}, Max={mask_array.max():.3f}")
|
| 249 |
|
| 250 |
-
mask_array = np.clip(mask_array, 0.0, 1.0)
|
| 251 |
-
mask_array = mask_array ** 0.85 # Gamma-Korrektur
|
| 252 |
print(f" Nach Gamma 0.85: Min={mask_array.min():.3f}, Max={mask_array.max():.3f}")
|
| 253 |
|
| 254 |
mask_array = (mask_array * 255).astype(np.uint8)
|
|
|
|
| 1 |
def create_sam_mask(self, image, bbox_coords, mode):
|
| 2 |
"""
|
| 3 |
ERWEITERTE Funktion: Erstellt präzise Maske mit SAM 2
|
|
|
|
| 4 |
"""
|
| 5 |
try:
|
| 6 |
print("#" * 80)
|
|
|
|
| 39 |
# Der Prozessor von SAM erwartet ein NumPy-Array kein PIL
|
| 40 |
image_np = np.array(image.convert("RGB"))
|
| 41 |
|
| 42 |
+
# Packt die BBox-Koordinaten in eine 3D-Liste
|
| 43 |
input_boxes = [[[x1, y1, x2, y2]]]
|
| 44 |
|
| 45 |
+
# Aufruf des SAM-Prozessors mit Originalbild in Form NumPy-Array und BBox.Der Processor verarbeitet Bild und BBox
|
| 46 |
+
# in die für SAM erforderlichen Tensoren und speichert sie in inputs.
|
| 47 |
inputs = self.sam_processor(
|
| 48 |
image_np,
|
| 49 |
input_boxes=input_boxes,
|
|
|
|
| 57 |
print("🧠 SAM 2 INFERENZ (Vorhersage)")
|
| 58 |
with torch.no_grad():
|
| 59 |
print(" Führe Vorhersage durch...")
|
| 60 |
+
outputs = self.sam_model(**inputs) #führt die Segmentierung mit SAM aus
|
| 61 |
print(f"✅ Vorhersage abgeschlossen")
|
| 62 |
print(f" Anzahl der Vorhersagemasken: {outputs.pred_masks.shape[2]}")
|
| 63 |
|
|
|
|
| 76 |
align_corners=False
|
| 77 |
).squeeze()
|
| 78 |
|
| 79 |
+
mask_np = resized_mask.sigmoid().cpu().numpy(). #wandelt Modellausgaben in Wahrscheinlichkeiten und bewegt Daten von GPU nach CPU
|
| 80 |
+
all_masks.append(mask_np) #fügt die aktuelle Maske der Liste all_masks hinzu
|
| 81 |
|
| 82 |
|
| 83 |
bbox_center = ((x1 + x2) // 2, (y1 + y2) // 2)
|
|
|
|
| 194 |
fb_x2 = int(x2 * scale_x)
|
| 195 |
fb_y2 = int(y2 * scale_y)
|
| 196 |
|
| 197 |
+
# Schwarzes Rechteck für Person bzw. BBox
|
| 198 |
cv2.rectangle(mask_array, (fb_x1, fb_y1), (fb_x2, fb_y2), 0, -1)
|
| 199 |
|
| 200 |
# Damit wird die Rohmaske für die UI-Anzeige gespeichert
|
|
|
|
| 202 |
|
| 203 |
print("🌳 ENVIRONMENT-CHANGE POSTPROCESSING")
|
| 204 |
|
| 205 |
+
# Konvertierung zu PIL, hochskalieren auf Originalgröße (korrekte Überlagerung mit O-Bild),
|
| 206 |
+
# Konvertierung NumPy für weitere Verarbeitung da mathematisch korrekter als PIL.
|
| 207 |
if image.size != original_image.size:
|
| 208 |
print(f" ⚠️ Bildgröße angepasst: {image.size} → {original_image.size}")
|
| 209 |
temp_mask = Image.fromarray(mask_array).convert("L")
|
|
|
|
| 224 |
# DEBUG nach MORPH_OPEN
|
| 225 |
print(f" Nach MORPH_OPEN - Weiße Pixel: {np.sum(mask_array > 127)}")
|
| 226 |
|
| 227 |
+
# Morphologische Operationen für saubere Umgebung - entfernt schwarze Pixel aus Umgebung
|
| 228 |
print("🔧 Verbessere Umgebungsmaske...")
|
| 229 |
kernel_close = np.ones((5, 5), np.uint8)
|
| 230 |
mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_CLOSE, kernel_close)
|
|
|
|
| 235 |
|
| 236 |
# Weiche Ränder für bessere Integration der Person
|
| 237 |
print("🌈 Erstelle weiche Übergänge...")
|
| 238 |
+
mask_array = cv2.GaussianBlur(mask_array, (9, 9), 2.0) #2.0 bestimmt wie stark die Unschärfe ist
|
| 239 |
print(" ✅ Gaussian Blur für weiche Übergänge")
|
| 240 |
|
| 241 |
# DEBUG nach Gaussian Blur
|
|
|
|
| 247 |
mask_array = mask_array.astype(np.float32) / 255.0
|
| 248 |
print(f" Konvertiert zu Float32: Min={mask_array.min():.3f}, Max={mask_array.max():.3f}")
|
| 249 |
|
| 250 |
+
mask_array = np.clip(mask_array, 0.0, 1.0). #begrenzt alle Werte auf 0 und 1
|
| 251 |
+
mask_array = mask_array ** 0.85 # Gamma-Korrektur Werte > 0.5 werden abgedunkelt, <0.5 aufgehellt-erzeugt natürliche Maskenübergänge
|
| 252 |
print(f" Nach Gamma 0.85: Min={mask_array.min():.3f}, Max={mask_array.max():.3f}")
|
| 253 |
|
| 254 |
mask_array = (mask_array * 255).astype(np.uint8)
|