python3 dlib實現人臉識別和情緒分析

2021-09-11 07:47:57 字數 4386 閱讀 8860

**:

一、介紹

我想做的是基於人臉識別的表情(情緒)分析。看到網上也是有很多的開源庫提供使用,為開發提供了很大的方便。我選擇目前用的比較多的dlib庫進行人臉識別與特徵標定。使用python也縮短了開發周期。

官網對於dlib的介紹是:dlib包含廣泛的機器學習演算法。所有的設計都是高度模組化的,快速執行,並且通過乙個乾淨而現代的c ++ api,使用起來非常簡單。它用於各種應用,包括機械人技術,嵌入式裝置,手機和大型高效能計算環境。

雖然應用都比較高大上,但是自己在pc上做個情緒分析的小軟體還是挺有意思的。

按照自己的想法與思路設計識別方式。目前也比較火的keras好像就是根據嘴型的變化作為情緒分析的乙個指標。

而我的想法是利用嘴的張開比例,眼睛的睜開程度,眉毛的傾斜角度作為情緒分析的三個指標。但是由於人與人長相的差異較大,五官的也是千差萬別,再加上我的計算方法也比較簡單。所以識別效率並不是很高。

識別規則:

1、嘴巴張開距離佔面部識別框寬度的比例越大,說明情緒越激動,可能是非常開心,也可能是極度憤怒。

2、眉毛上揚,17-21 或者 22-26 號特徵點距離面部識別框頂部與識別框高度的比值越小,說明眉毛上揚越厲害,可表示驚訝、開心。眉毛的傾斜角度,開心時眉毛一般是上揚,憤怒時皺眉,同時眉毛下壓的比較厲害。

3、眯眼睛,人在開懷大笑的時候會不自覺的眯起眼睛,憤怒或者驚訝的時候會瞪大眼睛。

系統缺點:不能捕捉細微表情的變化,只能大致的判斷出人的情緒,開心、憤怒、驚訝、自然。

系統優點:結構簡單,易於上手。

應用領域:微笑抓拍,捕捉瞬間的美好、緩解兒童自閉症、互動式遊戲開發。

由於人感情的複雜性,這些表情確實不能完完全全的代表乙個人內心深處的情緒波動,如要提高判斷的準確性,則需要心率檢測、語音處理等綜合評價。

二、開發環境搭建:

1、安裝vs2015,因為最新版的dlib-19.10需要這個版本的vscode

2、安裝opencv(whl方式安裝):

3、安裝dlib(whl方式安裝):

dlib各種版本的whl檔案:

4、如果想要使用人臉模型特徵標定的話,還需要乙個人臉面部形狀**器,這個可以通過自己的**進行訓練,也可以使用dlib作者給出的乙個訓練好的**器:

三、實施思路

四、具體步驟

首先是利用dlib進行人臉識別:)

cv2

import dlib

from skimage import io

# 使用特徵提取器get_frontal_face_detector

detector = dlib.get_frontal_face_detector()

# dlib的68點模型,使用作者訓練好的特徵**器

predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

# 所在路徑

# 生成dlib的影象視窗

win = dlib.image_window()

win.clear_overlay()

win.set_image(img)

# 特徵提取器的例項化

dets = detector(img, 1)

print("人臉數:", len(dets))

for k, d in enumerate(dets):

print("第", k+1, "個人臉d的座標:",

"left:", d.left(),

"right:", d.right(),

"top:", d.top(),

"bottom:", d.bottom())

width = d.right() - d.left()

heigth = d.bottom() - d.top()

print('人臉面積為:',(width*heigth))

標定的時候使用opencv的circle方法,在特徵點的座標上面新增水印,內容就是特徵點的序號和位置。然後例項化乙個 shape_predictor 物件,使用dlib作者訓練好人臉特徵檢測器,進行人臉的特徵點標定。

# 利用**器**

shape = predictor(img, d)

# 標出68個點的位置

for i in range(68):

cv2.circle(img, (shape.part(i).x, shape.part(i).y), 4, (0, 255, 0), -1, 8)

