RedBottle13 commited on
Commit
44b24c9
·
verified ·
1 Parent(s): 58ee01c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -164
app.py CHANGED
@@ -196,54 +196,6 @@ def add_hats_sticker(img_bgr, sticker_path, faces):
196
 
197
  return img_with_stickers
198
 
199
- def add_headbands_sticker(img_bgr, sticker_path, faces):
200
- headband_pil = Image.open(sticker_path)
201
-
202
- # Check the color mode and convert to RGBA
203
- headband_rgba = headband_pil.convert('RGBA')
204
-
205
- # Convert the headband_rgba to BGRA
206
- r, g, b, a = headband_rgba.split()
207
- headband_bgra = Image.merge("RGBA", (b, g, r, a))
208
-
209
- # A copy of the original image
210
- img_with_stickers = img_bgr.copy()
211
-
212
- for face in faces:
213
- landmarks = face_landmarking(img_bgr, face)
214
-
215
- # Determine the forehead region using landmarks
216
- # Assuming the headband will be placed between the temples
217
- left_temple = landmarks.part(0)
218
- right_temple = landmarks.part(16)
219
-
220
- # Calculate the width of the headband based on the temples
221
- headband_width = int(abs(left_temple.x - right_temple.x) * 1.6)
222
- headband_height = int(headband_width * headband_bgra.height / headband_bgra.width)
223
-
224
- # Resize the headband image
225
- resized_headband = headband_bgra.resize((headband_width, headband_height))
226
-
227
- # Calculate the angle of tilt using the eyes as reference
228
- left_eye_indices = range(36, 42)
229
- right_eye_indices = range(42, 48)
230
- angle = calculate_eye_angle(landmarks, left_eye_indices, right_eye_indices)
231
-
232
- # Rotate the headband image
233
- rotated_headband = resized_headband.rotate(-angle, expand=True, resample=Image.BICUBIC)
234
-
235
- # Calculate the position for the headband
236
- x1 = (left_temple.x + right_temple.x) // 2 - (headband_width // 2)
237
- y1 = left_temple.y - (headband_height // 2)
238
-
239
- # Convert PIL image to NumPy array
240
- headband_np = np.array(rotated_headband)
241
-
242
- # Overlay the headband on the image
243
- img_with_stickers = overlay_transparent(img_with_stickers, headband_np, x1, y1)
244
-
245
- return img_with_stickers
246
-
247
 
248
  # Function to add glasses stickers
249
  def add_glasses_sticker(img_bgr, sticker_path, faces):
@@ -410,83 +362,11 @@ def add_animal_faces_sticker(img_bgr, sticker_path, faces):
410
  return img_with_stickers
411
 
412
 
413
- # Function to process the image
414
- def process_image(image, sticker_choice):
415
- if sticker_choice:
416
- # add .png to the sticker_choice
417
- sticker_name = sticker_choice + '.png'
418
- # find sticker's category
419
- sticker_category = STICKER_TO_CATEGORY[sticker_name]
420
- # Path to the single sticker
421
- sticker_path = os.path.join('stickers',sticker_category, sticker_name)
422
-
423
- # Convert PIL image to OpenCV format BGR
424
- image_bgr = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
425
-
426
- # Detect faces
427
- faces = face_detecting(image_bgr)
428
- # print(sticker_category)
429
- if sticker_category == 'ears':
430
- img_with_stickers = add_ears_sticker(image_bgr, sticker_path, faces)
431
- elif sticker_category == 'glasses':
432
- img_with_stickers = add_glasses_sticker(image_bgr, sticker_path, faces)
433
- elif sticker_category == 'noses':
434
- img_with_stickers = add_noses_sticker(image_bgr, sticker_path, faces)
435
- elif sticker_category == 'headbands':
436
- img_with_stickers = add_ears_sticker(image_bgr, sticker_path, faces)
437
- else:
438
- img_with_stickers = add_glasses_sticker(image_bgr, sticker_path, faces)
439
- # Convert back to PIL image
440
- img_with_stickers_pil = Image.fromarray(cv2.cvtColor(img_with_stickers, cv2.COLOR_BGR2RGB))
441
- return img_with_stickers_pil
442
- else:
443
- return image
444
-
445
- def process_image_with_selections(image_input):
446
- # Convert PIL image to OpenCV format BGR
447
- image_bgr = cv2.cvtColor(np.array(image_input), cv2.COLOR_RGB2BGR)
448
-
449
- # Detect faces
450
- faces = face_detecting(image_bgr)
451
-
452
- # A copy of the original image to apply stickers on
453
- img_with_stickers = image_bgr.copy()
454
-
455
- for category, sticker_name in sticker_selections.items():
456
- if sticker_name: # Check if a sticker was selected in this category
457
- # the sticker file path
458
- sticker_path = os.path.join('stickers', category, sticker_name + '.png')
459
-
460
- # Apply the selected sticker based on its category
461
- if category == 'ears':
462
- img_with_stickers = add_ears_sticker(img_with_stickers, sticker_path, faces)
463
- elif category == 'glasses':
464
- img_with_stickers = add_glasses_sticker(img_with_stickers, sticker_path, faces)
465
- elif category == 'noses':
466
- img_with_stickers = add_noses_sticker(img_with_stickers, sticker_path, faces)
467
- elif category == 'headbands':
468
- img_with_stickers = add_hats_sticker(img_with_stickers, sticker_path, faces)
469
- elif category == 'hats':
470
- img_with_stickers = add_hats_sticker(img_with_stickers, sticker_path, faces)
471
- elif category == 'animal face':
472
- img_with_stickers = add_animal_faces_sticker(img_with_stickers, sticker_path, faces)
473
- else:
474
- img_with_stickers = img_with_stickers
475
- # Convert back to PIL image
476
- img_with_stickers_pil = Image.fromarray(cv2.cvtColor(img_with_stickers, cv2.COLOR_BGR2RGB))
477
-
478
- print("Selected stickers:")
479
- for category, selection in sticker_selections.items():
480
- print(f"{category}: {selection}")
481
-
482
- return img_with_stickers_pil
483
-
484
  # This dictionary will hold the user's sticker selections
485
- sticker_selections = {}
486
 
487
  # Function to update sticker selections
488
  def update_selections(category, selection):
489
- # sticker_selections[category] = selection
490
  sticker_selections[category] = None if selection == "None" else selection
491
  return ""
492
 
@@ -494,7 +374,6 @@ def update_selections(category, selection):
494
  def load_example_image(image_path):
495
  return gr.Image.from_file(image_path)
496
 
497
- from PIL import Image
498
 
499
  def resize_image(image, target_width, target_height):
500
  # Maintain aspect ratio
@@ -518,17 +397,6 @@ def get_face_crops(image_bgr, faces, target_width=500, target_height=130):
518
  return face_crops
519
 
520
 
521
- def get_face_crops2(image_bgr, faces):
522
- # Convert color space from BGR to RGB since OpenCV uses BGR by default
523
- image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
524
- face_crops = []
525
- for face in faces:
526
- # Extract the region of interest (the face) from the original image
527
- x, y, w, h = face.left(), face.top(), face.width(), face.height()
528
- face_crop = image_rgb[y:y+h, x:x+w]
529
- face_pil = Image.fromarray(face_crop)
530
- face_crops.append(face_pil)
531
- return face_crops
532
 
533
  # Function to process uploaded images and display face crops
534
  def process_and_show_faces(image_input):
@@ -565,23 +433,24 @@ def process_selected_faces(image_input, selected_face_indices):
565
  for category, sticker_name in sticker_selections.items():
566
  if sticker_name: # Check if a sticker was selected in this category
567
  # the sticker file path
568
- sticker_path = os.path.join('stickers', category, sticker_name + '.png')
569
-
570
- # Apply the selected sticker based on its category
571
- if category == 'ears':
572
- img_with_stickers = add_ears_sticker(img_with_stickers, sticker_path, faces)
573
- elif category == 'glasses':
574
- img_with_stickers = add_glasses_sticker(img_with_stickers, sticker_path, faces)
575
- elif category == 'noses':
576
- img_with_stickers = add_noses_sticker(img_with_stickers, sticker_path, faces)
577
- elif category == 'headbands':
578
- img_with_stickers = add_hats_sticker(img_with_stickers, sticker_path, faces)
579
- elif category == 'hats':
580
- img_with_stickers = add_hats_sticker(img_with_stickers, sticker_path, faces)
581
- elif category == 'animal face':
582
- img_with_stickers = add_animal_faces_sticker(img_with_stickers, sticker_path, faces)
583
- else:
584
- img_with_stickers = img_with_stickers
 
585
  # Convert back to PIL image
586
  img_with_stickers_pil = Image.fromarray(cv2.cvtColor(img_with_stickers, cv2.COLOR_BGR2RGB))
587
 
@@ -635,15 +504,44 @@ css = """
635
  }
636
  """
637
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
638
  # Create the Gradio interface
639
  with gr.Blocks(css=css) as demo:
640
 
641
  with gr.Row():
642
  with gr.Column():
643
  image_input = gr.Image(type="pil", label="Original Image")
 
 
 
 
 
644
  with gr.Column():
645
  output_image = gr.Image(label="Image with Stickers")
646
  # Prepare the checkboxes and image placeholders
 
647
  detect_faces_btn = gr.Button("Detect Faces")
648
 
649
  with gr.Row():
@@ -661,7 +559,8 @@ with gr.Blocks(css=css) as demo:
661
  process_button = gr.Button("Apply Stickers To Selected Faces")
662
 
663
  process_button.click(
664
- handle_face_selection,
 
665
  inputs=[image_input] + face_checkboxes,
666
  outputs=output_image
667
  )
@@ -682,20 +581,8 @@ with gr.Blocks(css=css) as demo:
682
  choices = [sticker.split('/')[-1].replace('.png', '') for sticker in stickers]
683
  radio = gr.Radio(label='', choices=choices, value="None", container=False, min_width=50, elem_classes="radio")
684
  radio.change(lambda selection, cat=category: update_selections(cat, selection), inputs=[radio], outputs=[])
 
685
 
686
- # function to clear all inputs and restart
687
- def clear_all():
688
- for i in range(MAX_EXPECTED_FACES):
689
- face_images[i].value = None
690
- face_checkboxes[i].value = False
691
- output_image.value = None
692
- for category in STICKER_TO_CATEGORY.values():
693
- sticker_selections[category] = None
694
- # radio.value = "None"
695
- print(sticker_selections)
696
-
697
-
698
- image_input.clear(fn=clear_all)
699
 
700
  demo.launch()
701
 
 
196
 
197
  return img_with_stickers
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
  # Function to add glasses stickers
201
  def add_glasses_sticker(img_bgr, sticker_path, faces):
 
362
  return img_with_stickers
363
 
364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  # This dictionary will hold the user's sticker selections
366
+ # sticker_selections = {}
367
 
368
  # Function to update sticker selections
369
  def update_selections(category, selection):
 
370
  sticker_selections[category] = None if selection == "None" else selection
371
  return ""
372
 
 
374
  def load_example_image(image_path):
375
  return gr.Image.from_file(image_path)
376
 
 
377
 
378
  def resize_image(image, target_width, target_height):
379
  # Maintain aspect ratio
 
397
  return face_crops
398
 
399
 
 
 
 
 
 
 
 
 
 
 
 
400
 
401
  # Function to process uploaded images and display face crops
402
  def process_and_show_faces(image_input):
 
433
  for category, sticker_name in sticker_selections.items():
434
  if sticker_name: # Check if a sticker was selected in this category
435
  # the sticker file path
436
+ if sticker_name != 'None':
437
+ sticker_path = os.path.join('stickers', category, sticker_name + '.png')
438
+
439
+ # Apply the selected sticker based on its category
440
+ if category == 'ears':
441
+ img_with_stickers = add_ears_sticker(img_with_stickers, sticker_path, faces)
442
+ elif category == 'glasses':
443
+ img_with_stickers = add_glasses_sticker(img_with_stickers, sticker_path, faces)
444
+ elif category == 'noses':
445
+ img_with_stickers = add_noses_sticker(img_with_stickers, sticker_path, faces)
446
+ elif category == 'headbands':
447
+ img_with_stickers = add_hats_sticker(img_with_stickers, sticker_path, faces)
448
+ elif category == 'hats':
449
+ img_with_stickers = add_hats_sticker(img_with_stickers, sticker_path, faces)
450
+ elif category == 'animal face':
451
+ img_with_stickers = add_animal_faces_sticker(img_with_stickers, sticker_path, faces)
452
+ else:
453
+ img_with_stickers = img_with_stickers
454
  # Convert back to PIL image
455
  img_with_stickers_pil = Image.fromarray(cv2.cvtColor(img_with_stickers, cv2.COLOR_BGR2RGB))
456
 
 
504
  }
