Khan19970 commited on
Commit
56c7c0d
Β·
verified Β·
1 Parent(s): 1685a54

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +59 -25
main.py CHANGED
@@ -144,6 +144,43 @@ def generate_shadow(car_rgba, bg, paste_pos, actual_tyre_y, v_type="low"):
144
  shadow_rgba = np.zeros((bg_h, bg_w, 4), dtype=np.uint8)
145
  shadow_rgba[..., 3] = (np.clip(shadow_canvas, 0, 1) * 220).astype(np.uint8)
146
  return Image.fromarray(shadow_rgba, "RGBA")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  # ──────────────────────────────────────────────────────────────────
149
  # CORE PIPELINE & POSITIONING
@@ -203,51 +240,48 @@ def auto_position_car(car_rgba: Image.Image, bg: Image.Image):
203
  return car_res, (px, py), tyre_y
204
 
205
  def run_pipeline(car_pil, bg_pil):
206
- # Standardize sizes
207
  car_pil = car_pil.resize((1024, int(1024 * car_pil.height/car_pil.width)), Image.LANCZOS)
208
  bg_pil = bg_pil.resize((1600, int(1600 * bg_pil.height/bg_pil.width)), Image.LANCZOS)
209
 
210
- # 1. Classification (New)
211
  v_type = classify_vehicle(car_pil)
212
- logger.info(f"Detected Vehicle Type: {v_type}")
213
-
214
  # 2. Segmentation
215
- import torch
216
  bundle = get_model("birefnet")
217
- orig_w, orig_h = car_pil.size
218
  inp = bundle["transform"](car_pil.convert("RGB")).unsqueeze(0).to(bundle["device"]).float()
219
  with torch.no_grad():
220
  bundle["model"].float()
221
- # inp = inp.float()
222
  preds = bundle["model"](inp)
223
  mask = torch.sigmoid(preds[-1]).squeeze().cpu().numpy()
224
- mask = cv2.resize(mask, (orig_w, orig_h))
225
 
226
- car_rgb = np.array(car_pil.convert("RGB"))
227
- car_rgba = Image.fromarray(np.dstack([car_rgb, (mask*255).astype(np.uint8)]), "RGBA")
228
-
229
- # 3. Positioning
230
- car_positioned, pos, actual_tyre_y = auto_position_car(car_rgba, bg_pil)
 
231
 
232
- # 4. Color Matching
233
  c_arr = np.array(car_positioned)
234
  rgb_fixed = harmonize_color(c_arr[..., :3], c_arr[..., 3]/255.0, np.array(bg_pil))
235
  car_final = Image.fromarray(np.dstack([rgb_fixed, c_arr[..., 3]]), "RGBA")
 
 
 
236
 
237
- # 5. Dynamic Shadow Generation
238
- shadow_layer = generate_shadow(car_final, bg_pil, pos, actual_tyre_y, v_type=v_type)
 
239
 
240
- # 6. Final Compositing
241
- bg_np = np.array(bg_pil.convert("RGB")).astype(np.float32)
242
- sh_np = np.array(shadow_layer).astype(np.float32)
243
- sh_alpha = (sh_np[..., 3] / 255.0)[..., None]
244
 
245
- # Multiply effect for shadow
246
- darkened_bg = bg_np * (1.0 - sh_alpha * 0.92)
247
- output_img = Image.fromarray(darkened_bg.astype(np.uint8))
248
- output_img.paste(car_final, pos, car_final)
249
 
250
- return output_img.convert("RGB")
251
 
252
  @app.post("/composite")
253
  async def composite(car_image: UploadFile = File(...), background_image: UploadFile = File(...)):
 
144
  shadow_rgba = np.zeros((bg_h, bg_w, 4), dtype=np.uint8)
145
  shadow_rgba[..., 3] = (np.clip(shadow_canvas, 0, 1) * 220).astype(np.uint8)
146
  return Image.fromarray(shadow_rgba, "RGBA")
147
+ # ──────────────────────────────────────────────────────────────────
148
+ # NEW: SPYNE-GRADE SHADOW & REFLECTION LOGIC
149
+ # ──────────────────────────────────────────────────────────────────
150
+
151
+ def extract_original_shadow(car_pil, mask_np):
152
+ """Original photo se asli shadow nikalne ka logic."""
153
+ orig_np = np.array(car_pil.convert("L")) # Grayscale
154
+ # Mask ko thora phailao (dilate) taake tires ke niche ka area mil jaye
155
+ kernel = np.ones((20,20), np.uint8)
156
+ dilated_mask = cv2.dilate(mask_np, kernel, iterations=2)
157
+ shadow_area_mask = dilated_mask - mask_np
158
+
159
+ # Shadow map: Light areas ko white aur dark areas (shadow) ko black/gray karo
160
+ # Original ground agar whiteish hai toh ye bohot acha kaam karta hai
161
+ shadow_map = orig_np.astype(float) / 255.0
162
+ shadow_map = np.clip(shadow_map * 1.2, 0, 1) # Contrast barhao
163
+ return shadow_map, shadow_area_mask
164
+
165
+ def generate_reflection(car_rgba, bg_size, pos):
166
+ """Car ki halki si perchaayi (reflection) floor par."""
167
+ bg_w, bg_h = bg_size
168
+ cw, ch = car_rgba.size
169
+ px, py = pos
170
+
171
+ # Car ko flip karo aur blur kardo
172
+ reflection = car_rgba.transpose(Image.FLIP_TOP_BOTTOM)
173
+ reflection = reflection.resize((cw, int(ch * 0.3)), Image.LANCZOS)
174
+
175
+ # Reflection Canvas
176
+ refl_canvas = Image.new("RGBA", (bg_w, bg_h), (0,0,0,0))
177
+ # Car ke bilkul niche paste karo (tyre line par)
178
+ refl_canvas.paste(reflection, (px, py + ch - 5))
179
+
180
+ # Bohat halki opacity (Spyne level is 5-10%)
181
+ refl_np = np.array(refl_canvas).astype(np.float32)
182
+ refl_np[..., 3] *= 0.08
183
+ return Image.fromarray(refl_np.astype(np.uint8), "RGBA")
184
 
185
  # ──────────────────────────────────────────────────────────────────
186
  # CORE PIPELINE & POSITIONING
 
240
  return car_res, (px, py), tyre_y
241
 
242
  def run_pipeline(car_pil, bg_pil):
243
+ # 1. Standardize
244
  car_pil = car_pil.resize((1024, int(1024 * car_pil.height/car_pil.width)), Image.LANCZOS)
245
  bg_pil = bg_pil.resize((1600, int(1600 * bg_pil.height/bg_pil.width)), Image.LANCZOS)
246
 
 
247
  v_type = classify_vehicle(car_pil)
248
+
 
249
  # 2. Segmentation
 
250
  bundle = get_model("birefnet")
 
251
  inp = bundle["transform"](car_pil.convert("RGB")).unsqueeze(0).to(bundle["device"]).float()
252
  with torch.no_grad():
253
  bundle["model"].float()
 
254
  preds = bundle["model"](inp)
255
  mask = torch.sigmoid(preds[-1]).squeeze().cpu().numpy()
256
+ mask = cv2.resize(mask, car_pil.size)
257
 
258
+ # 3. Extract Original Shadow (Secret Sauce)
259
+ orig_shadow_map, shadow_mask = extract_original_shadow(car_pil, mask)
260
+
261
+ # 4. Positioning
262
+ car_rgba_temp = Image.fromarray(np.dstack([np.array(car_pil), (mask*255).astype(np.uint8)]), "RGBA")
263
+ car_positioned, pos, actual_tyre_y = auto_position_car(car_rgba_temp, bg_pil)
264
 
265
+ # 5. Color Matching
266
  c_arr = np.array(car_positioned)
267
  rgb_fixed = harmonize_color(c_arr[..., :3], c_arr[..., 3]/255.0, np.array(bg_pil))
268
  car_final = Image.fromarray(np.dstack([rgb_fixed, c_arr[..., 3]]), "RGBA")
269
+
270
+ # 6. COMPOSITING LAYERS (Spyne Style)
271
+ bg_final = bg_pil.convert("RGBA")
272
 
273
+ # Layer A: Ambient Shadow (Jo humne pehle banayi thi)
274
+ ambient_layer = generate_shadow(car_final, bg_pil, pos, actual_tyre_y, v_type=v_type)
275
+ bg_final = Image.alpha_composite(bg_final, ambient_layer)
276
 
277
+ # Layer B: Reflection (New)
278
+ reflection_layer = generate_reflection(car_final, bg_pil.size, pos)
279
+ bg_final = Image.alpha_composite(bg_final, reflection_layer)
 
280
 
281
+ # Layer C: The Car
282
+ bg_final.paste(car_final, pos, car_final)
 
 
283
 
284
+ return bg_final.convert("RGB")
285
 
286
  @app.post("/composite")
287
  async def composite(car_image: UploadFile = File(...), background_image: UploadFile = File(...)):