關(guān)于OpenCV for Python入門之Dlib實(shí)現(xiàn)人臉檢測
Dlib 是用編程語言 C ++編寫的通用跨平臺軟件庫。它的設(shè)計(jì)深受來自契約式設(shè)計(jì)和基于組件的軟件工程的思想的影響。因此,首先也是最重要的是一組獨(dú)立的軟件組件。這是一個(gè)加速軟件許可證下發(fā)布的開源軟件。
Dlib包含用于處理網(wǎng)絡(luò),線程,圖形用戶界面,數(shù)據(jù)結(jié)構(gòu),線性代數(shù),機(jī)器學(xué)習(xí),圖像處理,數(shù)據(jù)挖掘,XML 和文本解析,數(shù)值優(yōu)化,貝葉斯網(wǎng)絡(luò)以及許多其他任務(wù)的軟件組件。近年來,許多開發(fā)工作都集中在創(chuàng)建廣泛的統(tǒng)計(jì)機(jī)器學(xué)習(xí)工具上。2009 年,Dlib 發(fā)表在機(jī)器學(xué)習(xí)研究。從那時(shí)起,它已在廣泛的領(lǐng)域中使用。
使用dlib可以大大簡化開發(fā),比如人臉識別,特征點(diǎn)檢測之類的工作都可以很輕松實(shí)現(xiàn)。同時(shí)也有很多基于dlib開發(fā)的應(yīng)用和開源庫,比如face_recogintion庫(應(yīng)用一個(gè)基于Python的開源人臉識別庫,face_recognition)等等。
dlib庫采用68點(diǎn)位置標(biāo)志人臉重要部位,比如18-22點(diǎn)標(biāo)志右眉毛,23-27點(diǎn)標(biāo)志左眉毛,37-42點(diǎn)標(biāo)志左眼,43-48點(diǎn)標(biāo)志右眼,32-36點(diǎn)標(biāo)志鼻子,49-68標(biāo)志嘴巴,這其中還可以識別嘴唇。
可以通過對眼睛的算法變換,識別出眨眼、瞇眼等動作,對眼睛、嘴巴的變換實(shí)現(xiàn)各種情緒的識別。
也可以通過對人的68點(diǎn)構(gòu)造算法模型,進(jìn)行人臉識別。
dlib的安裝比較麻煩,尤其是python3.7版本,通過pip intall命名無法安裝成功,建議自行到網(wǎng)上下載whl包,可節(jié)約探索時(shí)間。
# windows 通過whl文件安裝dlib
# dlib在python3.7版本下兼容性有問題,即使安裝了 Visual Studio 也還是無法安裝dlib
# 因此從網(wǎng)上下載了dlib for python37的whl文件
# pip install dlib-19.17.99-cp37-cp37m-win_amd64.whl
# pip install face_recognition
# pip install imutils
import dlib
import numpy as np
import cv2
import imutils
from imutils import face_utils
# 使用 Dlib 的正面人臉檢測器 frontal_face_detector
detector = dlib.get_frontal_face_detector()
# 使用訓(xùn)練好的模型shape_predictor_68_face_landmarks.dat,在檢測出人臉的同時(shí),檢測出人臉上的68個(gè)關(guān)鍵點(diǎn)
predictor=dlib.shape_predictor(r'C:\Python\Pycharm\docxprocess\face_detector\shape_predictor_68_face_landmarks.dat')
# 圖片所在路徑
imgname = r'C:\Python\Pycharm\docxprocess\picture\other\renwu\juhui1.jpg' #21
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\renwu\juhui2.png' #6
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\angry.png'
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\ldh.png'
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\happy.png'
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\shigu.jpeg'
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\renwu\juhui4.png' #24
# 讀取圖片,轉(zhuǎn)換灰度
img = cv2.imread(imgname)
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 人臉檢測,獲得人臉數(shù)據(jù)
faces = detector(img_gray, 1)
# rectangles[[(941, 254) (977, 290)], [(361, 210) (397, 246)], [(717, 138) (753, 174)], [(801, 214) (837, 250)],
# [(573, 138) (609, 174)], [(45, 210) (81, 246)], [(585, 202) (621, 238)], [(189, 254) (225, 290)],
# [(245, 214) (281, 250)], [(689, 210) (725, 246)], [(419, 247) (463, 290)], [(553, 242) (589, 278)],
# [(901, 218) (937, 254)], [(77, 246) (113, 282)], [(141, 222) (177, 258)], [(741, 242) (777, 278)],
# [(485, 202) (521, 238)], [(161, 110) (197, 146)], [(297, 166) (333, 202)], [(905, 138) (941, 174)],
# [(301, 246) (337, 282)], [(865, 106) (901, 142)], [(389, 146) (425, 182)], [(241, 138) (277, 174)]]
if len(faces) < 1:
print("未檢測到人臉")
else:
print("人臉數(shù)總數(shù)為", len(faces))
for(i, rect) in enumerate(faces):
# 返回人臉框的左上角坐標(biāo)和矩形框的尺寸
(x, y, w, h) = face_utils.rect_to_bb(rect)
# 在圖片上畫矩形框和輸出檢測的人臉數(shù)量
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(img, "Face #{}".format(i + 1), (x - 10, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imshow("Output", img)
cv2.waitKey(0)
之前opencv自帶的人臉檢測結(jié)果
1927年在比利時(shí)布魯塞爾召開的第五次索爾維會議,黑白照片,檢測出21人。
1924年林徽因等與訪問中國的泰戈?duì)柡嫌?,?個(gè)人,重要的泰戈?duì)枦]檢測出來。
1927年在比利時(shí)布魯塞爾召開的第五次索爾維會議,彩色照片,檢測出24人。
不老男神,帥氣的劉德華。
使用訓(xùn)練好的模型shape_predictor_68_face_landmarks.dat,在檢測出人臉的同時(shí),檢測出人臉上的68個(gè)關(guān)鍵點(diǎn),再看一下劉德華。
import dlib
import numpy as np
import cv2
import imutils
from imutils import face_utils
# 使用 Dlib 的正面人臉檢測器 frontal_face_detector
detector = dlib.get_frontal_face_detector()
# 使用訓(xùn)練好的模型shape_predictor_68_face_landmarks.dat,在檢測出人臉的同時(shí),檢測出人臉上的68個(gè)關(guān)鍵點(diǎn)
predictor=dlib.shape_predictor(r'C:\Python\Pycharm\docxprocess\face_detector\shape_predictor_68_face_landmarks.dat')
# 圖片所在路徑
imgname = r'C:\Python\Pycharm\docxprocess\picture\other\renwu\juhui1.jpg' #21
imgname = r'C:\Python\Pycharm\docxprocess\picture\other\renwu\juhui2.png' #6
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\angry.png'
imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\ldh.png'
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\happy.png'
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\ldh\shigu.jpeg'
# imgname = r'C:\Python\Pycharm\docxprocess\picture\other\renwu\juhui4.png' #24
# 讀取圖片,轉(zhuǎn)換灰度
img = cv2.imread(imgname)
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 人臉檢測,獲得人臉數(shù)據(jù)
faces = detector(img_gray, 1)
# rectangles[[(941, 254) (977, 290)], [(361, 210) (397, 246)], [(717, 138) (753, 174)], [(801, 214) (837, 250)],
# [(573, 138) (609, 174)], [(45, 210) (81, 246)], [(585, 202) (621, 238)], [(189, 254) (225, 290)],
# [(245, 214) (281, 250)], [(689, 210) (725, 246)], [(419, 247) (463, 290)], [(553, 242) (589, 278)],
# [(901, 218) (937, 254)], [(77, 246) (113, 282)], [(141, 222) (177, 258)], [(741, 242) (777, 278)],
# [(485, 202) (521, 238)], [(161, 110) (197, 146)], [(297, 166) (333, 202)], [(905, 138) (941, 174)],
# [(301, 246) (337, 282)], [(865, 106) (901, 142)], [(389, 146) (425, 182)], [(241, 138) (277, 174)]]
if len(faces) < 1:
print("未檢測到人臉")
else:
print("人臉數(shù)總數(shù)為", len(faces))
for(i, rect) in enumerate(faces):
# 返回人臉框的左上角坐標(biāo)和矩形框的尺寸
(x, y, w, h) = face_utils.rect_to_bb(rect)
# 在圖片上畫矩形框和輸出檢測的人臉數(shù)量
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(img, "Face #{}".format(i + 1), (x - 10, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# 標(biāo)記人臉中的68個(gè)landmark點(diǎn)
shape = predictor(img_gray, rect)
# <dlib.full_object_detection object at 0x0000018AF09586F8>
# shape轉(zhuǎn)換成68個(gè)坐標(biāo)點(diǎn)矩陣
shape = face_utils.shape_to_np(shape)
# [[245 149]
# [245 152]
# ...
# [246 159]]
# [[364 225]
# [365 228]
# ...
# [366 236]]
# 在源圖上輸出landmark點(diǎn)
for j,(x, y) in enumerate(shape):
cv2.circle(img, (x, y), 2, (0, 0, 255), -1)
cv2.putText(img, "{}".format(j + 1), (x - 10, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imshow("Output", img)
cv2.waitKey(0)