一、項目介紹前言
人臉識別作為一種生物特征識別技術,具有非侵擾性、非接觸性、友好性和便捷性等優點。人臉識別通用的流程主要包括人臉檢測、人臉裁剪、人臉校正、特征提取和人臉識別。人臉檢測是從獲取的圖像中去除干擾,提取人臉信息,獲取人臉圖像位置,檢測的成功率主要受圖像質量,光線強弱和遮擋等因素影響。下圖是整個人臉檢測過程。 二、識別檢測方法傳統識別方法
(1)基于點云數據的人臉識別
(2)基于面部特征的3D人臉識別深度學習識別方法
(1)基于深度圖的人臉識別
(2)基于RGB-3DMM的人臉識別
(3)基于RGB-D的人臉識別 本文方法關鍵點定位概述
一般人臉中有5個關鍵點,其中包括眼睛兩個,鼻子一個,嘴角兩個。還可以細致的分為68個關鍵點,這樣的話會概括的比較全面,我們本次研究就是68個關鍵點定位。 上圖就是我們定位人臉的68個關鍵點,其中他的順序是要嚴格的進行排序的。從1到68點的順序不能錯誤。
項目解析 使用機器學習框架dlib做本次的項目。首先我們要指定參數時,要把dlib中的68關鍵點人臉定位找到。設置出來的68關鍵點人臉定位找到。并且設置出來。
from collecTIons import OrderedDict
import numpy as np
import argparse
import dlib
import cv2
首先我們導入工具包。其中dlib庫是通過這個網址http://dlib.net/files/進行下載的。然后我們導入參數。
ap = argparse.ArgumentParser()
ap.add_argument(“-p”, “--shape-predictor”, required=True,
help=“path to facial landmark predictor”)
ap.add_argument(“-i”, “--image”, required=True,
help=“path to input image”)
args = vars(ap.parse_args())
這里我們要設置參數,--shape-predictor shape_predictor_68_face_landmarks.dat --image images/lanqiudui.jpg。
如果一張圖像里面有多個人臉,那么我們分不同部分進行檢測,裁剪出來所對應的ROI區域。我們的整體思路就是先檢測人臉所在的一個區域位置,然后檢測鼻子相對于人臉框所在的一個位置,比如說人的左眼睛在0.2w,0.2h的人臉框處。
FACIAL_LANDMARKS_68_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))
])
這個是68個關鍵點定位的各個部位相對于人臉框的所在位置。分別對應著嘴,左眼、右眼、左眼眉、右眼眉、鼻子、下巴。
FACIAL_LANDMARKS_5_IDXS = OrderedDict([
(“right_eye”, (2, 3)),
(“left_eye”, (0, 1)),
(“nose”, (4))
])
如果是5點定位,那么就需要定位左眼、右眼、鼻子。0、1、2、3、4分別表示對應的5個點。
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args[“shape_predictor”])
加載人臉檢測與關鍵點定位。加載出來。其中detector默認的人臉檢測器。然后通過傳入參數返回人臉檢測矩形框4點坐標。其中predictor以圖像的某塊區域為輸入,輸出一系列的點(point locaTIon)以表示此圖像region里object的姿勢pose。返回訓練好的人臉68特征點檢測器。
image = cv2.imread(args[“image”])
(h, w) = image.shape[:2]
width=500
r = width / float(w)
dim = (width, int(h * r))
image = cv2.resize(image, dim, interpolaTIon=cv2.INTER_AREA)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
這里我們把數據讀了進來,然后進行需處理,提取h和w,其中我們自己設定圖像的w為500,然后按照比例同比例設置h。然后進行了resize操作,最后轉化為灰度圖。
rects = detector(gray, 1)
這里調用了detector的人臉框檢測器,要使用灰度圖進行檢測,這個1是重采樣個數。這里面返回的是人臉檢測矩形框4點坐標。然后對檢測框進行遍歷
for (i, rect) in enumerate(rects):
# 對人臉框進行關鍵點定位
# 轉換成ndarray
shape = predictor(gray, rect)
shape = shape_to_np(shape)
這里面返回68個關鍵點定位。shape_to_np這個函數如下。
def shape_to_np(shape, dtype=“int”):
# 創建68*2
coords = np.zeros((shape.num_parts, 2), dtype=dtype)
# 遍歷每一個關鍵點
# 得到坐標
for i in range(0, shape.num_parts):
coords[i] = (shape.part(i).x, shape.part(i).y)
return coords
這里shape_to_np函數的作用就是得到關鍵點定位的坐標。
for (name, (i, j)) in FACIAL_LANDMARKS_68_IDXS.items():
clone = image.copy()
cv2.putText(clone, name, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0, 0, 255), 2)
# 根據位置畫點
for (x, y) in shape[i:j]:
cv2.circle(clone, (x, y), 3, (0, 0, 255), -1)
# 提取ROI區域
(x, y, w, h) = cv2.boundingRect(np.array([shape[i:j]]))
roi = image[y:y + h, x:x + w]
(h, w) = roi.shape[:2]
width=250
r = width / float(w)
dim = (width, int(h * r))
roi = cv2.resize(roi, dim, interpolaTIon=cv2.INTER_AREA)
# 顯示每一部分
cv2.imshow(“ROI”, roi)
cv2.imshow(“Image”, clone)
cv2.waitKey(0)
這里字典FACIAL_LANDMARKS_68_IDXS.items()是同時提取字典中的key和value數值。然后遍歷出來這幾個區域,并且進行顯示具體是那個區域,并且將這個區域畫圓。隨后提取roi區域并且進行顯示。后面部分就是同比例顯示w和h。然后展示出來。
output = visualize_facial_landmarks(image, shape)
cv2.imshow(“Image”, output)
cv2.waitKey(0)
最后展示所有區域。 其中visualize_facial_landmarks函數就是:
def visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):
# 創建兩個copy
# overlay and one for the final output image
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_68_IDXS.keys()):
# 得到每一個點的坐標
(j, k) = FACIAL_LANDMARKS_68_IDXS[name]
pts = shape[j:k]
# 檢查位置
if name == “jaw”:
# 用線條連起來
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
這個函數是計算cv2.convexHull凸包的,也就是下圖這個意思。 這個函數cv2.addWeighted是做圖像疊加的。
src1, src2:需要融合疊加的兩副圖像,要求大小和通道數相等 alpha:src1 的權重 beta:src2 的權重 gamma:gamma 修正系數,不需要修正設置為 0 dst:可選參數,輸出結果保存的變量,默認值為 None dtype:可選參數,輸出圖像數組的深度,即圖像單個像素值的位數(如 RGB 用三個字節表示,則為 24 位),選默認值 None 表示與源圖像保持一致。 dst = src1 × alpha + src2 × beta + gamma;上面的式子理解為,結果圖像 = 圖像 1× 系數 1+圖像 2× 系數 2+亮度調節量。
編輯:黃飛
評論