Astridkraft commited on
Commit
59f8710
·
verified ·
1 Parent(s): 2b65f18

Update controlnet_module.py

Browse files
Files changed (1) hide show
  1. controlnet_module.py +113 -51
controlnet_module.py CHANGED
@@ -1152,42 +1152,42 @@ class ControlNetProcessor:
1152
  raw_mask_array = mask_array.copy()
1153
 
1154
  # ============================================================
1155
- # POSTPROCESSING auf Crop-Größe
1156
  # ============================================================
1157
-
1158
- print("👤 POSTPROCESSING AUF CROP-GRÖSSE")
1159
 
1160
- # 1. Größte zusammenhängende Komponente finden
1161
- labeled_array, num_features = ndimage.label(mask_array)
1162
 
1163
- if num_features > 0:
1164
- print(f" 🔍 Gefundene Komponenten: {num_features}")
1165
 
1166
- sizes = ndimage.sum(mask_array, labeled_array, range(1, num_features + 1))
1167
- largest_component_idx = np.argmax(sizes) + 1
1168
 
1169
- print(f" 👑 Größte Komponente: Nr. {largest_component_idx} mit {sizes[largest_component_idx-1]:,} Pixel")
1170
 
1171
- # NUR die größte Komponente behalten (der Kopf)
1172
- mask_array = np.where(labeled_array == largest_component_idx, mask_array, 0)
1173
 
1174
- # MORPHOLOGISCHE OPERATIONEN FÜR SAUBEREN KOPF
1175
- print(" ⚙️ Morphologische Operationen für sauberen Kopf")
1176
 
1177
- # Zuerst CLOSE, um kleine Löcher im Kopf zu füllen
1178
- kernel_close = np.ones((7, 7), np.uint8)
1179
- mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_CLOSE, kernel_close, iterations=1)
1180
- print(" • MORPH_CLOSE (7x7) - Löcher im Kopf füllen")
1181
 
1182
- # Dann OPEN, um kleine Ausreißer zu entfernen
1183
- kernel_open = np.ones((5, 5), np.uint8)
1184
- mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_OPEN, kernel_open, iterations=1)
1185
- print(" • MORPH_OPEN (5x5) - Rauschen entfernen")
1186
 
1187
- # LEICHTER DILATE FÜR MEHR ABDECKUNG (wichtig für Gesicht!)
1188
- print(" 🔲 Leichter Dilate für natürliche Abdeckung")
1189
- kernel_dilate = np.ones((5, 5), np.uint8) # Größerer Kernel für Gesicht
1190
- mask_array = cv2.dilate(mask_array, kernel_dilate, iterations=1)
1191
 
1192
 
1193
  #Speicherung der Binärmaske für Inpaint da keine Graupixel
@@ -1228,35 +1228,97 @@ class ControlNetProcessor:
1228
  # Nochmal weichzeichnen
1229
  mask_array = cv2.GaussianBlur(mask_array, (11, 11), 2.0)
1230
 
1231
- # ============================================================
1232
- # Maske und Rohmaske auf Originalgröße transformieren
1233
- # ============================================================
1234
- print("🔄 MASKE AUF ORIGINALGRÖSSE TRANSFORMIEREN")
1235
 
1236
- # 1. Maske in Crop-Größe wird konveriert von NumPy nach PIL
1237
- mask_crop_pil = Image.fromarray(mask_array).convert("L")
1238
 
1239
- # Leere Maske in Originalgröße
1240
- mask_original = Image.new("L", original_image.size, 0)
1241
 
1242
- # Crop-Maske an richtiger Position in leerem Originalbild einfügen
1243
- # da Hauptprogramm Originalgröße erwartet.
1244
- mask_original.paste(mask_crop_pil, (crop_x1, crop_y1))
1245
 
1246
- # 2. Rohmaske ebenfalls transformieren
1247
- raw_mask_crop_pil = Image.fromarray(raw_mask_array).convert("L")
1248
- raw_mask_original = Image.new("L", original_image.size, 0)
1249
- raw_mask_original.paste(raw_mask_crop_pil, (crop_x1, crop_y1))
1250
-
1251
- #Binärmaske für Inpaint auf Originalgröße bringen
1252
- #konvertieren zu PIL-Image
1253
- inpaint_binary_crop_pil = Image.fromarray(inpaint_binary_mask).convert("L")
1254
- #Leeres schwarzes Bild in Originalgröße erstellen
1255
- inpaint_binary_original = Image.new("L", original_image.size, 0)
1256
- #Klebe Crop-SAM-Maske auf schwarzes Bild in Originalgröße
1257
- inpaint_binary_original.paste(inpaint_binary_crop_pil, (crop_x1, crop_y1))
1258
-
1259
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1260
  # ============================================================
