资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Python

通过dlib人脸识别矫正旋转身份证图像

Python 更新时间: 发布时间: 计算机考试归档 最新发布

通过dlib人脸识别矫正旋转身份证图像

原理

        通过不停地旋转图片,直到dlib能够识别到人脸;通过dlib找到眼角、嘴角、鼻子、下巴特征点,假设鼻子到下巴的直线与双眼直线、嘴角直线垂直,找到脸部角度,结合已旋转角度,计算出最终图像旋转角度。

效果

 

 代码

import dlibimport cv2import numpy as npimport mathimport osdetector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")POINTS_NUM_LANDMARK = 68def rotate_img(image, angle):    # grab the dimensions of the image and then determine the    # center    (h, w) = image.shape[:2]    (cX, cY) = (w // 2, h // 2)    # grab the rotation matrix (applying the negative of the    # angle to rotate clockwise), then grab the sine and cosine    # (i.e., the rotation components of the matrix)    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)    cos = np.abs(M[0, 0])    sin = np.abs(M[0, 1])    # compute the new bounding dimensions of the image    nW = int((h * sin) + (w * cos))    nH = int((h * cos) + (w * sin))    # adjust the rotation matrix to take into account translation    M[0, 2] += (nW / 2) - cX    M[1, 2] += (nH / 2) - cY    # perform the actual rotation and return the image    return cv2.warpAffine(image, M, (nW, nH))def show(img, ms=0):    """ 显示 """    cv2.imshow('show', img)    h, w = img.shape[:2]    cv2.resizeWindow("show", w, h)    cv2.waitKey(ms)def _largest_face(dets):    if len(dets) == 1:        return 0    face_areas = [(det.right() - det.left()) * (det.bottom() - det.top()) for det in dets]    largest_area = face_areas[0]    largest_index = 0    for index in range(1, len(dets)):        if face_areas[index] > largest_area:            largest_index = index            largest_area = face_areas[index]    print("largest_face index is {} in {} faces".format(largest_index, len(dets)))    return largest_index# 从dlib的检测结果抽取姿态估计需要的点坐标def get_image_points_from_landmark_shape(landmark_shape):    if landmark_shape.num_parts != POINTS_NUM_LANDMARK:        print("ERROR:landmark_shape.num_parts-{}".format(landmark_shape.num_parts))        return -1, None    # 2D image points. If you change the image, you need to change vector    image_points = np.array([        (landmark_shape.part(30).x, landmark_shape.part(30).y),  # Nose tip        (landmark_shape.part(8).x, landmark_shape.part(8).y),  # Chin        (landmark_shape.part(36).x, landmark_shape.part(36).y),  # Left eye left corner        (landmark_shape.part(45).x, landmark_shape.part(45).y),  # Right eye right corne        (landmark_shape.part(48).x, landmark_shape.part(48).y),  # Left Mouth corner        (landmark_shape.part(54).x, landmark_shape.part(54).y)  # Right mouth corner    ], dtype="double")    return 0, image_points# 计算两个点形成的直线角度,注意opencv的Y轴是朝下生长的,采用 y1-y2/x2-x1# 最终结果在(-180 ~ 180 )def computerAngle2(x1,y1,x2,y2):    angle = math.atan2((y1 - y2), (x2 - x1))    angle = angle * 180 / math.pi #(-180 ~ 180 )    return angle# 用dlib检测关键点,返回姿态估计需要的几个点坐标def detectImage(img,dets,angle):    largest_index = _largest_face(dets)    face_rectangle = dets[largest_index]    landmark_shape = predictor(img, face_rectangle)    return get_image_points_from_landmark_shape(landmark_shape)def findRotete(image_path):    img = cv2.imread(image_path)    finallyImg = None    finallyAngle = 0    for angle in range(0, 360, 60): # 不停旋转,注意如果每次旋转角度过大,存在所有角度无法识别到人脸的可能        rotateImg = rotate_img(img, angle)        dets = detector(rotateImg, 0)        if (len(dets) > 0):            finallyImg = rotateImg            ret, image_points = detectImage(rotateImg, dets, angle)            if ret != 0:                print('get_image_points failed')                break            for p in image_points:                cv2.circle(rotateImg, (int(p[0]), int(p[1])), 3, (0, 0, 255), -1)            Nose_x = image_points[0][0]            Nose_y = image_points[0][1]            Chin_x = image_points[1][0]            Chin_y = image_points[1][1]            Left_Eye_x = image_points[2][0]            Left_Eye_y = image_points[2][1]            Right_Eye_x = image_points[3][0]            Right_Eye_y = image_points[3][1]            Left_Mouth_x = image_points[4][0]            Left_Mouth_y = image_points[4][1]            Right_Mouth_x = image_points[5][0]            Right_Mouth_y = image_points[5][1]            eyeAngle = computerAngle2(Left_Eye_x, Left_Eye_y, Right_Eye_x, Right_Eye_y)            mouthAngle = computerAngle2(Left_Mouth_x, Left_Mouth_y, Right_Mouth_x, Right_Mouth_y)            nose2chinAngle = computerAngle2(Nose_x, Nose_y, Chin_x, Chin_y)            # 120.8157057517292 120.25643716352927 32.9052429229879            nose2chinAngle += 90 # 假设鼻子到下巴的直线与双眼直线垂直            print(angle, eyeAngle, mouthAngle, nose2chinAngle)            avgAngle = (eyeAngle + mouthAngle + nose2chinAngle) / 3 # 即双眼直线、嘴角直线与鼻子到下巴直线(垂直后)这三条直线的平均角度,后续要将此角度归0,即直线平行于图片            print(avgAngle)            finallyAngle = angle + avgAngle  # (angle - (- avgAngle)) avgAngle需要归零,即-avgAngle, 又因为angle 是顺时针旋转角度,avgAngle是逆时针旋转角度,即需要减去(-avgAngle)            if (finallyAngle > 360):                finallyAngle -= 360            if (finallyAngle < - 360):                finallyAngle += 360            print(finallyAngle)            break        show(rotate_img(img, angle), 200)    if (rotateImg is not None):        show(rotateImg, 1000)        finallyImg = rotate_img(img, finallyAngle)        filenames = image_path.split('.')        filename = filenames[0] + "Modify." + filenames[1]        print(filename)        cv2.imwrite(filename, finallyImg)        show(finallyImg, 2000)dir = "rotateCard"for s in os.listdir(dir):    image_path = os.path.join(dir, s)    if 'Modify' not in image_path:        findRotete(image_path)

参考来源

opencv人脸检测,旋转处理 - 姜小豆 - 博客园 (cnblogs.com)

dlib【正面人脸检测】【特征点检测】【旋转】_dlib检测正脸_ya鸡给给的博客-CSDN博客

使用opencv和dlib进行人脸姿态估计(python)_dlib 人脸角度_yuanlulu的博客-CSDN博客

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/1097806.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【通过dlib人脸识别矫正旋转身份证图像】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2