505
  """
506
 
507
+ def handle_image_upload(image):
508
+ global sticker_selections
509
+ sticker_selections = {category: "None" for category in STICKER_PATHS.keys()}
510
+ print("reset sticker_selections called") # Reset selections when a new image is loaded
511
+ # Print out the sticker selections state for each category
512
+ for category, selection in sticker_selections.items():
513
+ print(f"{category}: {selection}")
514
+ return image
515
+
516
+ # Initialize the sticker selections dictionary
517
+ def initialize_sticker_selections():
518
+ return {
519
+ 'hats': None,
520
+ 'animal face': None,
521
+ 'ears': None,
522
+ 'glasses': None,
523
+ 'noses': None,
524
+ 'headbands': None
525
+ }
526
+
527
+
528
+ sticker_selections = initialize_sticker_selections()
529
+ radio_components = {}
530
  # Create the Gradio interface
531
  with gr.Blocks(css=css) as demo:
532
 
533
  with gr.Row():
534
  with gr.Column():
535
  image_input = gr.Image(type="pil", label="Original Image")
536
+ image_input.change(
537
+ handle_image_upload,
538
+ inputs=[image_input],
539
+ outputs=[image_input]
540
+ )
541
  with gr.Column():
542
  output_image = gr.Image(label="Image with Stickers")
543
  # Prepare the checkboxes and image placeholders
544
+
545
  detect_faces_btn = gr.Button("Detect Faces")
546
 
547
  with gr.Row():
 
559
  process_button = gr.Button("Apply Stickers To Selected Faces")
560
 
561
  process_button.click(
562
+ handle_face_selection,
563
+ # inputs=[image_input, face_checkboxes, sticker_selections],
564
  inputs=[image_input] + face_checkboxes,
565
  outputs=output_image
566
  )
 
581
  choices = [sticker.split('/')[-1].replace('.png', '') for sticker in stickers]
582
  radio = gr.Radio(label='', choices=choices, value="None", container=False, min_width=50, elem_classes="radio")
583
  radio.change(lambda selection, cat=category: update_selections(cat, selection), inputs=[radio], outputs=[])
584
+ radio_components[category] = radio # Store the radio component
585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
 
587
  demo.launch()
588