基于Python+Keras+OpenCV實(shí)現(xiàn)實(shí)時(shí)人臉活體檢測(cè)
def isBlinking(history, maxFrames): """ @history: A string containing the history of eyes status where a '1' means that the eyes were closed and '0' open. @m(xù)axFrames: The maximal number of successive frames where an eye is closed """ for i in range(maxFrames): pattern = '1' + '0'*(i+1) + '1' if pattern in history: return True return False3.活體的人臉識(shí)別我們幾乎擁有了建立“真實(shí)”人臉識(shí)別算法的所有要素,我們只需要一種實(shí)時(shí)檢測(cè)人臉和眼睛的方法。我使用openCV預(yù)先訓(xùn)練的Haar級(jí)聯(lián)分類器來(lái)完成這些任務(wù)。有關(guān)Haar cascade人臉和眼睛檢測(cè)的更多信息,我強(qiáng)烈建議你閱讀openCV的這篇強(qiáng)大的文章。https://docs.opencv.org/3.4.3/d7/d8b/tutorial_py_face_detection.htmldef detect_and_display(model, video_capture, face_detector, open_eyes_detector, left_eye_detector, right_eye_detector, data, eyes_detected): frame = video_capture.read() # 調(diào)整框架大小 frame = cv2.resize(frame, (0, 0), fx=0.6, fy=0.6)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 檢測(cè)人臉 faces = face_detector.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=5, minSize=(50, 50), flags=cv2.CASCADE_SCALE_IMAGE )
# 對(duì)于每個(gè)檢測(cè)到的臉 for (x,y,w,h) in faces: # 將人臉編碼為128維嵌入向量 encoding = face_recognition.face_encodings(rgb, [(y, x+w, y+h, x)])[0]
# 將向量與所有已知的人臉編碼進(jìn)行比較 matches = face_recognition.compare_faces(data["encodings"], encoding)
# 目前我們不知道該人的名字 name = "Unknown"
# 如果至少有一次匹配: if True in matches: matchedIdxs = [i for (i, b) in enumerate(matches) if b] counts = {} for i in matchedIdxs: name = data["names"][i] counts[name] = counts.get(name, 0) + 1
# 匹配次數(shù)最多的已知編碼對(duì)應(yīng)于檢測(cè)到的人臉名稱 name = max(counts, key=counts.get)
face = frame[y:y+h,x:x+w] gray_face = gray[y:y+h,x:x+w]
eyes = []
# 眼睛檢測(cè) # 首先檢查眼睛是否睜開(kāi)(考慮到眼鏡) open_eyes_glasses = open_eyes_detector.detectMultiScale(gray_face,scaleFactor=1.1,minNeighbors=5,minSize=(30, 30),flags = cv2.CASCADE_SCALE_IMAGE ) # 如果open_eyes_glasses檢測(cè)到眼睛,則眼睛睜開(kāi) if len(open_eyes_glasses) == 2: eyes_detected[name]+='1' for (ex,ey,ew,eh) in open_eyes_glasses: cv2.rectangle(face,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
# 否則嘗試使用left和right_eye_detector檢測(cè)眼睛 # 以檢測(cè)到睜開(kāi)和閉合的眼睛 else: # 將臉?lè)殖勺笥覂蛇? left_face = frame[y:y+h, x+int(w/2):x+w] left_face_gray = gray[y:y+h, x+int(w/2):x+w]
right_face = frame[y:y+h, x:x+int(w/2)] right_face_gray = gray[y:y+h, x:x+int(w/2)]
# 檢測(cè)左眼 left_eye = left_eye_detector.detectMultiScale( left_face_gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags = cv2.CASCADE_SCALE_IMAGE )
# 檢測(cè)右眼 right_eye = right_eye_detector.detectMultiScale( right_face_gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags = cv2.CASCADE_SCALE_IMAGE )
eye_status = '1' # we suppose the eyes are open
# 檢查每只眼睛是否閉合。 # 如果有人閉著眼睛,我們得出結(jié)論是閉著眼睛 for (ex,ey,ew,eh) in right_eye: color = (0,255,0) pred = predict(right_face[ey:ey+eh,ex:ex+ew],model) if pred == 'closed': eye_status='0' color = (0,0,255) cv2.rectangle(right_face,(ex,ey),(ex+ew,ey+eh),color,2) for (ex,ey,ew,eh) in left_eye: color = (0,255,0) pred = predict(left_face[ey:ey+eh,ex:ex+ew],model) if pred == 'closed': eye_status='0' color = (0,0,255) cv2.rectangle(left_face,(ex,ey),(ex+ew,ey+eh),color,2) eyes_detected[name] += eye_status
# 每次,我們都會(huì)檢查該人是否眨眼 # 如果是,我們顯示其名字 if isBlinking(eyes_detected[name],3): cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 顯示名字 y = y - 15 if y - 15 > 15 else y + 15 cv2.putText(frame, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,0.75, (0, 255, 0), 2)
return frame上面的功能是用于檢測(cè)和識(shí)別真實(shí)人臉的代碼,它接受以下參數(shù):model:我們的睜眼/閉眼分類器video_capture:流視頻face_detector:Haar級(jí)聯(lián)的人臉?lè)诸惼。我使用了haarcascade_frontalface_alt.xmlopen_eyes_detector:Haar級(jí)聯(lián)睜眼分類器。我使用了haarcascade_eye_tree_eyeglasses.xmlleft_eye_detector:Haar級(jí)聯(lián)的左眼分類器。我使用了haarcascade_lefteye_2splits.xml,它可以檢測(cè)睜眼或閉眼。right_eye_detector:Haar級(jí)聯(lián)的右眼分類器。我使用了haarcascade_righteye_2splits.xml,它可以檢測(cè)睜眼或閉眼。data:已知編碼和已知名稱的字典eyes_detected:包含每個(gè)名稱的眼睛狀態(tài)歷史記錄的字典。在第2-4行,我們從網(wǎng)絡(luò)攝像頭流中獲取一個(gè)幀,然后調(diào)整其大小以加快計(jì)算速度。在第10行,我們從幀中檢測(cè)人臉,然后在第21行,我們將其編碼為128-d矢量。在第23-38行,我們將這個(gè)向量與已知的人臉編碼進(jìn)行比較,并通過(guò)計(jì)算匹配的次數(shù)來(lái)確定此人的姓名,選擇匹配次數(shù)最多的一個(gè)。從第45行開(kāi)始,我們?cè)囍綔y(cè)眼睛進(jìn)入人臉框。首先,我們嘗試用睜眼檢測(cè)器來(lái)檢測(cè)睜眼,如果探測(cè)器探測(cè)成功,則在第54行,將“1”添加到眼睛狀態(tài)歷史記錄中,這意味著眼睛是睜開(kāi)的,因?yàn)楸犻_(kāi)的眼睛探測(cè)器無(wú)法檢測(cè)到閉著的眼睛;否則,如果第一個(gè)分類器失。ǹ赡苁且?yàn)檠劬κ情]著的,或者僅僅是因?yàn)樗荒茏R(shí)別眼睛),則使用左眼和右眼檢測(cè)器,人臉被分為左右兩側(cè),以便對(duì)各個(gè)探測(cè)器進(jìn)行分類。從第92行開(kāi)始,提取眼睛部分,訓(xùn)練后的模型預(yù)測(cè)眼睛是否閉合,如果檢測(cè)到一只眼睛閉著,則兩眼都將被預(yù)測(cè)為閉著,并將“0”添加到眼睛狀態(tài)歷史記錄中;否則就可以斷定眼睛是睜開(kāi)的。最后,在第110行,is blinking()函數(shù)用于檢測(cè)眨眼,如果該人眨眼,則顯示姓名。整個(gè)代碼都可以在我的github帳戶上找到。

