MonsterMMORPG's picture
Upload 50 files
9445995 verified
from retinaface import RetinaFace
from PIL import Image
import torch
def auto_crop_image(image_path=r"F:\V_Express_V1\Material\Biden_Photo_Big.png", expand_percent=0.15, crop_size=(512, 512)):
# Check if CUDA is available
if torch.cuda.is_available():
device = 'cuda'
print("Using GPU for RetinaFace detection.")
else:
device = 'cpu'
print("Using CPU for RetinaFace detection.")
# Load image
img = Image.open(image_path)
# Perform face detection
faces = RetinaFace.detect_faces(image_path)
if not faces:
print("No faces detected.")
return None
# Assuming 'faces' is a dictionary of detected faces
# Pick the first face detected
face = list(faces.values())[0]
landmarks = face['landmarks']
# Extract the landmarks
right_eye = landmarks['right_eye']
left_eye = landmarks['left_eye']
right_mouth = landmarks['mouth_right']
left_mouth = landmarks['mouth_left']
# Calculate the distance between the eyes
eye_distance = abs(right_eye[0] - left_eye[0])
# Estimate the head width and height
head_width = eye_distance * 4.5 # Increase the width multiplier
head_height = eye_distance * 6.5 # Increase the height multiplier
# Calculate the center point between the eyes
eye_center_x = (right_eye[0] + left_eye[0]) // 2
eye_center_y = (right_eye[1] + left_eye[1]) // 2
# Calculate the top-left and bottom-right coordinates of the assumed head region
head_left = max(0, int(eye_center_x - head_width // 2))
head_top = max(0, int(eye_center_y - head_height // 2)) # Adjust the top coordinate
head_right = min(img.width, int(eye_center_x + head_width // 2))
head_bottom = min(img.height, int(eye_center_y + head_height // 2)) # Adjust the bottom coordinate
# Save the assumed head image
assumed_head_img = img.crop((head_left, head_top, head_right, head_bottom))
assumed_head_img.save("assumed_head.png", format='PNG')
# Calculate the expansion in pixels and the new dimensions
expanded_w = int(head_width * (1 + expand_percent))
expanded_h = int(head_height * (1 + expand_percent))
# Calculate the top-left and bottom-right points of the expanded box
center_x, center_y = head_left + head_width // 2, head_top + head_height // 2
left = max(0, center_x - expanded_w // 2)
right = min(img.width, center_x + expanded_w // 2)
top = max(0, center_y - expanded_h // 2)
bottom = min(img.height, center_y + expanded_h // 2)
# Crop the image with the expanded boundaries
cropped_img = img.crop((left, top, right, bottom))
cropped_img.save("expanded_face.png", format='PNG')
# Calculate the aspect ratio of the cropped image
cropped_width, cropped_height = cropped_img.size
aspect_ratio = cropped_width / cropped_height
# Calculate the target dimensions based on the desired crop size
target_width = crop_size[0]
target_height = crop_size[1]
# Adjust the crop to match the desired aspect ratio
if aspect_ratio > target_width / target_height:
# Crop from left and right
new_width = int(cropped_height * target_width / target_height)
left_crop = (cropped_width - new_width) // 2
right_crop = left_crop + new_width
top_crop = 0
bottom_crop = cropped_height
else:
# Crop from top and bottom
new_height = int(cropped_width * target_height / target_width)
top_crop = (cropped_height - new_height) // 2
bottom_crop = top_crop + new_height
left_crop = 0
right_crop = cropped_width
# Crop the image with the adjusted boundaries
final_cropped_img = cropped_img.crop((left_crop, top_crop, right_crop, bottom_crop))
final_cropped_img.save("final_cropped_img.png", format='PNG')
# Resize the cropped image to the desired size (512x512 by default) with best quality
resized_img = final_cropped_img.resize(crop_size, resample=Image.LANCZOS)
# Save the resized image as PNG
resized_img_path = image_path.rsplit('.', 1)[0] + '_cropped.png' # Change file name to avoid overwriting
resized_img.save("resized_img.png", format='PNG')
auto_crop_image()