利用dlib、imutils、opencv实现脸部剪裁旋转

【环境搭建】
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值