| 127 | |
| 128 | |
| 129 | def crop_face(image, face_landmarks, output_size, crop_size_multiplier=2.8): |
| 130 | img_h, img_w, _ = image.shape |
| 131 | |
| 132 | |
| 133 | if face_landmarks is None: |
| 134 | return cv2.resize(image, (output_size, output_size)) |
| 135 | |
| 136 | |
| 137 | #v4========== |
| 138 | # Convert normalized landmarks to pixel coordinates |
| 139 | face_landmarks_px = [(int(lm[0] * img_w), int(lm[1] * img_h)) for lm in face_landmarks] |
| 140 | |
| 141 | # Key face points |
| 142 | chin = face_landmarks_px[152] # Chin point |
| 143 | forehead = face_landmarks_px[10] # Forehead point |
| 144 | left_cheek = face_landmarks_px[234] # Left cheek |
| 145 | right_cheek = face_landmarks_px[454] # Right cheek |
| 146 | |
| 147 | # Calculate face bounding box dimensions |
| 148 | face_width = right_cheek[0] - left_cheek[0] |
| 149 | face_height = chin[1] - forehead[1] |
| 150 | |
| 151 | # Calculate new face height while maintaining aspect ratio |
| 152 | crop_size = max(face_width, face_height) # Ensure square crop around the face |
| 153 | |
| 154 | #make the crop slightly bigger |
| 155 | # crop_size=int(crop_size*2.8) |
| 156 | crop_size=int(crop_size*crop_size_multiplier) |
| 157 | |
| 158 | # Calculate crop center |
| 159 | face_center_x = (left_cheek[0] + right_cheek[0]) // 2 |
| 160 | # face_center_y = (forehead[1] + chin[1]) // 2 |
| 161 | face_center_y = int(forehead[1]*0.4 + chin[1]*0.6) #not the middle of the face but more closer to the chin than the forehead |
| 162 | |
| 163 | |
| 164 | # Crop boundaries in the original image |
| 165 | crop_x1 = int(face_center_x - crop_size // 2) |
| 166 | crop_x2 = crop_x1 + crop_size |
| 167 | crop_y1 = int(face_center_y - crop_size // 2) |
| 168 | crop_y2 = crop_y1 + crop_size |
| 169 | |
| 170 | |
| 171 | #get how much in each direction do we need to pad with zeros |
| 172 | pad_left=max(0, -crop_x1) |
| 173 | pad_right=abs(min(0, img_w-crop_x2)) |
| 174 | pad_top=max(0, -crop_y1) |
| 175 | pad_bottom=abs(min(0, img_h-crop_y2)) |
| 176 | |
| 177 | |
| 178 | # Extract the region from the original image |
| 179 | crop_x1 = max(0, crop_x1) |
| 180 | crop_y1 = max(0, crop_y1) |
| 181 | crop_x2 = min(img_w, crop_x2) |
| 182 | crop_y2 = min(img_h, crop_y2) |
| 183 | |
| 184 | cropped_region = image[crop_y1:crop_y2, crop_x1:crop_x2] |
| 185 | |
| 186 | |