DegMaTsu commited on
Commit
99c9e8c
·
verified ·
1 Parent(s): 6588d10

Upload 2 files

Browse files
custom_nodes/comfyui-reactor-node/scripts/reactor_logger.py CHANGED
@@ -1,47 +1,54 @@
1
- import logging
2
- import copy
3
- import sys
4
-
5
- from modules import shared
6
- from reactor_utils import addLoggingLevel
7
-
8
-
9
- class ColoredFormatter(logging.Formatter):
10
- COLORS = {
11
- "DEBUG": "\033[0;36m", # CYAN
12
- "STATUS": "\033[38;5;173m", # Calm ORANGE
13
- "INFO": "\033[0;32m", # GREEN
14
- "WARNING": "\033[0;33m", # YELLOW
15
- "ERROR": "\033[0;31m", # RED
16
- "CRITICAL": "\033[0;37;41m", # WHITE ON RED
17
- "RESET": "\033[0m", # RESET COLOR
18
- }
19
-
20
- def format(self, record):
21
- colored_record = copy.copy(record)
22
- levelname = colored_record.levelname
23
- seq = self.COLORS.get(levelname, self.COLORS["RESET"])
24
- colored_record.levelname = f"{seq}{levelname}{self.COLORS['RESET']}"
25
- return super().format(colored_record)
26
-
27
-
28
- # Create a new logger
29
- logger = logging.getLogger("ReActor")
30
- logger.propagate = False
31
-
32
- # Add Custom Level
33
- # logging.addLevelName(logging.INFO, "STATUS")
34
- addLoggingLevel("STATUS", logging.INFO + 5)
35
-
36
- # Add handler if we don't have one.
37
- if not logger.handlers:
38
- handler = logging.StreamHandler(sys.stdout)
39
- handler.setFormatter(
40
- ColoredFormatter("[%(name)s] %(asctime)s - %(levelname)s - %(message)s",datefmt="%H:%M:%S")
41
- )
42
- logger.addHandler(handler)
43
-
44
- # Configure logger
45
- loglevel_string = getattr(shared.cmd_opts, "reactor_loglevel", "INFO")
46
- loglevel = getattr(logging, loglevel_string.upper(), "info")
47
- logger.setLevel(loglevel)
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import copy
3
+ import sys
4
+
5
+ from modules import shared
6
+ from reactor_utils import addLoggingLevel
7
+
8
+
9
+ class ColoredFormatter(logging.Formatter):
10
+ COLORS = {
11
+ "DEBUG": "\033[0;36m", # CYAN
12
+ "STATUS": "\033[38;5;173m", # Calm ORANGE
13
+ "INFO": "\033[0;32m", # GREEN
14
+ "WARNING": "\033[0;33m", # YELLOW
15
+ "ERROR": "\033[0;31m", # RED
16
+ "CRITICAL": "\033[0;37;41m", # WHITE ON RED
17
+ "RESET": "\033[0m", # RESET COLOR
18
+ }
19
+
20
+ def format(self, record):
21
+ colored_record = copy.copy(record)
22
+ levelname = colored_record.levelname
23
+ seq = self.COLORS.get(levelname, self.COLORS["RESET"])
24
+ colored_record.levelname = f"{seq}{levelname}{self.COLORS['RESET']}"
25
+ return super().format(colored_record)
26
+
27
+
28
+ # Create a new logger
29
+ logger = logging.getLogger("ReActor")
30
+ logger.propagate = False
31
+
32
+ # Add Custom Level
33
+ # logging.addLevelName(logging.INFO, "STATUS")
34
+ addLoggingLevel("STATUS", logging.INFO + 5)
35
+
36
+ # Add handler if we don't have one.
37
+ if not logger.handlers:
38
+ handler = logging.StreamHandler(sys.stdout)
39
+ handler.setFormatter(
40
+ ColoredFormatter("[%(name)s] %(asctime)s - %(levelname)s - %(message)s",datefmt="%H:%M:%S")
41
+ )
42
+ logger.addHandler(handler)
43
+
44
+ # Configure logger
45
+ loglevel_string = getattr(shared.cmd_opts, "reactor_loglevel", "INFO")
46
+ loglevel = getattr(logging, loglevel_string.upper(), "info")
47
+ # logger.setLevel(loglevel)
48
+ logger.setLevel(logging.DEBUG) # Принудительно устанавливаем DEBUG
49
+
50
+ # Добавим сообщение для проверки, что изменения применились
51
+ logger.warning("--- ReActor LOGGING FORCED TO DEBUG LEVEL ---")
52
+
53
+ # В конце файла reactor_logger.py
54
+ logger.debug("--- ТЕСТОВОЕ DEBUG СООБЩЕНИЕ ---")
custom_nodes/comfyui-reactor-node/scripts/reactor_swapper.py CHANGED
@@ -20,7 +20,7 @@ import comfy.model_management as model_management
20
  from modules.shared import state
