devkunalnaik commited on
Commit
d5e1b6d
·
1 Parent(s): a068458

Quality: increase output resolution to 2048px, Lanczos upscale, adaptive unsharp mask

Browse files
Files changed (2) hide show
  1. processors/face_swap.py +26 -10
  2. utils/image_utils.py +2 -2
processors/face_swap.py CHANGED
@@ -141,13 +141,15 @@ class FaceSwapper:
141
 
142
  roi = result[y1:y2, x1:x2].copy()
143
 
144
- # 1. Unsharp mask (amount=1.4, radius=3)
145
- blurred = cv2.GaussianBlur(roi, (0, 0), 3)
146
- sharp = cv2.addWeighted(roi, 2.4, blurred, -1.4, 0)
 
 
147
 
148
  # 2. CLAHE on L channel
149
  lab = cv2.cvtColor(sharp, cv2.COLOR_BGR2LAB)
150
- clahe = cv2.createCLAHE(clipLimit=1.5, tileGridSize=(4, 4))
151
  lab[:, :, 0] = clahe.apply(lab[:, :, 0])
152
  enhanced_roi = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
153
 
@@ -181,12 +183,18 @@ class FaceSwapper:
181
  self._init()
182
 
183
  try:
184
- # Resize to optimal resolution (too large = slow; too small = blurry)
185
- MAX_DIM = 1280
186
- h, w = target_bgr.shape[:2]
187
- if max(h, w) > MAX_DIM:
188
- scale = MAX_DIM / max(h, w)
189
- target_bgr = cv2.resize(target_bgr, (int(w * scale), int(h * scale)))
 
 
 
 
 
 
190
 
191
  source_faces = self._app.get(source_bgr)
192
  target_faces = self._app.get(target_bgr)
@@ -208,6 +216,14 @@ class FaceSwapper:
208
  if enhance:
209
  result = self._enhance_opencv(result, target_faces)
210
 
 
 
 
 
 
 
 
 
211
  return result, f"Swapped {len(target_faces)} face(s) successfully."
212
 
213
  except Exception as exc:
 
141
 
142
  roi = result[y1:y2, x1:x2].copy()
143
 
144
+ # 1. Unsharp mask scale radius with face size for consistent sharpness
145
+ face_short = min(x2 - x1, y2 - y1)
146
+ sigma = max(1.5, face_short / 80) # larger face → larger radius
147
+ blurred = cv2.GaussianBlur(roi, (0, 0), sigma)
148
+ sharp = cv2.addWeighted(roi, 1.8, blurred, -0.8, 0)
149
 
150
  # 2. CLAHE on L channel
151
  lab = cv2.cvtColor(sharp, cv2.COLOR_BGR2LAB)
152
+ clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
153
  lab[:, :, 0] = clahe.apply(lab[:, :, 0])
154
  enhanced_roi = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
155
 
 
183
  self._init()
184
 
185
  try:
186
+ # Preserve full resolution up to 2048px on the longest side.
187
+ # Going beyond that adds little visible quality on CPU but multiplies time.
188
+ MAX_DIM = 2048
189
+ orig_h, orig_w = target_bgr.shape[:2]
190
+ scale_down = 1.0
191
+ if max(orig_h, orig_w) > MAX_DIM:
192
+ scale_down = MAX_DIM / max(orig_h, orig_w)
193
+ target_bgr = cv2.resize(
194
+ target_bgr,
195
+ (int(orig_w * scale_down), int(orig_h * scale_down)),
196
+ interpolation=cv2.INTER_LANCZOS4,
197
+ )
198
 
199
  source_faces = self._app.get(source_bgr)
200
  target_faces = self._app.get(target_bgr)
 
216
  if enhance:
217
  result = self._enhance_opencv(result, target_faces)
218
 
219
+ # If we downscaled, upscale back to original resolution with Lanczos
220
+ if scale_down < 1.0:
221
+ result = cv2.resize(
222
+ result,
223
+ (orig_w, orig_h),
224
+ interpolation=cv2.INTER_LANCZOS4,
225
+ )
226
+
227
  return result, f"Swapped {len(target_faces)} face(s) successfully."
228
 
229
  except Exception as exc:
utils/image_utils.py CHANGED
@@ -14,13 +14,13 @@ def bgr_to_pil(bgr_img: np.ndarray) -> Image.Image:
14
  return Image.fromarray(cv2.cvtColor(bgr_img, cv2.COLOR_BGR2RGB))
15
 
16
 
17
- def resize_to_max(image: np.ndarray, max_size: int = 1280) -> np.ndarray:
18
  """Downscale image so its longest side does not exceed max_size."""
19
  h, w = image.shape[:2]
20
  if max(h, w) <= max_size:
21
  return image
22
  scale = max_size / max(h, w)
23
- return cv2.resize(image, (int(w * scale), int(h * scale)), interpolation=cv2.INTER_AREA)
24
 
25
 
26
  def apply_color_correction(source: np.ndarray, target: np.ndarray, mask: np.ndarray) -> np.ndarray:
 
14
  return Image.fromarray(cv2.cvtColor(bgr_img, cv2.COLOR_BGR2RGB))
15
 
16
 
17
+ def resize_to_max(image: np.ndarray, max_size: int = 2048) -> np.ndarray:
18
  """Downscale image so its longest side does not exceed max_size."""
19
  h, w = image.shape[:2]
20
  if max(h, w) <= max_size:
21
  return image
22
  scale = max_size / max(h, w)
23
+ return cv2.resize(image, (int(w * scale), int(h * scale)), interpolation=cv2.INTER_LANCZOS4)
24
 
25
 
26
  def apply_color_correction(source: np.ndarray, target: np.ndarray, mask: np.ndarray) -> np.ndarray: