最近在做人脸相关课题,找个地方保存一下部分代码。
用的dlib是81个关键点,GitHub网址:https://github.com/codeniko/shape_predictor_81_face_landmarks
#读取视频,检测一帧中的人脸,并在图像中标出关键点,同时打印出关键点的坐标。
import dlib
import numpy as np
import cv2
from matplotlib import pyplot as plt
cap = cv2.VideoCapture('视频路径')
predictor_path = "shape_predictor_81_face_landmarks.dat的路径"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
while(True):
ret, frame = cap.read()
# 取灰度
img_gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
# 人脸数rects
rects = detector(img_gray, 0)
for i in range(len(rects)):
landmarks = np.matrix([[p.x, p.y] for p in predictor(frame, rects[i]).parts()])
for idx, point in enumerate(landmarks):
# 81点的坐标
pos = (point[0, 0], point[0, 1])
# 利用cv2.circle给每个特征点画一个圈,共81个
cv2.circle(frame, pos, 2, color=(0, 255, 0))
# 利用cv2.putText输出1-81
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, str(idx + 1), pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)
print("index=" + str(idx+1) + " x=" + str(pos[0]) + " y=" + str(pos[1]))
plt.imshow(frame)
plt.show()
if cv2.waitKey(1) & 0xFF == ord('q'):
print("q pressed")
break
cap.release()
cv2.destroyAllWindows()
接下来根据上面的人脸关键点,选取ROI。
a = np.arange(81)
b = np.arange(81)
# 取灰度
img_gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
dets = detector(img_gray, 0)
if (len(dets) != 0):
# 找到脸颊区域
for i in range(len(dets)):
landmarks = np.matrix([[p.x, p.y] for p in predictor(frame, dets[i]).parts()])
for idx, point in enumerate(landmarks):
# 68点的坐标
pos = (point[0, 0], point[0, 1])
# ROI:脸颊区域
a = a.tolist()
b = b.tolist()
a[idx] = point[0, 0]
b[idx] = point[0, 1]
a = np.array(a)
b = np.array(b)
# 额头区域
x1 = int(a[76])
y1 = int(b[19])
x2 = int(a[73])
y2 = int(b[73])
if (x1 < 0): # 防止人脸转动,x1位置超出图像
x1 = 0
forehead_ROI = frame[y2:y1, x1:x2]
# 脸颊区域
x1 = int((a[2] + a[4]) / 2)
y1 = int((b[2] + b[4]) / 2)
y2 = int((b[2] + b[23]) / 2)
x2 = int((a[12] + a[14]) / 2)
if (x1 < 0):
x1 = 0
cheek_ROI = frame[y2:y1, x1:x2]
# 检测整个人脸区域
for k, d in enumerate(dets):
[x1, x2, y1, y2] = [d.left(), d.right(), d.top(), d.bottom()]
face_ROI = frames[y1:y2, x1:x2]