cv2.puttext(img, str(i), (shape.part(i).x, shape.part(i).y), cv2.font_hershey_******x, 0.5, (255, 255, 255))

# 顯示一下處理的,然後銷毀視窗

cv2.imshow('face', img)

cv2.waitkey(0)

到此,68個特徵點的資訊就獲取到了,下面就需要跟根據這個68個特徵點的座標資訊,進行綜合 計算,作為每個表情的判斷指標。

根據上面說到的我的判斷指標,先計算嘴巴的張開比例,由於人離攝像頭距離的遠近,導致人臉識別框的大小不一,故選擇比例來作為判斷指標。

在選擇指標的標準數值之前,先對多個開心的人臉**進行分析。計算開心時的嘴巴張卡比例的平均。

下面是擷取對人眉毛的資料處理方法,對左邊眉毛上面的5個特徵點進行線性擬合,擬合出乙個一次函式直線,用擬合直線的斜率近似代表眉毛的傾斜程度。

# 眉毛

brow_sum = 0 # 高度之和

frown_sum = 0 # 兩邊眉毛距離之和

for j in range(17,21):

brow_sum+= (shape.part(j).y - d.top()) + (shape.part(j+5).y- d.top())

frown_sum+= shape.part(j+5).x - shape.part(j).x

brow_hight[0]+= (brow_sum/10)/self.face_width # 眉毛高度佔比

brow_width[0]+= (frown_sum/5)/self.face_width # 眉毛距離佔比

tempx = np.array(line_brow_x)

tempy = np.array(line_brow_y)

z1 = np.polyfit(tempx, tempy, 1) # 擬合成一次直線

self.brow_k = -round(z1[0], 3) # 擬合出曲線的斜率和實際眉毛的傾斜方向是相反的

我計算了25個人臉的開心表情的嘴巴張開比例、嘴巴寬度、眼睛張開程度、眉毛傾斜程度,匯入excel**生成折線圖:

通過折線圖能很明顯的看出什麼引數可以使用,什麼引數的可信度不高,什麼引數在那個範圍內可以作為乙個指標。

同樣的方法,計算人憤怒、驚訝、自然時的資料折線圖。

# 分情況討論

# 張嘴,可能是開心或者驚訝

if round(mouth_higth >= 0.03):

if eye_hight >= 0.056:

cv2.puttext(im_rd, "amazing", (d.left(), d.bottom() + 20), cv2.font_hershey_******x, 0.8,

(0, 0, 255), 2, 4)

else:

(0, 0, 255), 2, 4)

# 沒有張嘴,可能是正常和生氣

else:

if self.brow_k <= -0.3:

cv2.puttext(im_rd, "angry", (d.left(), d.bottom() + 20), cv2.font_hershey_******x, 0.8,

(0, 0, 255), 2, 4)

else:

cv2.puttext(im_rd, "nature", (d.left(), d.bottom() + 20), cv2.font_hershey_******x, 0.8,

(0, 0, 255), 2, 4)

五、實際執行效果:識別之後:

Python3結合Dlib實現人臉識別和剪下

利用python開發,借助dlib庫進行人臉識別,然後將檢測到的人臉剪下下來,依次排序顯示在新的影象上 實現的效果如下圖所示,將圖1原圖中的6張人臉檢測出來,然後剪下下來,在影象視窗中依次輸出顯示人臉 實現比較簡單,量也比較少,適合入門或者興趣學習。圖1 原圖和處理後得到的影象視窗 python 3...

python通過Dlib庫實現人臉68點特徵點標記

import cv2 影象處理庫 import dlib 人臉識別庫 from skimage import io 影象處理庫 功能 人臉檢測畫框 引數 無 返回值 預設的人臉檢測器 detector dlib.get frontal face detector print detector pre...

Dlib實現人臉檢測,並剪下人臉照

如果你的python版本也是3.6,那麼安裝dlib要簡單很多,直接 pip install dlib 19.7 0 coding utf 8 author zzz cming csdn address 2019 01 13 16 12 python3.6 import cv2 import dli...