0. 引言
利用 Dlib 官方訓練好的模型 “shape_predictor_68_face_landmarks.dat” 進行 68 個點標定;
利用 OpenCv 進行圖像化處理,在人臉上畫出 68 個特征點,並標明特征點的序號;
實現的 68 個特征點標定功能如下圖所示:

圖 1 人臉 68 個特征點的標定
1. 開發環境
Python: 3.6.3
Dlib: 19.7
Opencv, NumPy
需要調用的庫:
import dlib # 人臉檢測的庫 Dlib
import numpy as np # 數據處理的庫 Numpy
import cv2 # 圖像處理的庫 OpenCv
2. 設計流程
兩部分:68 個特征點提取 和 OpenCv 繪圖
68 點提取:
借助 Dlib 官方的 Demo: face_landmark_detection.py,可以得到臉部 68 個特征點的坐標;
OpenCv 繪圖:
使用 opencv 中 畫圓函數 cv2.circle() 和 畫字符函數 cv2.putText() ;
流程:
1. 調用 Dlib 庫來進行人臉識別,調用預測器 “shape_predictor_68_face_landmarks.dat” 進行 68 點標定;
2. 存入 68 個點坐標;
3. 利用 cv2.circle 來畫 68 個點;
4. 利用 cv2.putText() 函數來畫數字 1-68 ;
3. 源碼
# 對靜態人臉圖像文件進行68個特征點的標定 # Author: coneypo # Blog: http://www.cnblogs.com/AdaminXie # GitHub: https://github.com/coneypo/Dlib_face_detection_from_camera import dlib # 人臉識別的庫 Dlib import numpy as np # 數據處理的庫 numpy import cv2 # 圖像處理的庫 OpenCv # Dlib 檢測器和預測器 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor('data/dlib/shape_predictor_68_face_landmarks.dat') # 讀取圖像文件 img_rd = cv2.imread("test.jpg") img_gray = cv2.cvtColor(img_rd, cv2.COLOR_RGB2GRAY) # 人臉數 faces = detector(img_gray, 0) # 待會要寫的字體 font = cv2.FONT_HERSHEY_SIMPLEX # 標 68 個點 if len(faces) != 0: # 檢測到人臉 for i in range(len(faces)): # 取特征點坐標 landmarks = np.matrix([[p.x, p.y] for p in predictor(img_rd, faces[i]).parts()]) for idx, point in enumerate(landmarks): # 68 點的坐標 pos = (point[0, 0], point[0, 1]) # 利用 cv2.circle 給每個特征點畫一個圈,共 68 個 cv2.circle(img_rd, pos, 2, color=(139, 0, 0)) # 利用 cv2.putText 寫數字 1-68 cv2.putText(img_rd, str(idx + 1), pos, font, 0.2, (187, 255, 255), 1, cv2.LINE_AA) cv2.putText(img_rd, "faces: " + str(len(faces)), (20, 50), font, 1, (0, 0, 0), 1, cv2.LINE_AA) else: # 沒有檢測到人臉 cv2.putText(img_rd, "no face", (20, 50), font, 1, (0, 0, 0), 1, cv2.LINE_AA) # 窗口顯示 # 參數取 0 可以拖動縮放窗口,為 1 不可以 # cv2.namedWindow("image", 0) cv2.namedWindow("image", 1) cv2.imshow("image", img_rd) cv2.waitKey(0)
OpenCv 的畫圖函數
1. 畫圓 cv2.circle( img, (p1,p2), r, (255,255,255) )
cv2.circle(img=img, center=(50,30), radius=4, color=(255,0,255))
參數 1: img- 圖片對象 img;
參數 2: (p1,p2)- 圓心坐標 center;
參數 3: r- 半徑 radius;
參數 4: (255,255,255)- 顏色數組;
2. 寫字符 cv2.putText( img,"test", (p1,p2), font, 4, (255,255,255), 2, cv2, LINE_AA )
cv2.putText(img=img, text="hello world", org=(10,30), fontFace=font, fontScale=0.6, color=(187, 255, 255), thickness=1, lineType=cv2.LINE_AA)
參數 1: img- 圖像對象 img;
參數 2: "test"- 需要打印的字符 text(數字的話可以利用 str() 轉成字符);
參數 3: (p1,p2)- 坐標 textOrg;
參數 4: font- 字體 fontFace( 注意這里 font = cv2.FONT_HERSHEY_SIMPLEX );
參數 5: 4- 字號 fontScale;
參數 6: (255,255,255)- 顏色數組 color;
參數 7: 2- 線寬 thickness;
參數 8: LINE_AA- 線條種類 line_type;
* 關於 顏色數組:
(255,255,255), (藍色,綠色,紅色),每個值都是 0-255;
比如:藍色 (255,0,0),紫色 (255,0,255)
圖 2 部分顏色數組示意(具體可以參考 http://tool.oschina.net/commons?type=3 )
# 請尊重他人勞動成果,轉載或者使用源碼請注明出處 http://cnblogs.com/AdaminXie/
# 如有問題可以留言或者聯系郵箱 coneypo@foxmail.com