Opencv之人脸关键点定位
生活随笔
收集整理的這篇文章主要介紹了
Opencv之人脸关键点定位
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
項目要求
在包含(一個或多個)人臉的圖片中對臉上的某些部位(嘴巴、眉毛等部位)進行標記。
代碼實現(xiàn)
1、導入工具包
import numpy as np import dlib import cv22、對臉上的部位進行定義
在關鍵點定位的官方文檔中,提取68個關鍵點來表示臉上的部位。其中:
- 第1個點到第17個點:臉頰;
- 第18個點到第22個點:右邊眉毛;
- 第23個點到第27個點:左邊眉毛;
- 第28個點到第36個點:鼻子;
- 第37個點到第42個點:右眼;
- 第43個點到第48個點:左眼;
- 第49個點到第68個點:嘴巴。
如下圖所示:
3、加載dlib庫中的人臉檢測與關鍵點定位
detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')4、導入圖片并進行預處理
image = cv2.imread('./images/liudehua.jpg') (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)5、進行人臉檢測
rects = detector(gray, 1)detector()返回的結果是包含著檢測到的人臉的方框的左上角坐標和右下角坐標。
6、得到關鍵點的坐標
shape = predictor(gray, rect)此處返回的shape并不是關鍵點的坐標,我們需要將其中包含的坐標信息提取出來。
寫一個函數(shù) shape_to_np(shape, dtype=“int”) 將shape的返回值轉換為能用的坐標信息。
調用這個函數(shù):
shape = shape_to_np(shape)7、將每一個關鍵點繪制在圖上
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)# 根據(jù)位置畫點for (x, y) in shape[i:j]:cv2.circle(clone, (x, y), 3, (0, 0, 255), -1)# 提取ROI區(qū)域(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=250r = 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)8、將關鍵點圍出的面部部位在圖上標記出來
其中,臉頰部位可以用線連接起來,其他部位用凸包畫出。
# 創(chuàng)建兩個copy # overlay and one for the final output image overlay = image.copy() output = image.copy() # 設置一些顏色區(qū)域 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)] # 遍歷每一個區(qū)域 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)# 展示所有區(qū)域 output = visualize_facial_landmarks(image, shape) cv2.imshow("Image", output) cv2.waitKey(0) cv2.destroyAllWindows()如果檢測的圖片中有兩張人臉,只需要加一個循環(huán)即可,參考下面的完整代碼部分。
完整代碼
#導入工具包 import numpy as np import dlib import cv2#https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/ #http://dlib.net/files/FACIAL_LANDMARKS_68_IDXS = dict([("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 shape_to_np(shape, dtype="int"):# 創(chuàng)建68*2coords = 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) # 第i個關鍵點的橫縱坐標。return coordsdef visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):# 創(chuàng)建兩個copy# overlay and one for the final output imageoverlay = image.copy()output = image.copy()# 設置一些顏色區(qū)域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)]# 遍歷每一個區(qū)域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# 加載人臉檢測與關鍵點定位 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')# 讀取輸入數(shù)據(jù),預處理 image = cv2.imread('./images/liudehua2.jpg') (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)# 人臉檢測 rects = detector(gray, 1)# 遍歷檢測到的框 for (_, rect) in enumerate(rects):# 對人臉框進行關鍵點定位# 轉換成ndarrayshape = predictor(gray, rect)shape = shape_to_np(shape)# 遍歷每一個部分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)# 根據(jù)位置畫點for (x, y) in shape[i:j]:cv2.circle(clone, (x, y), 3, (0, 0, 255), -1)# 提取ROI區(qū)域(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=250r = 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)# 展示所有區(qū)域output = visualize_facial_landmarks(image, shape)cv2.imshow("Image", output)cv2.waitKey(0)cv2.destroyAllWindows()最終效果
總結
以上是生活随笔為你收集整理的Opencv之人脸关键点定位的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssl服务器无响应,iOS上的IBM A
- 下一篇: 热门职业考证大排行