#!/usr/bin/python
-- coding: UTF-8 --
import cv2
import dlib
import sys
import json
import os
import numpy as np
import matplotlib.pyplot as plt
import pdb
import matplotlib.pyplot as plt
SCALE_FACTOR = 1 # 图像的放缩比
index_dir = ‘E:/DisguisedFacesInTheWild/subjects’
root_dir = ‘E:/DisguisedFacesInTheWild/crop’
output_dir = ‘E:/DisguisedFacesInTheWild/alignment’
Base_path = ‘E:/DisguisedFacesInTheWild/deal/exp.jpg’
split = ‘Testing’ #Testing/Training
PREDICTOR_PATH = “E:/DisguisedFacesInTheWild/deal/shape_predictor_68_face_landmarks.dat”
ALIGN_POINTS = list(range(0,68))
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(PREDICTOR_PATH)
images_noface = []
images_withface = []
#以numpy数组的形式获取图像特征点,并返回68x2元素矩阵,其每一行对应于输入图像中特定特征点的x,y坐标。
def get_landmarks(im):
rects = detector(im, 1)
if len(rects) > 1:
raise TooManyFaces
if len(rects) == 0:
return 'NoFaces'
#raise NoFaces
return np.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])
#读取图片
def read_im_and_landmarks(fname):
im = cv2.imread(fname, cv2.IMREAD_COLOR)
im = cv2.resize(im, (im.shape[1] * SCALE_FACTOR,
im.shape[0] * SCALE_FACTOR))
s = get_landmarks(im)
return im, s
#人脸关键点,画图函数
def annotate_landmarks(im, landmarks):
im = im.copy()
for idx, point in enumerate(landmarks):
pos = (point[0, 0], point[0, 1])
cv2.putText(im, str(idx), pos,
fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
fontScale=0.4,
color=(0, 0, 255))
cv2.circle(im, pos, 3, color=(0, 255, 255))
return im
#获取变换矩阵
def transformation_from_points(points1, points2):
points1 = points1.astype(np.float64)
points2 = points2.astype(np.float64)
c1 = np.mean(points1, axis=0)
c2 = np.mean(points2, axis=0)
points1 -= c1
points2 -= c2
s1 = np.std(points1)
s2 = np.std(points2)
points1 /= s1
points2 /= s2
U, S, Vt = np.linalg.svd(points1.T * points2)
R = (U * Vt).T
return np.vstack([np.hstack(((s2 / s1) * R,
c2.T - (s2 / s1) * R * c1.T)),
np.matrix([0., 0., 1.])])
#根据变换矩阵进行变换
def warp_im(im, M, dshape):
output_im = np.zeros(dshape, dtype=im.dtype)
cv2.warpAffine(im,
M[:2],
(dshape[1], dshape[0]),
dst=output_im,
borderMode=cv2.BORDER_TRANSPARENT,
flags=cv2.WARP_INVERSE_MAP)
return output_im
人脸对齐函数
def face_Align(Base_path,cover_path):
im1, landmarks1 = read_im_and_landmarks(Base_path) # 底图
im2, landmarks2 = read_im_and_landmarks(cover_path) # 贴上来的图
if landmarks2 ==‘NoFaces’:
return ‘NoFaces’
if len(landmarks1) == 0 & len(landmarks2) == 0 :
raise ImproperNumber("Faces detected is no face!")
if len(landmarks1) > 1 & len(landmarks2) > 1 :
raise ImproperNumber("Faces detected is more than 1!")
M = transformation_from_points(landmarks1[ALIGN_POINTS],
landmarks2[ALIGN_POINTS])
warped_im2 = warp_im(im2, M, im1.shape)
return warped_im2
def text_save(filename, data):
file = open(filename,‘w’)
#data = data.replace("’", “”).replace("[", “”).replace("]", “”).replace(" “, “”).split(”,")
for i in range(len(data)):
s = str(data[i]) + ‘\n’
s = s.replace("[", “”).replace("]", “”)
file.write(s)
file.close()
if name == “main”:
#cover_path = 'E:/DisguisedFacesInTheWild/crop/Testing_data/Aaron_Eckhart/Aaron_Eckhart_a.jpg'
# warped_mask = face_Align(Base_path,cover_path)
# warped_file = os.path.join(output_dir,'Aaron_Eckhart_a.jpg')
# cv2.imwrite(warped_file, warped_mask)
# pdb.set_trace()
for i in range(2):
num_NoFaces = 0
if i==0: split ='Testing'
if i==1: split ='Training' #Testing/Training
if split =='Testing':
index_name = 'Testingsubjects.txt'
image_spilt = 'Testing_data'
elif split =='Training':
index_name = 'Trainingsubjects.txt'
image_spilt = 'Training_data'
else:
raise ImproperNumber("dataset error")
index_file = os.path.join(index_dir,index_name)
with open(index_file) as tr:
annos = tr.readlines()
num = len(annos)
for ii,anno in enumerate(annos):
image_files = []
# if ii<0:
# continue
parts = anno.replace("\n", "").split(" ")
subject = parts[0]
print subject
image_dir = os.path.join(root_dir,image_spilt,subject)
for root, dirs, files in os.walk(image_dir):
image_files =files
for image_name in image_files:
save_name = os.path.join(image_spilt,subject,image_name)
cover_path = os.path.join(image_dir,image_name)
warped_mask = face_Align(Base_path,cover_path)
if warped_mask == 'NoFaces':
images_noface.append(save_name)
num_NoFaces = num_NoFaces+1
# print 'NoFaces',num_NoFaces,cover_path
continue
images_withface.append(save_name)
aligned_dir = os.path.join(output_dir,image_spilt,subject)
if not os.path.exists(aligned_dir):
os.makedirs(aligned_dir)
warped_file = os.path.join(aligned_dir,image_name)
cv2.imwrite(warped_file,warped_mask)
# print images_withface,images_noface
# pdb.set_trace()
noface_file = os.path.join(output_dir,'noface.txt')
withface_file = os.path.join(output_dir,'withface.txt')
text_save(noface_file,images_noface)
text_save(withface_file,images_withface)