zoukankan      html  css  js  c++  java
  • 人脸跟踪、识别、脸部标识

    知识点:

    1. 人脸跟踪
    2. 人脸特征
    3. 要识别的人脸特征距离

    看效果图,鼻子部分已经被标识出来了:

    主要用到了dlib

    import dlib
    
    predictor_path = 'models\shape_predictor_68_face_landmarks.dat'
    face_rec_model_path = 'models\dlib_face_recognition_resnet_model_v1.dat'
    
    detector = dlib.get_frontal_face_detector()                       #人脸跟踪
    predictor = dlib.shape_predictor(predictor_path)                  #人脸68个特征点检测器
    facerec = dlib.face_recognition_model_v1(face_rec_model_path)     #映射人脸为128维特征值

    由于目标里还希望把鼻子区域标识出来(方便后续自己贴图上去),因此:

    from imutils import face_utils
    
    (noseStart, noseEnd) = face_utils.FACIAL_LANDMARKS_IDXS["nose"] 
    
    #省略一部分代码,主要是省略了opencv调用摄像头逻辑代码
    
            success, img = cap.read()                                  #读取摄像头视频信息
            frame = imutils.resize(img, width=300)                     #resize,尺寸越小处理越快
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)             #变灰度图
            rects = detector(gray, 0)                                  #人脸区域跟踪
            rect = rects[0]                                            #假设只有1个区域存在人脸
            shape = predictor(gray, rect)                              #识别68个特征点
            shape = face_utils.shape_to_np(shape)                      #转换为numpy格式
            nose = shape[noseStart:noseEnd]                            #只拿鼻子区域的点
            noseHull = cv2.convexHull(nose)                            #把这些点转换为凸包
            cv2.drawContours(frame, [noseHull], -1, (0, 255, 0), 1)    #画出这些凸包外形
            cv2.putText(frame, "nose", (nose[0][0], nose[0][1]), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)         #文本标注
    

      

    face_utils.FACIAL_LANDMARKS_IDXS,这个是对68个点的描述,有很多(有兴趣大家自己试试):
    #For dlib’s 68-point facial landmark detector:
    FACIAL_LANDMARKS_68_IDXS = OrderedDict([
    	("mouth", (48, 68)),
    	("inner_mouth", (60, 68)),
    	("right_eyebrow", (17, 22)),
    	("left_eyebrow", (22, 27)),
    	("right_eye", (36, 42)),
    	("left_eye", (42, 48)),
    	("nose", (27, 36)),
    	("jaw", (0, 17))
    ])
    

      

    接下来就是识别人脸到底是谁了

    def get_feature(path):
        img = imread(path)
        frame = img
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        dets = detector(gray, 0)
        shape = predictor(gray, dets[0])
        face_vector = facerec.compute_face_descriptor(img, shape)
        return face_vector
    
    faces = [
               (get_feature('faces\dbh.jpg'), 'McKay')
            ]
    

      目前就1张,所以只load了1个到faces array里

           实际匹配代码如下:

    def distance(a, b):
        a, b = np.array(a), np.array(b)
        sub = np.sum((a - b) ** 2)
        add = (np.sum(a ** 2) + np.sum(b ** 2)) / 2.
        r = sub / add
        return r
    
    def process_face_id(faces, frame, rect, shape): found_face_id = 'Unknown' if len(faces) > 0: face_descriptor = facerec.compute_face_descriptor(frame, shape) min_face_id = found_face_id min_face_distance = 1 for face_feature, face_id in faces: cur_distance = distance(face_feature, face_descriptor) if cur_distance < min_face_distance: min_face_distance = cur_distance min_face_id = face_id if min_face_distance < threshold: found_face_id = min_face_id cv2.rectangle(frame, (rect.left(), rect.top() + 10), (rect.right(), rect.bottom()), (0, 255, 0), 2) cv2.putText(frame, found_face_id, (rect.left(), rect.top()), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2, cv2.LINE_AA) if found_face_id != 'Unknown': events.append(('user_found', found_face_id, time.time()))

      

    需要pip install的有:

    import dlib
    import cv2
    import numpy as np
    import imutils
    from imutils import face_utils
    from imageio import imread
    
    
    pip install cmake
    pip install dlib
    pip install opencv-python
    pip install numpy
    pip install imutils
    pip install imageio 
    

      

    完整代码

    import dlib
    import cv2
    import numpy as np
    import imutils
    from imutils import face_utils
    from imageio import imread
    import time
    
    predictor_path = 'models\shape_predictor_68_face_landmarks.dat'
    face_rec_model_path = 'models\dlib_face_recognition_resnet_model_v1.dat'
    
    predictor = dlib.shape_predictor(predictor_path)
    detector = dlib.get_frontal_face_detector()
    facerec = dlib.face_recognition_model_v1(face_rec_model_path)
    
    (noseStart, noseEnd) = face_utils.FACIAL_LANDMARKS_IDXS["nose"]
    
    threshold = 0.12
    
    
    def get_feature(path):
        img = imread(path)
        frame = img
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        dets = detector(gray, 0)
        # print('检测到了 %d 个人脸' % len(dets))
        # 这里假设每张图只有一个人脸
        shape = predictor(gray, dets[0])
        face_vector = facerec.compute_face_descriptor(img, shape)
        return face_vector
    
    
    def distance(a, b):
        a, b = np.array(a), np.array(b)
        sub = np.sum((a - b) ** 2)
        add = (np.sum(a ** 2) + np.sum(b ** 2)) / 2.
        r = sub / add
        return r
    
    
    faces = None
    cap = None
    success = None
    events = []
    
    
    def init():
        global faces
        global cap
        global success
        faces = [
                    (get_feature('faces\dbh.jpg'), 'McKay')
                ]
    
        cap = cv2.VideoCapture(0)
        success, img = cap.read()
    
    def start():
        global faces
        global cap
        global success
        while success:
            success, img = cap.read()
            frame = imutils.resize(img, width=300)
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            rects = detector(gray, 0)
            for rect in rects:
                shape = predictor(gray, rect)
    
                process_face_id(faces, frame, rect, shape)
    
                shape = face_utils.shape_to_np(shape)
                nose = shape[noseStart:noseEnd]
                noseHull = cv2.convexHull(nose)
                cv2.drawContours(frame, [noseHull], -1, (0, 255, 0), 1)
                cv2.putText(frame, "nose", (nose[0][0], nose[0][1]), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
    
            cv2.imshow("Frame", frame)
            key = cv2.waitKey(1) & 0xFF
    
        cv2.destroyAllWindows()
    
    
    def process_face_id(faces, frame, rect, shape):
        found_face_id = 'Unknown'
        if len(faces) > 0:
            face_descriptor = facerec.compute_face_descriptor(frame, shape)
            min_face_id = found_face_id
            min_face_distance = 1
            for face_feature, face_id in faces:
                cur_distance = distance(face_feature, face_descriptor)
                if cur_distance < min_face_distance:
                    min_face_distance = cur_distance
                    min_face_id = face_id
    
            if min_face_distance < threshold:
                found_face_id = min_face_id
        cv2.rectangle(frame, (rect.left(), rect.top() + 10), (rect.right(), rect.bottom()), (0, 255, 0), 2)
        cv2.putText(frame, found_face_id, (rect.left(), rect.top()), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2, cv2.LINE_AA)
        if found_face_id != 'Unknown':
            events.append(('user_found', found_face_id, time.time()))
    

      

  • 相关阅读:
    js设计模式之 适配器模式与应用场景
    2017版本的IDEA
    JAVA实验六——图形用户界面设计——6-47选择整数计算
    升级apache版本
    基于 PVE + TrueNAS 的私有云配置流程
    基于Win10+VS2019的ceres-solver-2.0.0配置流程
    基于PVE+ROS+LEDE的软路由配置流程
    启动android studio
    vscode配置
    找不到https://raw.githubusercontent.com
  • 原文地址:https://www.cnblogs.com/aarond/p/dlib.html
Copyright © 2011-2022 走看看