1261
  # ABSCHLIESSENDE STATISTIK
1262
  # ============================================================
 
1152
  raw_mask_array = mask_array.copy()
1153
 
1154
  # ============================================================
1155
+ # POSTPROCESSING unterschiedlich für Crop/Original
1156
  # ============================================================
1157
+ if use_crop_strategy:
1158
+ print("👤 POSTPROCESSING AUF CROP-GRÖSSE")
1159
 
1160
+ # 1. Größte zusammenhängende Komponente finden
1161
+ labeled_array, num_features = ndimage.label(mask_array)
1162
 
1163
+ if num_features > 0:
1164
+ print(f" 🔍 Gefundene Komponenten: {num_features}")
1165
 
1166
+ sizes = ndimage.sum(mask_array, labeled_array, range(1, num_features + 1))
1167
+ largest_component_idx = np.argmax(sizes) + 1
1168
 
1169
+ print(f" 👑 Größte Komponente: Nr. {largest_component_idx} mit {sizes[largest_component_idx-1]:,} Pixel")
1170
 
1171
+ # NUR die größte Komponente behalten (der Kopf)
1172
+ mask_array = np.where(labeled_array == largest_component_idx, mask_array, 0)
1173
 
1174
+ # MORPHOLOGISCHE OPERATIONEN FÜR SAUBEREN KOPF
1175
+ print(" ⚙️ Morphologische Operationen für sauberen Kopf")
1176
 
1177
+ # Zuerst CLOSE, um kleine Löcher im Kopf zu füllen
1178
+ kernel_close = np.ones((7, 7), np.uint8)
1179
+ mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_CLOSE, kernel_close, iterations=1)
1180
+ print(" • MORPH_CLOSE (7x7) - Löcher im Kopf füllen")
1181
 
1182
+ # Dann OPEN, um kleine Ausreißer zu entfernen
1183
+ kernel_open = np.ones((5, 5), np.uint8)
1184
+ mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_OPEN, kernel_open, iterations=1)
1185
+ print(" • MORPH_OPEN (5x5) - Rauschen entfernen")
1186
 
1187
+ # LEICHTER DILATE FÜR MEHR ABDECKUNG (wichtig für Gesicht!)
1188
+ print(" 🔲 Leichter Dilate für natürliche Abdeckung")
1189
+ kernel_dilate = np.ones((5, 5), np.uint8) # Größerer Kernel für Gesicht
1190
+ mask_array = cv2.dilate(mask_array, kernel_dilate, iterations=1)
1191
 
1192
 
1193
  #Speicherung der Binärmaske für Inpaint da keine Graupixel
 
1228
  # Nochmal weichzeichnen
1229
  mask_array = cv2.GaussianBlur(mask_array, (11, 11), 2.0)
1230
 
1231
+ # ============================================================
1232
+ # Maske und Rohmaske auf Originalgröße transformieren (nur für Crop)
1233
+ # ============================================================
1234
+ print("🔄 MASKE AUF ORIGINALGRÖSSE TRANSFORMIEREN")
1235
 
1236
+ # 1. Maske in Crop-Größe wird konveriert von NumPy nach PIL
1237
+ mask_crop_pil = Image.fromarray(mask_array).convert("L")
1238
 
1239
+ # Leere Maske in Originalgröße
1240
+ mask_original = Image.new("L", original_image.size, 0)
1241
 
1242
+ # Crop-Maske an richtiger Position in leerem Originalbild einfügen
1243
+ # da Hauptprogramm Originalgröße erwartet.
1244
+ mask_original.paste(mask_crop_pil, (crop_x1, crop_y1))
1245
 