發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
3月27日立即報(bào)名>> 【工程師系列】汽車電子技術(shù)在線大會(huì)
-
4月30日立即下載>> 【村田汽車】汽車E/E架構(gòu)革新中,新智能座艙挑戰(zhàn)的解決方案
-
5月15-17日立即預(yù)約>> 【線下巡回】2025年STM32峰會(huì)
-
即日-5.15立即報(bào)名>>> 【在線會(huì)議】安森美Hyperlux™ ID系列引領(lǐng)iToF技術(shù)革新
-
5月15日立即下載>> 【白皮書(shū)】精確和高效地表征3000V/20A功率器件應(yīng)用指南
-
5月16日立即參評(píng) >> 【評(píng)選啟動(dòng)】維科杯·OFweek 2025(第十屆)人工智能行業(yè)年度評(píng)選
推薦專題
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達(dá)AI統(tǒng)治的開(kāi)始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 4 “AI寒武紀(jì)”爆發(fā)至今,五類新物種登上歷史舞臺(tái)
- 5 國(guó)產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計(jì)算迎來(lái)商業(yè)化突破,但落地仍需時(shí)間
- 7 東陽(yáng)光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開(kāi)成長(zhǎng)空間
- 8 地平線自動(dòng)駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營(yíng)收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機(jī)器人東風(fēng)翻身?