【环境搭建】
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.35
self.predictor = predictor
self.desiredLeftEye = desiredLeftEye
self.desiredFaceWidth = desiredFaceWidth
self.desiredFaceHeight = desiredFaceHeight
if self.desiredFaceHeight is None:
self.desiredFaceHeight = self.desiredFaceWidth
def 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)/2
lefteyey=(p2y+p3y)/2
righteyex=(p0x+p1x)/2
righteyey=(p0y+p1y)/2
centerx=(lefteyex+righteyex)/2
centery=(lefteyey+righteyey)/2
dX=(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.desiredFaceWidth
scale = desiredDist / dist
# 使用旋转矩阵旋转和缩放脸
M = cv2.getRotationMatrix2D((centerx,centery), angle, scale)
# 更新矩阵的旋转量
tX = self.desiredFaceWidth * 0.5
tY = 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 OpenCV
x = rect.left()
y = rect.top()
w = rect.right() - x
h = 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
版权声明:本文为qq_37249793原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。