parokshsaxena commited on
Commit
5ca0873
β€’
1 Parent(s): d3da15b

intensity transfer instead of color

Browse files
Files changed (2) hide show
  1. app.py +5 -3
  2. src/background_processor.py +52 -0
app.py CHANGED
@@ -153,9 +153,7 @@ def start_tryon(human_img_dict,garm_img,garment_des, background_img, is_checked,
153
 
154
  #human_img_orig = human_img_dict["background"].convert("RGB") # ImageEditor
155
  human_img_orig = human_img_dict.convert("RGB") # Image
156
-
157
- if background_img:
158
- human_img_orig = BackgroundProcessor.color_transfer(human_img_orig, background_img)
159
 
160
  """
161
  # Derive HEIGHT & WIDTH such that width is not more than 1000. This will cater to both Shein images (4160x6240) of 3:4 AR and model standard images ( 768x1024 ) of 2:3 AR
@@ -186,6 +184,10 @@ def start_tryon(human_img_dict,garm_img,garment_des, background_img, is_checked,
186
  else:
187
  human_img = human_img_orig.resize((WIDTH, HEIGHT))
188
 
 
 
 
 
189
 
190
  if is_checked:
191
  # internally openpose_model is resizing human_img to resolution 384 if not passed as input
 
153
 
154
  #human_img_orig = human_img_dict["background"].convert("RGB") # ImageEditor
155
  human_img_orig = human_img_dict.convert("RGB") # Image
156
+
 
 
157
 
158
  """
159
  # Derive HEIGHT & WIDTH such that width is not more than 1000. This will cater to both Shein images (4160x6240) of 3:4 AR and model standard images ( 768x1024 ) of 2:3 AR
 
184
  else:
185
  human_img = human_img_orig.resize((WIDTH, HEIGHT))
186
 
187
+ # Do color transfer from background image for better image harmonization
188
+ if background_img:
189
+ human_img = BackgroundProcessor.intensity_transfer(human_img, background_img)
190
+
191
 
192
  if is_checked:
193
  # internally openpose_model is resizing human_img to resolution 384 if not passed as input
src/background_processor.py CHANGED
@@ -235,6 +235,11 @@ class BackgroundProcessor:
235
  @classmethod
236
  def color_transfer(cls, source_pil: Image, target_pil: Image) -> Image:
237
  source = ImageFormatConvertor.pil_to_cv2(source_pil)
 
 
 
 
 
238
  target = ImageFormatConvertor.pil_to_cv2(target_pil)
239
  source = cv2.cvtColor(source, cv2.COLOR_BGR2LAB)
240
  target = cv2.cvtColor(target, cv2.COLOR_BGR2LAB)
@@ -254,4 +259,51 @@ class BackgroundProcessor:
254
 
255
  res = cv2.cvtColor(result, cv2.COLOR_LAB2BGR)
256
  res_pil = ImageFormatConvertor.cv2_to_pil(res)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  return res_pil
 
235
  @classmethod
236
  def color_transfer(cls, source_pil: Image, target_pil: Image) -> Image:
237
  source = ImageFormatConvertor.pil_to_cv2(source_pil)
238
+ # Resize background image
239
+ width, height = source_pil.width, source_pil.height
240
+ target_pil = target_pil.convert("RGB")
241
+ target_pil = target_pil.resize((width, height))
242
+
243
  target = ImageFormatConvertor.pil_to_cv2(target_pil)
244
  source = cv2.cvtColor(source, cv2.COLOR_BGR2LAB)
245
  target = cv2.cvtColor(target, cv2.COLOR_BGR2LAB)
 
259
 
260
  res = cv2.cvtColor(result, cv2.COLOR_LAB2BGR)
261
  res_pil = ImageFormatConvertor.cv2_to_pil(res)
262
+ return res_pil
263
+
264
+ @classmethod
265
+ def intensity_transfer(cls, source_pil: Image, target_pil: Image) -> Image:
266
+ """
267
+ Transfers the intensity distribution from the target image to the source image.
268
+
269
+ Parameters:
270
+ source (np.ndarray): The source image (foreground) to be harmonized.
271
+ target (np.ndarray): The target image (background) whose intensity distribution is to be matched.
272
+ eps (float): A small value to avoid division by zero.
273
+
274
+ Returns:
275
+ np.ndarray: The intensity-transferred source image.
276
+ """
277
+ source = ImageFormatConvertor.pil_to_cv2(source_pil)
278
+ # Resize background image
279
+ width, height = source_pil.width, source_pil.height
280
+ target_pil = target_pil.convert("RGB")
281
+ target_pil = target_pil.resize((width, height))
282
+
283
+ target = ImageFormatConvertor.pil_to_cv2(target_pil)
284
+
285
+ source_lab = cv2.cvtColor(source, cv2.COLOR_BGR2LAB)
286
+ target_lab = cv2.cvtColor(target, cv2.COLOR_BGR2LAB)
287
+
288
+ # Compute the mean and standard deviation of the L channel (intensity) of the source and target images
289
+ source_mean, source_std = cv2.meanStdDev(source_lab[:, :, 0])
290
+ target_mean, target_std = cv2.meanStdDev(target_lab[:, :, 0])
291
+
292
+ # Reshape the mean and std to (1, 1, 1) so they can be broadcast correctly
293
+ source_mean = source_mean.reshape((1, 1, 1))
294
+ source_std = source_std.reshape((1, 1, 1))
295
+ target_mean = target_mean.reshape((1, 1, 1))
296
+ target_std = target_std.reshape((1, 1, 1))
297
+
298
+ # Transfer the intensity (L channel)
299
+ result_l = (source_lab[:, :, 0] - source_mean) * (target_std / source_std) + target_mean
300
+ result_l = np.clip(result_l, 0, 255).astype(np.uint8)
301
+
302
+ # Combine the transferred L channel with the original A and B channels
303
+ result_lab = np.copy(source_lab)
304
+ result_lab[:, :, 0] = result_l
305
+
306
+ # return cv2.cvtColor(result_lab, cv2.COLOR_LAB2BGR)
307
+ res = cv2.cvtColor(result_lab, cv2.COLOR_LAB2BGR)
308
+ res_pil = ImageFormatConvertor.cv2_to_pil(res)
309
  return res_pil