21
 
22
  # 1. Добавьте импорт logging наверху файла, если его там нет:
23
- # import logging
24
  from scripts.reactor_logger import logger
25
  from reactor_utils import (
26
  move_path,
@@ -126,21 +126,9 @@ def getFaceSwapModel(model_path: str):
126
  if FS_MODEL is None or CURRENT_FS_MODEL_PATH is None or CURRENT_FS_MODEL_PATH != model_path:
127
  CURRENT_FS_MODEL_PATH = model_path
128
  FS_MODEL = unload_model(FS_MODEL)
129
-
130
- # Извлекаем имя файла модели из пути
131
- model_filename = os.path.basename(model_path)
132
-
133
- # Определяем правильный путь в зависимости от типа модели
134
- if "hyperswap" in model_filename.lower():
135
- # Ищем в директории hyperswap
136
- correct_path = os.path.join(folder_paths.models_dir, "hyperswap", model_filename)
137
- FS_MODEL = ort.InferenceSession(correct_path, providers=providers)
138
- elif "reswapper" in model_filename.lower():
139
- # Ищем в директории reswapper
140
- correct_path = os.path.join(folder_paths.models_dir, "reswapper", model_filename)
141
- FS_MODEL = insightface.model_zoo.get_model(correct_path, providers=providers)
142
  else:
143
- # Для моделей insightface используем оригинальный путь
144
  FS_MODEL = insightface.model_zoo.get_model(model_path, providers=providers)
145
  return FS_MODEL
146
 
@@ -149,10 +137,10 @@ def get_landmarks_5(face):
149
  # face.landmark_5: np.ndarray shape (5,2)
150
  # Если нет, попробуй face.kps или face.landmark
151
  if hasattr(face, 'landmark_5') and face.landmark_5 is not None:
152
- # logger.debug("landmark_5: %s", face.landmark_5)
153
  return face.landmark_5
154
  elif hasattr(face, 'kps') and face.kps is not None:
155
- # logger.debug("kps: %s", face.kps)
156
  return face.kps
157
  elif hasattr(face, 'landmark') and face.landmark is not None:
158
  # 68-точечная разметка, берём нужные индексы
@@ -160,9 +148,9 @@ def get_landmarks_5(face):
160
  # Пример: [36, 45, 30, 48, 54] — левый/правый глаз, нос, левый/правый рот
161
  if face.landmark.shape[0] >= 68:
162
  idxs = [36, 45, 30, 48, 54]
163
- # logger.debug("landmark (68 точек): %s", face.landmark[idxs])
164
  return face.landmark[idxs]
165
- # logger.warning("Нет подходящих точек в объекте Face. Доступные атрибуты: %s", dir(face))
166
  return None
167
 
168
  #### Что проверить:
@@ -190,14 +178,14 @@ def create_gradient_mask(crop_size=256):
190
 
191
  # 3. Рисуем эллипс (заполняем белым цветом, значение=1.0)
192
  cv2.ellipse(
193
- mask, # Массив для рисования
194
- center, # Центр эллипса
195
- axes, # Полуоси (ширина, высота)
196
- angle=0, # Угол поворота
197
- startAngle=0, # Начальный угол дуги
198
- endAngle=360, # Конечный угол дуги (360 = полный эллипс)
199
- color=1.0, # Значение для заполнения (белый = 1.0)
200
- thickness=-1 # -1 = заполнить всю область эллипса
201
  )
202
 
203
  # 4. Применяем размытие для плавных краёв
@@ -224,7 +212,7 @@ def paste_back(target_img, swapped_face, M, crop_size=256):
224
  mask = create_gradient_mask(crop_size)
225
 
226
  # Сохраняем для отладки
227
- # cv2.imwrite("debug_original_mask.png", (mask * 255).astype(np.uint8))
228
 
229
  # Преобразуем в трехканальную маску
230
  mask_3c = np.stack([mask] * 3, axis=2)
@@ -258,13 +246,13 @@ def paste_back(target_img, swapped_face, M, crop_size=256):
258
  inv_mask = cv2.GaussianBlur(inv_mask, (3, 3), 0)
259
 
260
  # Отладка
261
- # logger.debug("Warped face shape: %s | Min: %s | Max: %s", inv_face.shape, inv_face.min(), inv_face.max())
262
- # logger.debug("Warped mask shape: %s | Min: %s | Max: %s", inv_mask.shape, inv_mask.min(), inv_mask.max())
263
 
264
  # Визуализация
265
- # cv2.imshow("Warped Face", inv_face.astype(np.uint8))
266
- # cv2.imshow("Warped Mask", (inv_mask * 255).astype(np.uint8))
267
- # cv2.waitKey(1)
268
 
269
  # 6. Плавное наложение
270
  target_img_float = target_img.astype(np.float32)
@@ -275,7 +263,7 @@ def paste_back(target_img, swapped_face, M, crop_size=256):
275
  result = np.clip(result, 0, 255).astype(np.uint8)
276
 
277
  # Сохраняем результат
278
- # cv2.imwrite("debug_result.png", result)
279
 
280
  return result
281
 
@@ -288,8 +276,8 @@ def visualize_points(img, points, color=(0, 255, 0)):
288
  img = img.copy()
289
  for p in points:
290
  cv2.circle(img, tuple(p.astype(int)), 3, color, -1)
291
- # cv2.imshow("Face Points", img)
292
- # cv2.waitKey(1)
293
 
294
  # Итоговая функция run_hyperswap с аффинным преобразованием
295
  def run_hyperswap(session, source_face, target_face, target_img):
@@ -301,7 +289,7 @@ def run_hyperswap(session, source_face, target_face, target_img):
301
  visualize_points(target_img, target_landmarks_5, (0, 255, 0)) # Зеленые точки
302
 
303
  if target_landmarks_5 is None:
304
- # logger.error("Не удалось получить 5 точек для целевого лица")
305
  # Важно: Если ошибка, возвращаем None и исходную матрицу (или обрабатываем ошибку иначе)
306
  return None, None
307
 
@@ -316,7 +304,7 @@ def run_hyperswap(session, source_face, target_face, target_img):
316
 
317
  # Вычисляем аффинную матрицу
318
  M = get_affine_transform(target_landmarks_5.astype(np.float32), std_landmarks_256)
319
- # logger.debug("Affine Matrix M (used for cropping):\n%s", M)
320
 
321
  #### Что проверить:
322
  # Матрица `M` не должна содержать `NaN` или бесконечности.
@@ -329,9 +317,9 @@ def run_hyperswap(session, source_face, target_face, target_img):
329
  #### Что проверить:
330
  # Окно `"Crop Before Inference"` должно показывать лицо, вырезанное по аффинному преобразованию.
331
  # Если изображение черное — проблема в `M` или `target_landmarks_5`.
332
- # logger.debug("Crop shape: %s | Min: %s | Max: %s", crop.shape, crop.min(), crop.max())
333
- # cv2.imshow("Crop Before Inference", crop)
334
- # cv2.waitKey(1) # Отображает изображение
335
 
336
  # 4. Преобразуем crop для модели
337
  # crop_input = crop[:, :, ::-1] / 255.0
@@ -345,9 +333,9 @@ def run_hyperswap(session, source_face, target_face, target_img):
345
  # 5. Инференс
346
  try:
347
  output = session.run(None, {'source': source_embedding, 'target': crop_input})[0][0]
348
- # logger.debug("Model output shape: %s | Min: %s | Max: %s", output.shape, output.min(), output.max())
349
  except Exception as e:
350
- # logger.error("Ошибка выполнения модели: %s", e)
351
  return target_img
352
 
353
  # 6. Обратная нормализация
@@ -365,9 +353,9 @@ def run_hyperswap(session, source_face, target_face, target_img):
365
  #### Что проверить:
366
  # `output` должен быть в диапазоне `[0..255]` и содержать лицо.
367
  # Если `output` черный — проблема в нормализации/денормализации или в самой модели.
368
- # logger.debug("Output after denormalization: Min: %s | Max: %s", output.min(), output.max())
369
- # cv2.imshow("Output After Denormalization", output)
370
- # cv2.waitKey(1)
371
 
372
  # 7. ИЗМЕНЕНИЕ: Возвращаем результат 256x256 И матрицу M
373
  # Мы больше не вызываем warp_and_paste_face отсюда.
@@ -468,13 +456,13 @@ def get_face_single(img_data: np.ndarray, face, face_index=0, det_size=(640, 640
468
  try:
469
  faces_sorted = sort_by_order(face, order)
470
  selected_face = faces_sorted[face_index]
471
- # logger.debug("Выбрано лицо: bbox=%s, landmark_5=%s, kps=%s, landmark=%s",
472
- # selected_face.bbox,
473
- # hasattr(selected_face, "landmark_5"),
474
- # hasattr(selected_face, "kps"),
475
- # hasattr(selected_face, "landmark"))
476
  return selected_face, 0
477
- # return faces_sorted[face_index], 0
478
  # return sorted(face, key=lambda x: x.bbox[0])[face_index], 0
479
  except IndexError:
480
  return None, 0
@@ -496,14 +484,14 @@ def swap_face(
496
  codeformer_weight: float = 0.5,
497
  interpolation: str = "Bicubic",
498
  ):
499
- # >>>>> РЕШЕНИЕ: Принудительная установка уровня DEBUG <<<<<
500
- # if logger.getEffectiveLevel() != logging.DEBUG:
501
- # print("\n--- [ReActor Debug] Принудительная установка уровня логирования на DEBUG (10) в swap_face ---")
502
- # logger.setLevel(logging.DEBUG)
503
 
504
- # Проверочное сообщение (теперь оно должно появиться)
505
- # logger.debug("--- ТЕСТ: swap_face запущена, уровень логирования DEBUG активен. ---")
506
- # >>>>> КОНЕЦ РЕШЕНИЯ <<<<<
507
 
508
  global SOURCE_FACES, SOURCE_IMAGE_HASH, TARGET_FACES, TARGET_IMAGE_HASH
509
  result_image = target_img
@@ -625,7 +613,7 @@ def swap_face(
625
  if target_face is not None and wrong_gender == 0:
626
  logger.status(f"Swapping...")
627
  if "hyperswap" in model:
628
- # logger.status(f"Swapping with Hyperswap...")
629
  swapped_face_256, M = run_hyperswap(face_swapper, source_face, target_face, result)
630
  if swapped_face_256 is not None:
631
  result = paste_back(result, swapped_face_256, M, crop_size=256)
@@ -811,17 +799,7 @@ def swap_face_many(
811
  logger.status(f'Source Faces must have no entries (default=0), one entry, or same number of entries as target faces.')
812
  elif source_face is not None:
813
  results = target_imgs
814
-
815
- # Определяем путь к модели в зависимости от типа
816
- if "inswapper" in model:
817
- model_path = os.path.join(insightface_path, model)
818
- elif "reswapper" in model:
819
- model_path = os.path.join(reswapper_path, model)
820
- elif "hyperswap" in model:
821
- model_path = os.path.join(hyperswap_path, model)
822
- else:
823
- model_path = os.path.join(insightface_path, model)
824
-
825
  face_swapper = getFaceSwapModel(model_path)
826
 
827
  source_face_idx = 0
@@ -845,23 +823,16 @@ def swap_face_many(
845
  target_face_single, wrong_gender = get_face_single(target_img, target_face, face_index=face_num, gender_target=gender_target, order=faces_order[0])
846
  if target_face_single is not None and wrong_gender == 0:
847
  result = target_img
848
-
849
- # Обработка в зависимости от типа модели
850
- if "hyperswap" in model:
851
- # Для Hyperswap используем специальную функцию
852
- swapped_face_256, M = run_hyperswap(face_swapper, source_face, target_face_single, result)
853
- if swapped_face_256 is not None:
854
- result = paste_back(result, swapped_face_256, M, crop_size=256)
855
- elif face_boost_enabled:
856
  logger.status(f"Face Boost is enabled")
857
  bgr_fake, M = face_swapper.get(target_img, target_face_single, source_face, paste_back=False)
858
  bgr_fake, scale = restorer.get_restored_face(bgr_fake, face_restore_model, face_restore_visibility, codeformer_weight, interpolation)
859
  M *= scale
860
  result = swapper.in_swap(target_img, bgr_fake, M)
861
  else:
862
- # Для остальных моделей используем метод get()
863
  result = face_swapper.get(target_img, target_face_single, source_face)
864
-
865
  results[i] = result
866
  pbar.update(1)
867
  elif wrong_gender == 1:
 
20
  from modules.shared import state
21
 
22
  # 1. Добавьте импорт logging наверху файла, если его там нет:
23
+ import logging
24
  from scripts.reactor_logger import logger
25
  from reactor_utils import (
26
  move_path,
 
126
  if FS_MODEL is None or CURRENT_FS_MODEL_PATH is None or CURRENT_FS_MODEL_PATH != model_path:
127
  CURRENT_FS_MODEL_PATH = model_path
128
  FS_MODEL = unload_model(FS_MODEL)
129
+ if "hyperswap" in model_path.lower():
130
+ FS_MODEL = ort.InferenceSession(model_path, providers=providers)
 
 
 
 
 
 
 
 
 
 
 
131
  else:
 
132
  FS_MODEL = insightface.model_zoo.get_model(model_path, providers=providers)
133
  return FS_MODEL
134
 
 
137
  # face.landmark_5: np.ndarray shape (5,2)
138
  # Если нет, попробуй face.kps или face.landmark
139
  if hasattr(face, 'landmark_5') and face.landmark_5 is not None:
140
+ logger.debug("landmark_5: %s", face.landmark_5)
141
  return face.landmark_5
142
  elif hasattr(face, 'kps') and face.kps is not None:
143
+ logger.debug("kps: %s", face.kps)
144
  return face.kps
145
  elif hasattr(face, 'landmark') and face.landmark is not None:
146
  # 68-точечная разметка, берём нужные индексы
 
148
  # Пример: [36, 45, 30, 48, 54] — левый/правый глаз, нос, левый/правый рот
149
  if face.landmark.shape[0] >= 68:
150
  idxs = [36, 45, 30, 48, 54]
151
+ logger.debug("landmark (68 точек): %s", face.landmark[idxs])
152
  return face.landmark[idxs]
153
+ logger.warning("Нет подходящих точек в объекте Face. Доступные атрибуты: %s", dir(face))
154
  return None
155
 
156
  #### Что проверить:
 
178
 
179
  # 3. Рисуем эллипс (заполняем белым цветом, значение=1.0)
180
  cv2.ellipse(
181
+ mask,
182
+ center,
183
+ axes,
184
+ angle=0,
185
+ startAngle=0,
186
+ endAngle=360,
187
+ color=1.0,
188
+ thickness=-1
189
  )
190
 
191
  # 4. Применяем размытие для плавных краёв
 
212
  mask = create_gradient_mask(crop_size)
213
 
214
  # Сохраняем для отладки
215
+ cv2.imwrite("debug_original_mask.png", (mask * 255).astype(np.uint8))
216
 
217
  # Преобразуем в трехканальную маску
218
  mask_3c = np.stack([mask] * 3, axis=2)
 
246
  inv_mask = cv2.GaussianBlur(inv_mask, (3, 3), 0)
247
 
248
  # Отладка
249
+ logger.debug("Warped face shape: %s | Min: %s | Max: %s", inv_face.shape, inv_face.min(), inv_face.max())
250
+ logger.debug("Warped mask shape: %s | Min: %s | Max: %s", inv_mask.shape, inv_mask.min(), inv_mask.max())
251
 
252
  # Визуализация
253
+ # cv2.imshow("Warped Face", inv_face.astype(np.uint8))
254
+ # cv2.imshow("Warped Mask", (inv_mask * 255).astype(np.uint8))
255
+ # cv2.waitKey(1)
256
 
257
  # 6. Плавное наложение
258
  target_img_float = target_img.astype(np.float32)
 
263
  result = np.clip(result, 0, 255).astype(np.uint8)
264
 
265
  # Сохраняем результат
266
+ cv2.imwrite("debug_result.png", result)
267
 
268
  return result
269
 
 
276
  img = img.copy()
277
  for p in points:
278
  cv2.circle(img, tuple(p.astype(int)), 3, color, -1)
279
+ # cv2.imshow("Face Points", img)
280
+ # cv2.waitKey(1)
281
 
282
  # Итоговая функция run_hyperswap с аффинным преобразованием
283
  def run_hyperswap(session, source_face, target_face, target_img):
 
289
  visualize_points(target_img, target_landmarks_5, (0, 255, 0)) # Зеленые точки
290
 
291
  if target_landmarks_5 is None:
292
+ logger.error("Не удалось получить 5 точек для целевого лица")
293
  # Важно: Если ошибка, возвращаем None и исходную матрицу (или обрабатываем ошибку иначе)
294
  return None, None
295
 
 
304
 
305
  # Вычисляем аффинную матрицу
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` или бесконечности.
 
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) # Отображает изображение
323
 
324
  # 4. Преобразуем crop для модели
325
  # crop_input = crop[:, :, ::-1] / 255.0
 
333
  # 5. Инференс
334
  try:
335
  output = session.run(None, {'source': source_embedding, 'target': crop_input})[0][0]
336
+ logger.debug("Model output shape: %s | Min: %s | Max: %s", output.shape, output.min(), output.max())
337
  except Exception as e:
338
+ logger.error("Ошибка выполнения модели: %s", e)
339
  return target_img
340
 
341
  # 6. Обратная нормализация
 
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 отсюда.
 
456
  try:
457
  faces_sorted = sort_by_order(face, order)
458
  selected_face = faces_sorted[face_index]
459
+ logger.debug("Выбрано лицо: bbox=%s, landmark_5=%s, kps=%s, landmark=%s",
460
+ selected_face.bbox,
461
+ hasattr(selected_face, "landmark_5"),
462
+ hasattr(selected_face, "kps"),
463
+ hasattr(selected_face, "landmark"))
464
  return selected_face, 0
465
+ return faces_sorted[face_index], 0
466
  # return sorted(face, key=lambda x: x.bbox[0])[face_index], 0
467
  except IndexError:
468
  return None, 0
 
484
  codeformer_weight: float = 0.5,
485
  interpolation: str = "Bicubic",
486
  ):
487
+ # >>>>> РЕШЕНИЕ: Принудительная установка уровня DEBUG <<<<<
488
+ if logger.getEffectiveLevel() != logging.DEBUG:
489
+ print("\n--- [ReActor Debug] Принудительная установка уровня логирования на DEBUG (10) в swap_face ---")
490
+ logger.setLevel(logging.DEBUG)
491
 
492
+ # Проверочное сообщение (теперь оно должно появиться)
493
+ logger.debug("--- ТЕСТ: swap_face запущена, уровень логирования DEBUG активен. ---")
494
+ # >>>>> КОНЕЦ РЕШЕНИЯ <<<<<
495
 
496
  global SOURCE_FACES, SOURCE_IMAGE_HASH, TARGET_FACES, TARGET_IMAGE_HASH
497
  result_image = target_img
 
613
  if target_face is not None and wrong_gender == 0:
614
  logger.status(f"Swapping...")
615
  if "hyperswap" in model:
616
+ logger.status(f"Swapping with Hyperswap...")
617
  swapped_face_256, M = run_hyperswap(face_swapper, source_face, target_face, result)
618
  if swapped_face_256 is not None:
619
  result = paste_back(result, swapped_face_256, M, crop_size=256)
 
799
  logger.status(f'Source Faces must have no entries (default=0), one entry, or same number of entries as target faces.')
800
  elif source_face is not None:
801
  results = target_imgs
802
+ model_path = model_path = os.path.join(insightface_path, model)
 
 
 
 
 
 
 
 
 
 
803
  face_swapper = getFaceSwapModel(model_path)
804
 
805
  source_face_idx = 0
 
823
  target_face_single, wrong_gender = get_face_single(target_img, target_face, face_index=face_num, gender_target=gender_target, order=faces_order[0])
824
  if target_face_single is not None and wrong_gender == 0:
825
  result = target_img
826
+ # logger.status(f"Swapping {i}...")
827
+ if face_boost_enabled:
 
 
 
 
 
 
828
  logger.status(f"Face Boost is enabled")
829
  bgr_fake, M = face_swapper.get(target_img, target_face_single, source_face, paste_back=False)
830
  bgr_fake, scale = restorer.get_restored_face(bgr_fake, face_restore_model, face_restore_visibility, codeformer_weight, interpolation)
831
  M *= scale
832
  result = swapper.in_swap(target_img, bgr_fake, M)
833
  else:
834
+ # logger.status(f"Swapping as-is")
835
  result = face_swapper.get(target_img, target_face_single, source_face)
 
836
  results[i] = result
837
  pbar.update(1)
838
  elif wrong_gender == 1: