人脸对齐 python代码

本文人脸对齐,基于Deep Convolutional Network Cascade for Facial Point Detection进行,将双眼、鼻尖、双嘴角(共五点)校准至同一位置,为人脸识别的预处理环节
参考:https://github.com/RiweiChen/FaceTools
           http://mmlab.ie.cuhk.edu.hk/archive/CNN_FacePoint.htm

有可能报错UnicodeEncodeError: 'ascii' codec can't encode character,可在文件头添加

import sys  

reload(sys)  

sys.setdefaultencoding('utf-8') 

注意:此种方法造成print函数无法输出

在python安装目录下的lib\site-packages文件夹,新建sitecustomize.py,文件中的代码为:

import sys  

sys.setdefaultencoding('utf-8')   

即可解决输出问题
import os
import cv2
import glob
import struct
import numpy as np
from skimage import io

ImagePath = 'xxx'     
PointPath = 'xxx'    
AlignPath = 'xxx'  

print 'Face Alignment - Get Image List. step(1/6)'

if not os.path.exists('output'):  
    os.makedirs('output')

lines = []   
def getImageList(filePath):
    dirlist = os.listdir(filePath)
    for dirs in dirlist:     
        if os.path.isdir(os.path.join(filePath,dirs)):  
            getImageList(os.path.join(filePath,dirs))
    for filename in glob.glob(filePath+'/*.jpg'):       
        lines.append(filename)
getImageList(ImagePath)

text = str(len(lines))
lines.insert(0,text)

imagelist = './output/imagelist.list'   
file0 = open(imagelist,'w')
for i in range(len(lines)):
    file0.write(lines[i]+'\n')
file0.close() 

step1 获取图像列表

为了匹配人脸检测的格式需求,需要在文件列表头添加文件数目

print 'Face Alignment - Face Detection. step(2/6)'

facelist = './Output/facelist.list'
os.system('FacePartDetect.exe data '+imagelist+' '+facelist)
step2 人脸检测
# 参考 Y. Sun, X. Wang, and X. Tang. Deep Convolutional Network Cascade for Facial Point Detection. In Proceedings
   of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)
, 2013.
# http://mmlab.ie.cuhk.edu.hk/archive/CNN_FacePoint.htm
下载后,将FacePartDetect.exe、data拷贝至当前文件夹
print 'Face Alignment - Face Detection Refine. step(3/6)'

def find_max_face(line):
    word = line.split()
    num_detect = len(word)/4
    areas = np.empty([num_detect],dtype=np.int32) 
    for i in range(num_detect):
        areas[i]=(int(word[4*i+2])-int(word[4*i+1]))*(int(word[4*i+4])-int(word[4*i+3]))
    m = np.argmax(areas)
    line_refine = word[0]+' '+word[4*m+1]+' '+word[4*m+2]+' '+word[4*m+3]+' '+word[4*m+4]+'\n'
    return line_refine

facelist_refine = './Output/facelist_refine.list'
file1 = open(facelist,'r')
file2 = open(facelist_refine,'w')
for line in file1.readlines():   
    if line.count(" ")==4:
        newline = line.replace(ImagePath,'')
        file2.write(newline.split('\\')[-1])
    else:
        if line.count(" ")>4: 
            newline = find_max_face(line)
            file2.write(newline.split('\\')[-1])
file1.close()
file2.close()
step3 人脸检测校准
去除没检测到人脸或检测到多个人脸(取最大人脸)的情况
print 'Face Alignment - Point Detection. step(4/6)'

pointbin = './Output/pointlist.bin'
os.system('TestNet.exe '+facelist_refine+' '+ImagePath+' Input '+pointbin)
step4 特征点检测
# 参考 Y. Sun, X. Wang, and X. Tang. Deep Convolutional Network Cascade for Facial Point Detection. In  Proceedings 
   of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)
, 2013.
# http://mmlab.ie.cuhk.edu.hk/archive/CNN_FacePoint.htm
下载后,将TestNet.exe、Input、tbb.dll、opencv_core231.dll、opencv_highgui231.dll、opencv_imgproc231.dll拷贝至当前文件夹
print 'Face Alignment - Get Points File. step(5/6)'

pointlist = './Output/pointlist.list'

file3 = open(pointbin,'rb');
imageNum = struct.unpack('i',file3.read(4))[0]
pointNum = struct.unpack('i',file3.read(4))[0]
for i in range(imageNum):
    valid = struct.unpack('b',file3.read(1))
pointData = np.empty((2*pointNum * imageNum,1),dtype = np.float64)
k = 0
for i in range(imageNum):
    for j in range(pointNum*2):
        pointData[k] = struct.unpack('d',file3.read(8))
        k = k+1
points = np.reshape(pointData,(imageNum,2*pointNum))
file3.close()

file4 = open(facelist_refine,'r')
file5 = open(pointlist,'w')
for i in range(imageNum):
    fn = file4.readline().split()[0] 
    file5.write(fn)
    for j in range(10):
        file5.write(' '+str(int(points[i][j])))
    file5.write('\n')

    img = io.imread(os.path.join(ImagePath,fn))
    for j in range(5):
        cv2.circle(img,(int(points[i][j*2+0]),int(points[i][j*2+1])),3,(255,0,0),-1)
    io.imsave(os.path.join(PointPath,fn),img)

file4.close()
file5.close() 
step5 特征点校准
从二进制文件中读取特征点位置信息
print 'Face Alignment - Face Alignment. step(6/6)'

file6 = open(pointlist)
word = file6.readline().split()
print 'reference image:'+os.path.join(ImagePath,word[0])

ref = np.empty((10,1),dtype=np.int)
act = np.empty((10,1),dtype=np.int)
for i in range(10):
    ref[i] = int(word[i+1])
refimage = io.imread(os.path.join(ImagePath,word[0]))  

for line in file6.readlines():
    word = line.split()
    for i in range(10):
        act[i] = int(word[i+1])
    src = np.matrix([[int(act[0]),int(act[2]),int(act[4]),int(act[6]),int(act[8])],[int(act[1]),int(act[3]),int(act[5]),int(act[7]),int(act[9])],[1,1,1,1,1]])
    dst = np.matrix([[int(ref[0]),int(ref[2]),int(ref[4]),int(ref[6]),int(ref[8])],[int(ref[1]),int(ref[3]),int(ref[5]),int(ref[7]),int(ref[9])]])
    T = (src*src.T).I*src*dst.T   
    img = io.imread(os.path.join(ImagePath,word[0]))
    rows, cols, channels = img.shape
    img_affine = cv2.warpAffine(img,T.T,(cols,rows))

    for i in range(5):
        cv2.circle(img_affine,(int(ref[i*2+0]),int(ref[i*2+1])),3,(255,0,0),-1)
    io.imsave(os.path.join(AlignPath,word[0]),img_affine)
file6.close()
step6 人脸对齐
取第一张人脸作为基准人脸,并采用透视投影进行对齐










你可能感兴趣的:(人脸对齐 python代码)