1246
+ # 2. Rohmaske ebenfalls transformieren
1247
+ raw_mask_crop_pil = Image.fromarray(raw_mask_array).convert("L")
1248
+ raw_mask_original = Image.new("L", original_image.size, 0)
1249
+ raw_mask_original.paste(raw_mask_crop_pil, (crop_x1, crop_y1))
1250
+
1251
+ #Binärmaske für Inpaint auf Originalgröße bringen
1252
+ #konvertieren zu PIL-Image
1253
+ inpaint_binary_crop_pil = Image.fromarray(inpaint_binary_mask).convert("L")
1254
+ #Leeres schwarzes Bild in Originalgröße erstellen
1255
+ inpaint_binary_original = Image.new("L", original_image.size, 0)
1256
+ #Klebe Crop-SAM-Maske auf schwarzes Bild in Originalgröße
1257
+ inpaint_binary_original.paste(inpaint_binary_crop_pil, (crop_x1, crop_y1))
1258
+
1259
+ else: #keine use_crop_stategy Bild<=512
1260
+ print("👤 POSTPROCESSING AUF ORIGINALGRÖSSE (≤512px)")
1261
+
1262
+ # POSTPROCESSING-LOGIK FÜR ORIGINALGRÖSSE
1263
+ labeled_array, num_features = ndimage.label(mask_array)
1264
+
1265
+ if num_features > 0:
1266
+ print(f" 🔍 Gefundene Komponenten: {num_features}")
1267
+ sizes = ndimage.sum(mask_array, labeled_array, range(1, num_features + 1))
1268
+ largest_component_idx = np.argmax(sizes) + 1
1269
+ print(f" 👑 Größte Komponente: Nr. {largest_component_idx} mit {sizes[largest_component_idx-1]:,} Pixel")
1270
+
1271
+ mask_array = np.where(labeled_array == largest_component_idx, mask_array, 0)
1272
+
1273
+ # ANGEPASSTE Morphologische Operationen für Originalgröße
1274
+ kernel_close = np.ones((5, 5), np.uint8)
1275
+ mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_CLOSE, kernel_close, iterations=1)
1276
+ print(" • MORPH_CLOSE (5x5) - Löcher im Kopf füllen")
1277
+
1278
+ kernel_open = np.ones((3, 3), np.uint8)
1279
+ mask_array = cv2.morphologyEx(mask_array, cv2.MORPH_OPEN, kernel_open, iterations=1)
1280
+ print(" • MORPH_OPEN (3x3) - Rauschen entfernen")
1281
+
1282
+ # Leichter Dilate für mehr Abdeckung
1283
+ kernel_dilate = np.ones((3, 3), np.uint8)
1284
+ mask_array = cv2.dilate(mask_array, kernel_dilate, iterations=1)
1285
+ print(" • DILATE (3x3) - Natürliche Abdeckung")
1286
+
1287
+ # Binärmaske für Inpaint speichern (vor Blur)
1288
+ inpaint_binary_mask = mask_array.copy()
1289
+
1290
+ # ANGEPASSTER Gaussian Blur für Originalgröße
1291
+ mask_array = cv2.GaussianBlur(mask_array, (11, 11), 2.0)
1292
+ print(" • GAUSSIAN BLUR (11x11, sigma=2.0) - Weiche Übergänge")
1293
+
1294
+ # Gamma-Korrektur
1295
+ mask_array_float = mask_array.astype(np.float32) / 255.0
1296
+ mask_array_float = np.clip(mask_array_float, 0.0, 1.0)
1297
+ mask_array_float = mask_array_float ** 0.8
1298
+ mask_array = (mask_array_float * 255).astype(np.uint8)
1299
+ print(" • GAMMA (0.8) - Glatte Übergänge")
1300
+
1301
+ # Finaler weicher Blur
1302
+ mask_array = cv2.GaussianBlur(mask_array, (7, 7), 1.0)
1303
+ print(" • FINALER BLUR (7x7, sigma=1.0)")
1304
+
1305
+ # Prüfe Maskendichte
1306
+ white_pixels = np.sum(mask_array > 128)
1307
+ coverage_ratio = white_pixels / heur_bbox_area if heur_bbox_area > 0 else 0
1308
+ print(f" 📊 Aktuelle Abdeckung: {white_pixels:,}px / {heur_bbox_area:,}px = {coverage_ratio:.1%}")
1309
+
1310
+ if coverage_ratio < 0.9:
1311
+ print(f" ⚠️ Maske zu dünn für Gesicht (<90%)")
1312
+ kernel_extra = np.ones((5, 5), np.uint8)
1313
+ mask_array = cv2.dilate(mask_array, kernel_extra, iterations=1)
1314
+ mask_array = cv2.GaussianBlur(mask_array, (7, 7), 1.5)
1315
+
1316
+ # Masken sind bereits in Originalgröße
1317
+ mask_original = Image.fromarray(mask_array).convert("L")
1318
+ raw_mask_original = Image.fromarray(raw_mask_array).convert("L")
1319
+ inpaint_binary_original = Image.fromarray(inpaint_binary_mask).convert("L")
1320
+
1321
+
1322
  # ============================================================
1323
  # ABSCHLIESSENDE STATISTIK
1324
  # ============================================================