面部区域的面部标志索引
在dlib内部实现的面部标志性检测器产生映射到特定面部结构的 68 (x,y)坐标 。这些68点映射是通过在标记的iBUG 300-W数据集上训练一个形状预测器获得的。
下面我们可以看到这68个坐标映射到的每一个:
通过检查图像,我们可以看到可以通过简单的Python索引来访问面部区域(因为上面的图像是单索引的,所以假设使用Python进行零索引):
- 该 口可以通过点被访问 [48,68] 。
- 通过点 的 右眉毛[17,22]。
- 的 左眉 贯通点 [22,27] 。
- 所述 右眼用 [36,42]。
- 所述 左眼 用 [42,48]。
- 该 鼻用 [27,36]。
- 并通过[0,17]的下巴 。
代码:
from collections import OrderedDict
import numpy as np
import cv2
# 定义一个映射面部索引的字典
# 特定人脸区域的地标
FACIAL_LANDMARKS_IDXS = OrderedDict([
("mouth", (48, 68)),
("right_eyebrow", (17, 22)),
("left_eyebrow", (22, 27)),
("right_eye", (36, 42)),
("left_eye", (42, 48)),
("nose", (27, 36)),
("jaw", (0, 17))
])
def rect_to_bb(rect):
# 由DLIB预测一个边界并转换它
# 对于通常我们所做的格式(x,y,w,h)
# OPEN与OpenCV
x = rect.left()
y = rect.top()
w = rect.right() - x
h = rect.bottom() - y
# 返回 tuple (x, y, w, h)
return (x, y, w, h)
def shape_to_np(shape, dtype="int"):
# 初始化(x,y)坐标的列表
coords = np.zeros((shape.num_parts, 2), dtype=dtype)
# 对所有面部标志进行循环并转换
# 关于x(y,y)坐标的2元组
for i in range(0, shape.num_parts):
coords[i] = (shape.part(i).x, shape.part(i).y)
# 返回(x,y)坐标的列表
return coords
def visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):
# 创建输入图像的两个副本 (一个用于输入图像)
# 叠加和 (一个用于最终输出图像)
overlay = image.copy()
output = image.copy()
# 如果颜色列表为“否”,则用唯一的方法初始化它。
# 每个脸部标志区域的颜色
if colors is None:
colors = [(19, 199, 109), (79, 76, 240), (230, 159, 23),
(168, 100, 168), (158, 163, 32),
(163, 38, 32), (180, 42, 220)]
# 在面部标志区域上分别的连线
for (i, name) in enumerate(FACIAL_LANDMARKS_IDXS.keys()):
# grab the (x, y)-coordinates associated with the
# face landmark
(j, k) = FACIAL_LANDMARKS_IDXS[name]
pts = shape[j:k]
# 检查是否应该画下颌线
if name == "jaw":
# 因为 jawline 是一个非封闭的面部区域,
# 只画出(x,y)坐标之间的直线
for l in range(1, len(pts)):
ptA = tuple(pts[l - 1])
ptB = tuple(pts[l])
cv2.line(overlay, ptA, ptB, colors[i], 2)
# 处理计算点的凸包
# 并在覆盖图上绘制船体
else:
hull = cv2.convexHull(pts)
cv2.drawContours(overlay, [hull], -1, colors[i], -1)
# 应用透明覆盖
cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, output)
# 返回输出图像
return output
调用:
from imutils import face_utils
import imutils
import dlib
#初始化dlib人脸检测(基于HOG),然后创建面部标志预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('点模型数据地址')
image = cv2.imread('图片地址')#输入图片实参则读入图片
image = imutils.resize(image, width=500) # 调整图片宽度为500
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#图片调整为灰色
# 检测灰度图像中的面部
rects = detector(gray, 1)
for (i, rect) in enumerate(rects):
shape = predictor(gray, rect)
shape = shape_to_np(shape)
ii=visualize_facial_landmarks(image,shape)
cv2.imshow('ok',ii)
cv2.waitKey(0)