DegMaTsu commited on
Commit
0756247
·
verified ·
1 Parent(s): b96ff87

Upload reactor_swapper.py

Browse files
custom_nodes/comfyui-reactor-node/scripts/reactor_swapper.py CHANGED
@@ -306,17 +306,13 @@ def run_hyperswap(session, source_face, target_face, target_img):
306
  M = get_affine_transform(target_landmarks_5.astype(np.float32), std_landmarks_256)
307
  logger.debug("Affine Matrix M (used for cropping):\n%s", M)
308
 
309
- #### Что проверить:
310
- # Матрица `M` не должна содержать `NaN` или бесконечности.
311
- # Если матрица нулевая или искаженная — проблема в точках `target_landmarks_5`.
312
-
313
  # Применяем аффинное преобразование с новой матрицей M
314
  crop = cv2.warpAffine(target_img, M, (256, 256), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REFLECT)
315
 
316
  # Визуализация crop перед инференсом
317
  #### Что проверить:
318
- # Окно `"Crop Before Inference"` должно показывать лицо, вырезанное по аффинному преобразованию.
319
- # Если изображение черное — проблема в `M` или `target_landmarks_5`.
320
  logger.debug("Crop shape: %s | Min: %s | Max: %s", crop.shape, crop.min(), crop.max())
321
  # cv2.imshow("Crop Before Inference", crop)
322
  # cv2.waitKey(1) # Отображает изображение
@@ -338,30 +334,44 @@ def run_hyperswap(session, source_face, target_face, target_img):
338
  logger.error("Ошибка выполнения модели: %s", e)
339
  return target_img
340
 
341
- # 6. Обратная нормализация
342
- # output = output * 0.5 + 0.5
343
- # output = np.clip(output, 0, 1)
344
- # output = (output * 255).astype(np.uint8)
345
- # output = output.transpose(1, 2, 0)
346
- # output = output[:, :, ::-1] # RGB->BGR
347
- output = (output * 0.5 + 0.5) * 255.0 # [-1..1] -> [0..255]
348
- output = np.clip(output, 0, 255).astype(np.uint8)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  output = output.transpose(1, 2, 0) # CHW -> HWC
350
- output = output[:, :, ::-1] # BGR -> RGB (Убедитесь, что это BGR, если вход был BGR)
351
 
352
  # Визуализация после денормализации
353
- #### Что проверить:
354
- # `output` должен быть в диапазоне `[0..255]` и содержать лицо.
355
- # Если `output` черный — проблема в нормализации/денормализации или в самой модели.
356
  logger.debug("Output after denormalization: Min: %s | Max: %s", output.min(), output.max())
357
  # cv2.imshow("Output After Denormalization", output)
358
  # cv2.waitKey(1)
359
 
360
- # 7. ИЗМЕНЕНИЕ: Возвращаем результат 256x256 И матрицу M
361
  # Мы больше не вызываем warp_and_paste_face отсюда.
362
  # return result
363
 
364
- return output, M # Возвращаем лицо (256x256) и матрицу M
365
 
366
  def sort_by_order(face, order: str):
367
  if order == "left-right":
 
306
  M = get_affine_transform(target_landmarks_5.astype(np.float32), std_landmarks_256)
307
  logger.debug("Affine Matrix M (used for cropping):\n%s", M)
308
 
 
 
 
 
309
  # Применяем аффинное преобразование с новой матрицей M
310
  crop = cv2.warpAffine(target_img, M, (256, 256), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REFLECT)
311
 
312
  # Визуализация crop перед инференсом
313
  #### Что проверить:
314
+ # Окно `"Crop Before Inference"` должно показывать лицо, вырезанное по аффинному преобразованию.
315
+ # Если изображение черное — проблема в `M` или `target_landmarks_5`.
316
  logger.debug("Crop shape: %s | Min: %s | Max: %s", crop.shape, crop.min(), crop.max())
317
  # cv2.imshow("Crop Before Inference", crop)
318
  # cv2.waitKey(1) # Отображает изображение
 
334
  logger.error("Ошибка выполнения модели: %s", e)
335
  return target_img
336
 
337
+ # --- CPU FLOAT NORMALIZATION FIX ---
338
+ # предотвращает появление "синей кожи" и "шума" при работе на CPU
339
+ # (адаптировано из патча patch_cpu_fix.diff)
340
+ if isinstance(output, np.ndarray):
341
+ # устранение NaN и бесконечностей
342
+ output = np.nan_to_num(output, nan=0.0, posinf=255.0, neginf=0.0)
343
+
344
+ # если диапазон похож на [-1,1] → нормализуем в [0,255]
345
+ if output.min() < 0.0 or output.max() <= 1.5:
346
+ output = ((output + 1.0) / 2.0 * 255.0)
347
+
348
+ # жёсткое ограничение диапазона и тип для OpenCV
349
+ output = np.clip(output, 0, 255).astype(np.uint8).copy()
350
+
351
+ # защита от повторного использования буфера (inplace CPU bug)
352
+ try:
353
+ output.setflags(write=True)
354
+ except Exception:
355
+ pass
356
+
357
+ # 6. Обратная нормализация (теперь output уже uint8, просто transpose и BGR)
358
+ # (ваш код без изменений, но без старой денормализации)
359
  output = output.transpose(1, 2, 0) # CHW -> HWC
360
+ output = output[:, :, ::-1] # RGB -> BGR (Убедитесь, что это BGR, если вход был BGR)
361
 
362
  # Визуализация после денормализации
363
+ #### Что проверить:
364
+ # `output` должен быть в диапазоне `[0..255]` и содержать лицо.
365
+ # Если `output` черный — проблема в нормализации/денормализации или в самой модели.
366
  logger.debug("Output after denormalization: Min: %s | Max: %s", output.min(), output.max())
367
  # cv2.imshow("Output After Denormalization", output)
368
  # cv2.waitKey(1)
369
 
370
+ # 7. Возвращаем результат 256x256 И матрицу M
371
  # Мы больше не вызываем warp_and_paste_face отсюда.
372
  # return result
373
 
374
+ return output, M # Возвращаем лицо (256x256) и матрицу M
375
 
376
  def sort_by_order(face, order: str):
377
  if order == "left-right":