ameerazam08's picture
Upload folder using huggingface_hub
e34aada verified
raw
history blame
3.27 kB
import face_alignment
import os
import cv2
import skimage.transform as trans
import argparse
import torch
import numpy as np
import tqdm
device = 'cuda' if torch.cuda.is_available() else 'cpu'
def get_affine(src):
dst = np.array([[87, 59],
[137, 59],
[112, 120]], dtype=np.float32)
tform = trans.SimilarityTransform()
tform.estimate(src, dst)
M = tform.params[0:2, :]
return M
def affine_align_img(img, M, crop_size=224):
warped = cv2.warpAffine(img, M, (crop_size, crop_size), borderValue=0.0)
return warped
def affine_align_3landmarks(landmarks, M):
new_landmarks = np.concatenate([landmarks, np.ones((3, 1))], 1)
affined_landmarks = np.matmul(new_landmarks, M.transpose())
return affined_landmarks
def get_eyes_mouths(landmark):
three_points = np.zeros((3, 2))
three_points[0] = landmark[36:42].mean(0)
three_points[1] = landmark[42:48].mean(0)
three_points[2] = landmark[60:68].mean(0)
return three_points
def get_mouth_bias(three_points):
bias = np.array([112, 120]) - three_points[2]
return bias
def align_folder(folder_path, folder_save_path):
fa = face_alignment.FaceAlignment(face_alignment.LandmarksType._2D, device=device)
preds = fa.get_landmarks_from_directory(folder_path)
sumpoints = 0
three_points_list = []
for img in tqdm.tqdm(preds.keys(), desc='preprocessing..'):
pred_points = np.array(preds[img])
if pred_points is None or len(pred_points.shape) != 3:
print('preprocessing failed')
return False
else:
num_faces, size, _ = pred_points.shape
if num_faces == 1 and size == 68:
three_points = get_eyes_mouths(pred_points[0])
sumpoints += three_points
three_points_list.append(three_points)
else:
print('preprocessing failed')
return False
avg_points = sumpoints / len(preds)
M = get_affine(avg_points)
p_bias = None
for i, img_pth in tqdm.tqdm(enumerate(preds.keys()), desc='affine and save'):
three_points = three_points_list[i]
affined_3landmarks = affine_align_3landmarks(three_points, M)
bias = get_mouth_bias(affined_3landmarks)
if p_bias is None:
bias = bias
else:
bias = p_bias * 0.2 + bias * 0.8
p_bias = bias
M_i = M.copy()
M_i[:, 2] = M[:, 2] + bias
img = cv2.imread(img_pth)
wrapped = affine_align_img(img, M_i)
img_save_path = os.path.join(folder_save_path, img_pth.split('/')[-1])
cv2.imwrite(img_save_path, wrapped)
print('cropped files saved at {}'.format(folder_save_path))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--folder_path', help='the folder which needs processing')
args = parser.parse_args()
if os.path.isdir(args.folder_path):
home_path = '/'.join(args.folder_path.split('/')[:-1])
save_img_path = os.path.join(home_path, args.folder_path.split('/')[-1] + '_cropped')
os.makedirs(save_img_path, exist_ok=True)
align_folder(args.folder_path, save_img_path)
if __name__ == '__main__':
main()