1. 程式人生 > >python OpenCV+dlib 實時進行面部標誌檢測(一)

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)