+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2020-03(72)

2020-04(55)

2020-05(24)

2020-06(36)

2020-07(25)

人脸矫正代码

发布于2020-09-30 06:51     阅读(1070)     评论(0)     点赞(7)     收藏(0)


0

1

2

3

4

5

6

7

8

9

def face_alignment(faces,show=False):
    '''
    faces: num * width * height * channels ,value = 0~255, dtype = np.uint8, 
    note: width must equal to height
    '''
    print(faces.shape)
    if len(faces.shape)==4 and faces.shape[3]==1:
        faces = faces.reshape(faces.shape[:-1]) # if gray, turns to num * width * height, no channel axis 如果是灰度图,去掉最后一维,否则predictor会报错
    num = faces.shape[0]
    import numpy as np
    faces_aligned = np.zeros(shape=faces.shape,dtype=np.uint8)
    import dlib
    predictor_path = "./shape_predictor_68_face_landmarks.dat" # dlib提供的训练好的68个人脸关键点的模型,网上可以下
    predictor = dlib.shape_predictor(predictor_path) # 用来预测关键点
    for i in range(num):
        img = faces[i]
        rec = dlib.rectangle(0,0,img.shape[0],img.shape[1])
        shape = predictor(np.uint8(img),rec) # 注意输入的必须是uint8类型
        order=[36,45,30,48,54] # left eye, right eye, nose, left mouth, right mouth  注意关键点的顺序,这个在网上可以找
        if show:
            plt.pyplot.figure()
            plt.pyplot.imshow(img,cmap='gray')
            for j in order:
                x = shape.part(j).x
                y = shape.part(j).y
                plt.pyplot.scatter(x,y) # 可以plot出来看看效果,这里我只plot5个点
        eye_center =( (shape.part(36).x + shape.part(45).x) * 1./2, # 计算两眼的中心坐标
                      (shape.part(36).y + shape.part(45).y) * 1./2) 
        dx = (shape.part(45).x - shape.part(36).x) # note: right - right
        dy = (shape.part(45).y - shape.part(36).y)
        import math
        angle = math.atan2(dy,dx) * 180. / math.pi # 计算角度
#        print angle
        import cv2
        RotateMatrix = cv2.getRotationMatrix2D(eye_center, angle, scale=1) # 计算仿射矩阵
        RotImg = cv2.warpAffine(img, RotateMatrix, (img.shape[0], img.shape[1])) # 进行放射变换,即旋转
        faces_aligned[i] = RotImg
    return faces_aligned # uint8

import numpy as np
import os
import cv2
import math
import face_recognition

class face_detector():
        def __init__(self):

            self.cv2_base_dir = os.path.dirname(os.path.abspath(cv2.__file__))

            self.haar_model1 = os.path.join(self.cv2_base_dir, 'data/haarcascade_frontalface_default.xml')

            self.haar_model2 = os.path.join(self.cv2_base_dir, 'data/haarcascade_frontalface_alt.xml')

            self.haar_model3 = os.path.join(self.cv2_base_dir, 'data/haarcascade_frontalface_alt2.xml')

            self.haar_model4 = os.path.join(self.cv2_base_dir, 'data/haarcascade_frontalface_alt_tree.xml')


            self.face_cascade = cv2.CascadeClassifier(self.haar_model2)

            self.cap = cv2.VideoCapture(0)

            self.total = 0

            self.detected_num = 0

            self.angle = 0

        def capture(self):

            while(1):
                # get a frame
                ret, frame = self.cap.read()
                # show a frame
                gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)


                faces = self.face_cascade.detectMultiScale(gray, 1.3,5)


                if(len(faces)>0):
                    self.detected_num += 1
                    self.total += 1
                    percent = self.detected_num/self.total
                    percent = str(percent)
                    #print("Detected " + percent + "\n" + "total number is " + str(self.total) + "\n" +
                        #"detected nunber is " + str(self.detected_num))
                    #from frame to detect angle
                    is_angle,angle,direction = self.Horizontal_angle(frame)
                    if(is_angle == 1):
                        #print("angle is " + str(angle) + "direction is " + str(direction))
                        if angle > self.angle:
                            self.angle = angle
                            print("max angle = {}".format(angle))
                    #print()
                    for(x,y,w,h) in faces:
                        self.x = x
                        self.y = y
                        cv2.putText(frame,str(angle),(400,50),cv2.FONT_HERSHEY_PLAIN,2.0,(0,0,255),2)

                        #cv2.addText(frame,str(angle),(10,10),cv2.FONT_HERSHEY_SIMPLEX )
                        cv2.rectangle(frame, (x,y), (x+w, y+h), (255,0,0),2)

                else:
                    self.total += 1

                    #print("No face detected")
                    #print()


                cv2.imshow("Detecting", frame)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break


            self.cap.release()
            cv2.destroyAllWindows()

        def Horizontal_angle(self,input_frame):
            face_landmark = face_recognition.face_landmarks(input_frame,model="large")

            if len(face_landmark) == 0:
                #no face landmark has been detected
                return 0,-1,"no"
            face_landmark_dict = face_landmark[0]

            self.landmark = face_landmark_dict

            right_eye_list = face_landmark_dict['right_eye']
            left_eye_list = face_landmark_dict['left_eye']

            right_eye_centre_x = 0
            right_eye_centre_y = 0
            left_eye_centre_x = 0
            left_eye_centre_y = 0

            for i in range(len(right_eye_list)):
                right_eye_centre_x += right_eye_list[i][0]
                right_eye_centre_y += right_eye_list[i][1]

            for j in range(len(left_eye_list)):
                left_eye_centre_x += left_eye_list[i][0]
                left_eye_centre_y += left_eye_list[i][1]

            right_eye_centre_x,right_eye_centre_y = right_eye_centre_x/float(len(right_eye_list)),right_eye_centre_y/float(len(right_eye_list))
            left_eye_centre_x, left_eye_centre_y = left_eye_centre_x/float(len(left_eye_list)), left_eye_centre_y/float(len(left_eye_list))

            #print("right is {}".format((right_eye_centre_x,right_eye_centre_y)))
            #print("left is {}".format((left_eye_centre_x,left_eye_centre_y)))

            direction = 'clockwise'
            if right_eye_centre_y>left_eye_centre_y:
                #C_x,C_y = 0,right_eye_centre_y
                direction = 'counterclockwise'



            AB_length = math.sqrt(math.pow((right_eye_centre_x-left_eye_centre_x),2)+math.pow((right_eye_centre_y-left_eye_centre_y),2))
            AC_length = right_eye_centre_x
            BC_length = math.sqrt(math.pow(left_eye_centre_x,2)+math.pow((left_eye_centre_y-right_eye_centre_y),2))

            cosA = float((math.pow(AB_length,2)+math.pow(AC_length,2)-math.pow(BC_length,2)))/float(2*AB_length*AC_length)
            #print(cosA)
            #human head angle
            if cosA > 1.0 or cosA < -1.0:
                return 0

            angle = (math.acos(cosA))*(180/float(math.pi))
            #print(angle,direction)

            #self.angle = angle
            #self.direction = direction
            return 1,angle,direction




if __name__ == '__main__':
    work = face_detector()
    work.capture()

0

1

2

3

4

5

6

7



所属网站分类: 技术文章 > 博客

作者:吃点豆皮子

链接: https://www.pythonheidong.com/blog/article/554218/b47ac0c520c70bfd5edf/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

7 0
收藏该文
已收藏

评论内容:(最多支持255个字符)