python OpenCV+dlib 实时进行面部标志检测(一)

面部区域的面部标志索引

在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)

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_yuki_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值