知识点:
- 人脸跟踪
- 人脸特征
- 要识别的人脸特征距离
看效果图,鼻子部分已经被标识出来了:
主要用到了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()))
原文地址:https://www.cnblogs.com/aarond/p/dlib.html
时间: 2024-10-23 15:14:20