1 前言
?? 優(yōu)質(zhì)競賽項目系列,今天要分享的是
?? 基于深度學(xué)習(xí)的人臉專注度檢測計算算法
該項目較為新穎,適合作為競賽課題方向,學(xué)長非常推薦!
??學(xué)長這里給一個題目綜合評分(每項滿分5分)
- 難度系數(shù):3分
- 工作量:3分
- 創(chuàng)新點:5分
?? 更多資料, 項目分享:文章來源:http://www.zghlxwxcb.cn/news/detail-734207.html
https://gitee.com/dancheng-senior/postgraduate文章來源地址http://www.zghlxwxcb.cn/news/detail-734207.html
2 相關(guān)技術(shù)
2.1CNN簡介
卷積神經(jīng)網(wǎng)絡(luò)(CNN),是由多層卷積結(jié)構(gòu)組成的一種神經(jīng)網(wǎng)絡(luò)。卷積結(jié)構(gòu)可以減少網(wǎng)絡(luò)的內(nèi)存占用、參數(shù)和模型的過擬合。卷積神經(jīng)網(wǎng)絡(luò)是一種典型的深度學(xué)習(xí)算法。廣泛應(yīng)用于視覺處理和人工智能領(lǐng)域,特別是在圖像識別和人臉識別領(lǐng)域。與完全連接的神經(jīng)網(wǎng)絡(luò)相比,CNN輸入是通過交換參數(shù)和局部感知來提取圖像特征的圖像。卷積神經(jīng)網(wǎng)絡(luò)是由輸入層、卷積層、池化層、全連接層和輸出層五層結(jié)構(gòu)組成。其具體模型如下圖所示。
(1)輸入層(Input
layer):輸入層就是神經(jīng)網(wǎng)絡(luò)的輸入端口,就是把輸入傳入的入口。通常傳入的圖像的R,G,B三個通道的數(shù)據(jù)。數(shù)據(jù)的輸入一般是多維的矩陣向量,其中矩陣中的數(shù)值代表的是圖像對應(yīng)位置的像素點的值。
(2)卷積層(Convolution layer):卷積層在CNN中主要具有學(xué)習(xí)功能,它主要提取輸入的數(shù)據(jù)的特征值。
(3)池化層(Pooling
layer):池化層通過對卷積層的特征值進行壓縮來獲得自己的特征值,減小特征值的矩陣的維度,減小網(wǎng)絡(luò)計算量,加速收斂速度可以有效避免過擬合問題。
(4)全連接層(Full connected
layer):全連接層主要實現(xiàn)是把經(jīng)過卷積層和池化層處理的數(shù)據(jù)進行集合在一起,形成一個或者多個的全連接層,該層在CNN的功能主要是實現(xiàn)高階推理計算。
(5)輸出層(Output layer):輸出層在全連接層之后,是整個神經(jīng)網(wǎng)絡(luò)的輸出端口即把處理分析后的數(shù)據(jù)進行輸出。
2.2 人臉識別算法
利用dlib實現(xiàn)人臉68個關(guān)鍵點檢測并標注,關(guān)鍵代碼
?
import cv2
# 加載人臉識別模型
face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat'
facerec = dlib.face_recognition_model_v1(face_rec_model_path)
# 加載特征點識別模型
predictor_path = "shape_predictor_5_face_landmarks.dat"
predictor = dlib.shape_predictor(predictor_path)
# 讀取圖片
img_path = "step1/image/face.jpg"
img = cv2.imread(img_path)
# 轉(zhuǎn)換為灰階圖片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 正向人臉檢測器將圖像
detector = dlib.get_frontal_face_detector()
# 使用人臉識別模型來檢測圖像中的人臉
faces = detector(gray, 1)
# 使用特征點識別模型來檢測人臉中的特征
for i, face in enumerate(faces):
# 獲取人臉特征點
shape = predictor(img, face)
?
2.3專注檢測原理
總體流程
主要通過電腦攝像頭去實時的抓拍學(xué)生當前的狀態(tài)和行為,不間斷的采集學(xué)生上課時的面部表情和眼睛注視的方向,利用CNN提取相應(yīng)的特征數(shù)據(jù)并進行分析處理,若對應(yīng)輸出的判斷值大于設(shè)置的閾值時,則認為學(xué)生在走神沒有認真學(xué)習(xí)。并且對拍攝時間進行計時,在界面上實時輸出該學(xué)生在課堂上的有效學(xué)習(xí)時間和學(xué)生在課堂上專注時間的比例并進行存入表格中。
眼睛檢測算法
基于dlib人臉識別68特征點檢測、分別獲取左右眼面部標志的索引,通過opencv對視頻流進行灰度化處理,檢測出人眼的位置信息。人臉特征點檢測用到了dlib,dlib有兩個關(guān)鍵函數(shù):dlib.get_frontal_face_detector()和dlib.shape_predictor(predictor_path)。
前者是內(nèi)置的人臉檢測算法,使用HOG pyramid,檢測人臉區(qū)域的界限(bounds)。
后者是用來檢測一個區(qū)域內(nèi)的特征點,并輸出這些特征點的坐標,它需要一個預(yù)先訓(xùn)練好的模型(通過文件路徑的方法傳入),才能正常工作。
使用開源模型shape_predictor_68_face_landmarks.dat,可以得到68個特征點位置的坐標,連起來后,可以有如圖所示的效果(紅色是HOG
pyramid檢測的結(jié)果,綠色是shape_predictor的結(jié)果,僅把同一個器官的特征點連線)。
通過計算眼睛的寬高比來確定專注狀態(tài)
基本原理:計算 眼睛長寬比 Eye Aspect Ratio,EAR.當人眼睜開時,EAR在某個值上下波動,當人眼閉合時
關(guān)鍵代碼
?
# -*- coding: utf-8 -*-
# import the necessary packages
from scipy.spatial import distance as dist
from imutils.video import FileVideoStream
from imutils.video import VideoStream
from imutils import face_utils
import numpy as np # 數(shù)據(jù)處理的庫 numpy
import argparse
import imutils
import time
import dlib
import cv2
def eye_aspect_ratio(eye):
# 垂直眼標志(X,Y)坐標
A = dist.euclidean(eye[1], eye[5])# 計算兩個集合之間的歐式距離
B = dist.euclidean(eye[2], eye[4])
# 計算水平之間的歐幾里得距離
# 水平眼標志(X,Y)坐標
C = dist.euclidean(eye[0], eye[3])
# 眼睛長寬比的計算
ear = (A + B) / (2.0 * C)
# 返回眼睛的長寬比
return ear
# 定義兩個常數(shù)
# 眼睛長寬比
# 閃爍閾值
EYE_AR_THRESH = 0.2
EYE_AR_CONSEC_FRAMES = 3
# 初始化幀計數(shù)器和眨眼總數(shù)
COUNTER = 0
TOTAL = 0
# 初始化DLIB的人臉檢測器(HOG),然后創(chuàng)建面部標志物預(yù)測
print("[INFO] loading facial landmark predictor...")
# 第一步:使用dlib.get_frontal_face_detector() 獲得臉部位置檢測器
detector = dlib.get_frontal_face_detector()
# 第二步:使用dlib.shape_predictor獲得臉部特征位置檢測器
predictor = dlib.shape_predictor('D:/myworkspace/JupyterNotebook/fatigue_detecting/model/shape_predictor_68_face_landmarks.dat')
# 第三步:分別獲取左右眼面部標志的索引
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
# 第四步:打開cv2 本地攝像頭
cap = cv2.VideoCapture(0)
# 從視頻流循環(huán)幀
while True:
# 第五步:進行循環(huán),讀取圖片,并對圖片做維度擴大,并進灰度化
ret, frame = cap.read()
frame = imutils.resize(frame, width=720)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 第六步:使用detector(gray, 0) 進行臉部位置檢測
rects = detector(gray, 0)
# 第七步:循環(huán)臉部位置信息,使用predictor(gray, rect)獲得臉部特征位置的信息
for rect in rects:
shape = predictor(gray, rect)
# 第八步:將臉部特征信息轉(zhuǎn)換為數(shù)組array的格式
shape = face_utils.shape_to_np(shape)
# 第九步:提取左眼和右眼坐標
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
# 第十步:構(gòu)造函數(shù)計算左右眼的EAR值,使用平均值作為最終的EAR
leftEAR = eye_aspect_ratio(leftEye)
rightEAR = eye_aspect_ratio(rightEye)
ear = (leftEAR + rightEAR) / 2.0
# 第十一步:使用cv2.convexHull獲得凸包位置,使用drawContours畫出輪廓位置進行畫圖操作
leftEyeHull = cv2.convexHull(leftEye)
rightEyeHull = cv2.convexHull(rightEye)
cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)
# 第十二步:進行畫圖操作,用矩形框標注人臉
left = rect.left()
top = rect.top()
right = rect.right()
bottom = rect.bottom()
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 3)
'''
分別計算左眼和右眼的評分求平均作為最終的評分,如果小于閾值,則加1,如果連續(xù)3次都小于閾值,則表示進行了一次眨眼活動
'''
# 第十三步:循環(huán),滿足條件的,眨眼次數(shù)+1
if ear < EYE_AR_THRESH:# 眼睛長寬比:0.2
COUNTER += 1
else:
# 如果連續(xù)3次都小于閾值,則表示進行了一次眨眼活動
if COUNTER >= EYE_AR_CONSEC_FRAMES:# 閾值:3
TOTAL += 1
# 重置眼幀計數(shù)器
COUNTER = 0
# 第十四步:進行畫圖操作,68個特征點標識
for (x, y) in shape:
cv2.circle(frame, (x, y), 1, (0, 0, 255), -1)
# 第十五步:進行畫圖操作,同時使用cv2.putText將眨眼次數(shù)進行顯示
cv2.putText(frame, "Faces: {}".format(len(rects)), (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "Blinks: {}".format(TOTAL), (150, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "COUNTER: {}".format(COUNTER), (300, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "EAR: {:.2f}".format(ear), (450, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
print('眼睛實時長寬比:{:.2f} '.format(ear))
if TOTAL >= 50:
cv2.putText(frame, "SLEEP!!!", (200, 200),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
cv2.putText(frame, "Press 'q': Quit", (20, 500),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (84, 255, 159), 2)
# 窗口顯示 show with opencv
cv2.imshow("Frame", frame)
# if the `q` key was pressed, break from the loop
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 釋放攝像頭 release camera
cap.release()
# do a bit of cleanup
cv2.destroyAllWindows()
?
2.4 OpenCV
OpenCV是計算機視覺中一個經(jīng)典的數(shù)據(jù)庫。支持多語言、跨平臺、功能強大。其提供了一個Python接口,用戶可以在保證可讀性和操作效率的前提下,用Python調(diào)用C/C++實現(xiàn)所需的功能。OpenCV是一個基于BSD許可證的跨平臺計算機視覺庫,可以在Linux、windows和Mac
OS操作系統(tǒng)上運行。它由一系列C函數(shù)和少量C++類組成。同時,它還提供了與Python、ruby、MATLAB等語言的接口,實現(xiàn)了圖像處理和計算機視覺中的許多通用算法。
本項目中OpenCV主要是在圖片的采集的圖片的預(yù)處理方面使用,通過操作界面中的按鈕選項選擇是否打開攝像頭,使用OpenCV來調(diào)用電腦攝像頭來檢測錄像過程中的聚焦和人臉鏡頭的矯正等狀態(tài),然后在攝像頭的錄像的視頻流中抓取對應(yīng)的人臉照片,然后調(diào)用內(nèi)部的函數(shù)對照片的尺寸和光線等進行矯正處理后,傳給神經(jīng)網(wǎng)絡(luò)進行特征值提取。
3 功能介紹
3.1人臉錄入功能
數(shù)據(jù)庫數(shù)據(jù)錄入
將采集到的人臉信息和姓名、學(xué)號錄入到數(shù)據(jù)庫中,數(shù)據(jù)庫表如下圖所示:
過程演示
3.2 人臉識別
3.3 人臉專注度檢測
拍攝時間進行計時,在界面上實時輸出該學(xué)生在課堂上的有效學(xué)習(xí)時間和學(xué)生在課堂上專注時間的比例
3.4 識別記錄
4 最后
?? 更多資料, 項目分享:
https://gitee.com/dancheng-senior/postgraduate
到了這里,關(guān)于基于深度學(xué)習(xí)的人臉專注度檢測計算系統(tǒng) - opencv python cnn 計算機競賽的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!