本文共 6373 字,大约阅读时间需要 21 分钟。
知识点:
看效果图,鼻子部分已经被标识出来了:
主要用到了dlib
import dlibpredictor_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_vectorfaces = [           (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 dlibimport cv2import numpy as npimport imutilsfrom imutils import face_utilsfrom imageio import imreadpip install cmakepip install dlibpip install opencv-pythonpip install numpypip install imutilspip install imageio
完整代码
import dlibimport cv2import numpy as npimport imutilsfrom imutils import face_utilsfrom imageio import imreadimport timepredictor_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.12def 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_vectordef 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 rfaces = Nonecap = Nonesuccess = Noneevents = []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()))  
转载地址:http://eckwk.baihongyu.com/