【环境搭建】
1.安装cmake
pip install cmake
2.安装dlib
pip install dlib
注1:python3.7之前的版本如果不能直接下载,可以去豆瓣源的dlib区下载http://pypi.doubanio.com/simple/dlib/
注2:pythoh3.7的dlib包如在此处下载 链接:https://pan.baidu.com/s/1SOYzGexGxUrFwTDgq93gNA
提取码:z3db
3.安装Imutils
pip install imutils
如果不行就用豆瓣源http://pypi.doubanio.com/simple/imutils/
4、安装opencv(若未安装请自行安装)
【实现功能:人脸对齐、旋转、裁剪】
【与模型人脸对齐函数(分5个关键点和68个关键点两种方法,本文采用5个关键点,取眼睛和鼻子作为参考。68个关键点的原理类似)】
【代码如下】
import numpy as np
import cv2
from collections import OrderedDict#排序
import argparse
import dlib
import matplotlib.pyplot as plt
import imutils
#加载模型
p = 'shape_predictor_5_face_landmarks.dat'
#p = 'shape_predictor_68_face_landmarks.dat'
#FACIAL_LANDMARKS_5_IDXS = OrderedDict([("right_eye", (2, 3)),("left_eye", (0, 1)),("nose", (4))])#定义人脸区域的字典和坐标
#FACIAL_LANDMARKS_68_IDXS = OrderedDict([("mouth", (48, 68)),("right_eyebrow", (17, 22)),("left_eyebrow", (22, 27)),("right_eye", (36, 42)),("left_eye", (42, 48)),("nose", (27, 36)),("jaw",(0,17))])#定义人脸区域的字典和坐标
#人脸对齐
class FaceAligner:#初始化人脸框def __init__(self, predictor, desiredLeftEye=(0.42, 0.42), desiredFaceWidth=224, desiredFaceHeight=None):#0.35,0.35self.predictor = predictor self.desiredLeftEye = desiredLeftEye self.desiredFaceWidth = desiredFaceWidth self.desiredFaceHeight = desiredFaceHeight if self.desiredFaceHeight is None:self.desiredFaceHeight = self.desiredFaceWidthdef align(self, image, gray, rect):for i in range(len(rects)):landmarks = np.matrix([[p.x, p.y] for p in predictor(image,rects[i]).parts()])for idx, point in enumerate(landmarks):if(idx==0):p0x = (point[0, 0])p0y = (point[0, 1])elif(idx==1):p1x = (point[0, 0])p1y = (point[0, 1])elif(idx==2):p2x = (point[0, 0])p2y = (point[0, 1])elif(idx==3):p3x = (point[0, 0])p3y = (point[0, 1])lefteyex=(p2x+p3x)/2lefteyey=(p2y+p3y)/2righteyex=(p0x+p1x)/2righteyey=(p0y+p1y)/2centerx=(lefteyex+righteyex)/2centery=(lefteyey+righteyey)/2dX=(righteyex-centerx)dY=(righteyey-centery)angle = np.degrees(np.arctan2(dY, dX))# 根据所需的x坐标计算所需的右眼x坐标desiredRightEyeX = 1.0 - self.desiredLeftEye[0]# 通过获取当前图像中眼睛之间的距离与所需图像中眼睛之间的距离的比率来确定新结果图像的比例dist = np.sqrt((dX ** 2) + (dY ** 2))desiredDist = (desiredRightEyeX - self.desiredLeftEye[0])desiredDist *= self.desiredFaceWidthscale = desiredDist / dist# 使用旋转矩阵旋转和缩放脸M = cv2.getRotationMatrix2D((centerx,centery), angle, scale)# 更新矩阵的旋转量tX = self.desiredFaceWidth * 0.5tY = self.desiredFaceHeight * self.desiredLeftEye[1]M[0, 2] += (tX - centerx)M[1, 2] += (tY - centery)# 应用仿射变换(w, h) = (self.desiredFaceWidth, self.desiredFaceHeight)output = cv2.warpAffine(image, M, (w, h),flags=cv2.INTER_CUBIC)# 返回对齐脸return output#获取人脸关矩阵的坐标
def rect_to_bb(rect):# take a bounding predicted by dlib and convert it# to the format (x, y, w, h) as we would normally do# with OpenCVx = rect.left()y = rect.top()w = rect.right() - xh = rect.bottom() - y# return a tuple of (x, y, w, h)return (x, y, w, h)image = cv2.imread('test5.jpg')#读图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#灰度化
detector = dlib.get_frontal_face_detector()#创建预测器
predictor = dlib.shape_predictor(p)#读模型
fa = FaceAligner(predictor, desiredFaceWidth=224)
print(fa)
#检测面部,得到左上、右下坐标
rects = detector(gray, 1)#2
#提取感兴趣部分并对齐
FaceAligned = fa.align(image, gray, rects)
cv2.imshow('faceorig',image)
cv2.imshow('alin', FaceAligned)
cv2.waitKey(0)
cv2.destroyAllWindows()
模型百度云链接:https://pan.baidu.com/s/1AjMhKl3R-iU2cYiGJ1ptBw
提取码:smvs