Python+CV2+dlib 图像旋转达到放平人脸作用

出发点:看了很多有关旋转人脸的,多为使用c语言实现的,结合前辈思想使用python实现了一版。

注意:本人使用的是jupyter notebook边写边检查, 所以使用IDE的童鞋记得将我函数定义代码和测试代码分开,测试代码放到

“if __name__=='__main__'”中,可以规范点。

流程为:

1.获得人脸特征点

2.获得左右眼角

3.计算左右眼角坐标差值dx,dy然后求artan值转换为弧度angle

4.选定鼻尖为人脸中心center

5.创建旋转矩阵

6.warpAffine旋转图片

import cv2
import dlib
import numpy as np
import math

shape_path = './shape_predictor_68_face_landmarks.dat'  # 特征检测器模型路径
img = cv2.imread('./test/test.jpg')  # 测试图片
detector = dlib.get_frontal_face_detector()  # 人脸检测器
predictor = dlib.shape_predictor(shape_path)  # 人脸特征检测器

# 用来取得特征点集合
def getRes(img):
    # 在这里需要将BGR格式颜色通道转为RGB,因为dlib默认使用RGB图片
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    res = detector(img, 1)  # 检测结果
    for idx,face in enumerate(res):  # 遍历检测结果中的人脸
        shape = predictor(img, face)  # 检测图像中人脸的特征点
    return shape

# 用来取得左右眼眼角,鼻尖坐标
def getLocation(shape, img_, debug):
    left_eye_x = shape.parts()[36].x  # 36对应左眼角
    left_eye_y = shape.parts()[36].y
    right_eye_x = shape.parts()[45].x  # 45对应右眼角
    right_eye_y = shape.parts()[45].y
    center = shape.parts()[30].x, shape.parts()[30].y
    if debug:
        cv2.circle(img_, (left_eye_x, left_eye_y), 2, (255,0,0), 2)
        cv2.circle(img_, (right_eye_x, right_eye_y), 2, (255,0,0), 2)
        cv2.circle(img_, center, 2, (255,0,0), 2)
    return left_eye_x, left_eye_y, right_eye_x, right_eye_y, center, img_

# 测试一下
shape = getRes(img)
result = getLocation(shape, img, True)
img_ = result[-1]  # 获取标点后图片
# 显示测试图片
cv2.imshow('img_', img_)
cv2.waitKey()
cv2.destroyAllWindows()

# 测试无误,继续

#计算两眼的角度
#原理:
#y/x = tan(角度)
#arctan(y/x) = 弧度
#度化弧度: 180° = π弧度 则:1° = π弧度/180
#弧度化度: π弧度 = 180° 则:1弧度 = 180/π(°)

left_eye_x = result[0]
left_eye_y = result[1]
right_eye_x = result[2]
right_eye_y = result[3]
center = result[4]

# 现在获取角度
def getAngle(left_eye_x, left_eye_y, right_eye_x, right_eye_y):
    dy = left_eye_y - right_eye_y
    dx = left_eye_x - right_eye_x
    angle = math.atan(dy/dx)*180/math.pi
    return angle
angle = getAngle(left_eye_x, left_eye_y, right_eye_x, right_eye_y)

# 获得旋转矩阵
warp_matrix = cv2.getRotationMatrix2D(center, angle, 1)

# 最终得到旋转图像
rotated = cv2.warpAffine(img_, warp_matrix, (img.shape[1], img.shape[0]))

 

你可能感兴趣的:(图像处理)