《百度AI人臉識別與檢測》專欄為項目專欄,從零到一,從無到有開發一個學生人臉識別簽到系統;主要用到的技術有百度開放平臺中的人臉檢測、人臉識別、Python圖形界面開發PyQt5、線程的管理、以及通過python調用百度接口實現人臉檢測、百度開放平臺中人臉檢測技術文檔的理解等,由淺入深、由局部到整體的一個項目學習過程,如果你想對人臉識別感興趣,對python的圖形界面設計感興趣,可以訂閱本專欄,因為對你可能有幫助哦!
前文參考:
百度AI人臉識別與檢測一:學生人臉識別簽到系統簡介及百度AI開放平臺賬號注冊和人臉實例應用創建
百度AI人臉識別與檢測二:學生人臉識別打卡簽到系統主界面功能需求和設計以及通過Python實現界面運行
百度AI人臉識別與檢測三:學生人臉識別打卡簽到系統通過OpenCV實現電腦攝像頭數據在Label控件上的實時顯示
百度AI人臉識別與檢測四:學生人臉識別打卡簽到系統之百度AI人臉檢測及相應程序異常處理
最近博客發布于6個月之前,這半年時間,學長也接收到很多小伙伴對《百度AI人臉識別與檢測》專欄的催更,但也只做了簡單的回應。在這脫更的半年時間中,學長完成了自己的畢業設計、畢業論文,同時拿到了自己工作單位的offer,成為了一名簡簡單單的程序員;拿到了自己的駕駛證,成為了新手司機中的一份子;拿到了屬于自己大學四年的畢業證和學位證,成為了廣大校友中的一名新人。從學校到職場,從學生到校友,是林君學長這脫更6個月的變化。自己的大學四年,感謝每一位教育過自己的老師,同時也感謝物聯一班的每一位同學、朋友。但總之,學長再次開始了屬于自己的創作之旅。祝愿我們每一位小伙伴都能在學習中進步和成長,不只是簡單的應付作業哦!
百度AI人臉識別與檢測五:學生人臉識別打卡簽到系統之百度AI人臉識別
- 一、百度AI人臉識別API接口
- 1、創建用戶臉部信息組
- 2、創建用戶臉部信息
- 3、人臉搜索API請求文檔說明
- 4、人臉搜索API返回參數說明
- 二、完成系統人臉識別功能模塊
- 1、定義人臉識別數據接收和發送信號
- 2、編寫人臉搜索訪問方法
- 3、調用函數,進行人臉識別
- 4、主線程人臉識別數據接收顯示
- 5、人臉識別運行結果測試
上次博客我們介紹了百度AI的人臉檢測,并通過界面實現了基本的人臉檢測,本次博客林君學長將帶大家了解、并實現基于百度AI的人臉識別。人臉識別和人臉檢測有本質上的區別,人臉檢測只是將圖像或者視頻中的人臉進行一個簡單的檢測,包括面部表情、顏值分數、是否佩戴眼鏡等等;而人臉識別是指將圖像或者視頻的人臉進行檢測,然后進行識別,不僅檢測到這個人,還要識別出這個人是誰,叫什么名字,對應的了解到這個人的一系列信息。因此,人臉識別是在人臉檢測到的基礎上,通過對應的特征對比,來判斷數據庫中的人臉特征是否有與檢測的到的人臉特征一致,如果一致,找到此人;如果不一致,查無此人!
一、百度AI人臉識別API接口
百度AI人臉識別API接口是本地代碼與百度云服務器進行連接的訪問規則,本次博客需要對百度人臉識別進行訪問,因此需要查看對應的API接口規則,根據規則編寫訪問接口的Python代碼。而對于對應接口地址,在上次博客中已經介紹如何查看,本次博客需要用到的人臉識別主要用的是其中的人臉搜索接口。
1、創建用戶臉部信息組
最新的百度AI開放平臺好像要進行實名認證,然后才能領取免費的人臉識別模塊,打開人臉識別模塊的功能,所以小伙伴記得去實名認證,然后免費領取一下
既然是人臉搜索,對應的應該有一個用戶的臉部信息庫,但由于初次運用,需要我們手動錄取信息,在之后的項目中,可以通過軟件自動添加人臉信息或者更新人臉信息,便不再需要在百度AI平臺上進行手動添加。由于初次進行識別,我們需要穿件用戶組合人臉信息,具體步驟如下所示:
(1)、打開控制臺,找到人臉識別版塊后選擇管理應用,上次博客我們創建了應用實例。
(2)、在學生人臉打開簽到系統實例中,點擊查看人臉庫。
(3)、點擊新建組,ID我們取為class1,寓意為第一個班級,然后點擊確定。
通過以上步驟,我們的班級就創建好了!接下來,我們為班級中添加學生吧!
2、創建用戶臉部信息
班級創建完成,但是目前班級中沒有成員,需要我們手動添加學生的臉部信息
(1)點擊剛剛創建好的class1的用戶組,進入到用戶組里面添加用戶。
(2)、點擊新建用戶。填入用戶的名字(拼音或者英文名字,暫不支持中文),然后選擇一張該用戶(學生)的照片上傳到用戶組中,如下所示:
(3)、多次循環操作,便為班級添加好了學生,學長只添加了自己的,因此列表只有一項。
這樣,我們班級一的人臉數據庫便創建成功,下面便可以通過API接口進行對應代碼的編寫了!
3、人臉搜索API請求文檔說明
在編寫相關人臉識別的代碼之前,我們首先需要了解如何訪問百度AI開放平臺中人臉識別模塊中的人臉搜索功能。官方給了對于的API文檔說明,鏈接如下:
人臉搜索API官方請求文檔說明
在API文檔中,我們首先得找請求說明,該部分有請求代碼格式,以及請求參數說明,具體如下步驟。
(1)、請求格式標準代碼Python
import requests
'''
人臉搜索
'''
request_url
= "https://aip.baidubce.com/rest/2.0/face/v3/search"
params
= "{\"image\":\"027d8308a2ec665acb1bdf63e513bcb9\",\"image_type\":\"FACE_TOKEN\",\"group_id_list\":\"group_repeat,group_233\",\"quality_control\":\"LOW\",\"liveness_control\":\"NORMAL\"}"
access_token
= '[調用鑒權接口獲取的token]'
request_url
= request_url
+ "?access_token=" + access_token
headers
= {'content-type': 'application/json'}
response
= requests
.post
(request_url
, data
=params
, headers
=headers
)
if response
:print (response
.json
())
(2)請求參數說明
- image:需要進行人臉識別的圖像。
- image_type:圖像的格式,這里的格式我們上次博客設置的base64,因此本次的格式依舊如此。
- FACE_TOKEN:調用鑒權接口獲取的token,通過AK和SK獲取的token
- group_id_list:需要在那個用戶組列表中進行人臉識別對比
重要的是以上四個,后面的參數請通過API官方文檔自行了解,下面給出后面參數的解釋截圖:
4、人臉搜索API返回參數說明
有訪問參數,在訪問成功后,進行人臉識別,我們需要的便是識別之后的信息,因此讀懂API的返回參數是項目中非常重要的技能。百度AI人臉識別項目中,需要根據返回參數進行對應的信息接收、處理和顯示。人臉搜索API文檔中,請參考返回說明章節。
(1)、返回參數介紹
(2)返回參數示例
在經過以上第一大步驟的進行之后,便可以開始我們接下來的代碼編寫了,在我們的《百度AI人臉識別與檢測》項目中,通過以上了解的到的相關知識,完成人臉識別模塊的功能。請繼續往下面看!
二、完成系統人臉識別功能模塊
1、定義人臉識別數據接收和發送信號
在人臉識別完成之后,我們首先需要處理的便是人臉識別信息數據,將這些數據送到PyQT對于功能的控件上顯示。但前面的代碼我們了解到,在進行人臉檢測是在子線程中,而數據的顯示是在主線程中的窗口上面,因此,首先我們需要定義一個變量,用該變量存儲人臉識別信息,并將子線程中得到的變量傳遞到主線程。而pyqt5中通過pyqtSignal信號接口實現了子線程與主線程之間的變量傳遞。
(1)、在detect.py文件中,定義transmit_data1信號,用于子線程與主線程中的人臉識別數據交互,信號類型為字符串型。
transmit_data1
= pyqtSignal
(str)
(2)、代碼添加位置如下:
2、編寫人臉搜索訪問方法
(1)通過人臉搜索API文檔規則,在detect.py文件尾部編寫訪問方法,代碼如下所示:
def face_search(self
):request_url
= "https://aip.baidubce.com/rest/2.0/face/v3/search"params
= {"image": self
.imageData
,"image_type": "BASE64","group_id_list": "class1",}access_token
= self
.access_tokenrequest_url
= request_url
+ "?access_token=" + access_tokenheaders
= {'content-type': 'application/json'}response
= requests
.post
(request_url
, data
=params
, headers
=headers
)if response
:data
= response
.json
()if data
['error_msg'] == 'SUCCESS':if data
['result']['user_list'][0]['score'] > 90: del [data
['result']['user_list'][0]['score']]datetime
= QDateTime
.currentDateTime
()datetime
= datetime
.toString
()data
['result']['user_list'][0]['datetime'] = datetimelist1
= [data
['result']['user_list'][0]['user_id'],data
['result']['user_list'][0]['group_id']]self
.transmit_data1
.emit
("學生簽到成功\n學生信息如下:\n" + "姓名:" + list1
[0] + "\n" + "班級:" + list1
[1])
- image:通過人臉檢測傳遞過來的圖像
- image_type:圖像格式為base64
- group_id_list:上面我們創建的class1用戶組
3、調用函數,進行人臉識別
(1)人臉識別的基礎是在人臉檢測的基礎上進行的,在人臉檢測到之后,方可進行人臉識別,因此,在detect.py文件中的人臉檢測函數中進行人臉識別方法的調用。
self
.face_search
()
(2)、代碼添加位置如下:
(3)detect.py文件中的代碼便修改完成,修改后的代碼如下所示:
import requests
from PyQt5
.QtCore
import QThread
, pyqtSignal
, QDateTime
class detect_thread(QThread
):transmit_data
= pyqtSignal
(dict)transmit_data1
= pyqtSignal
(str) def __init__(self
,access_token
):super(detect_thread
,self
).__init__
()self
.ok
=Trueself
.condition
= Falseself
.access_token
=access_token
def run(self
):while self
.ok
==True:if self
.condition
==True:self
.detect_face
(self
.imageData
)self
.condition
=False'''接收主線程傳遞過來的圖像'''def get_imgdata(self
,data
):self
.imageData
=dataself
.condition
=True'''人臉檢測'''def detect_face(self
,base64_image
):request_url
= "https://aip.baidubce.com/rest/2.0/face/v3/detect"params
= {"image": base64_image
, "image_type": "BASE64", "face_field": "gender,age,beauty,mask,emotion,expression,glasses,face_shape", "max_face_num": 10}access_token
= self
.access_tokenrequest_url
= request_url
+ "?access_token=" + access_tokenheaders
= {'content-type': 'application/json'}response
= requests
.post
(request_url
, data
=params
, headers
=headers
)if response
:data
= response
.json
()self
.face_search
()self
.transmit_data
.emit
(dict(data
))def face_search(self
):request_url
= "https://aip.baidubce.com/rest/2.0/face/v3/search"params
= {"image": self
.imageData
,"image_type": "BASE64","group_id_list": "class1",}access_token
= self
.access_tokenrequest_url
= request_url
+ "?access_token=" + access_tokenheaders
= {'content-type': 'application/json'}response
= requests
.post
(request_url
, data
=params
, headers
=headers
)if response
:data
= response
.json
()if data
['error_msg'] == 'SUCCESS':if data
['result']['user_list'][0]['score'] > 90: del [data
['result']['user_list'][0]['score']]datetime
= QDateTime
.currentDateTime
()datetime
= datetime
.toString
()data
['result']['user_list'][0]['datetime'] = datetimelist1
= [data
['result']['user_list'][0]['user_id'],data
['result']['user_list'][0]['group_id']]self
.transmit_data1
.emit
("學生簽到成功\n學生信息如下:\n" + "姓名:" + list1
[0] + "\n" + "班級:" + list1
[1])
下面就需要在主線程中進行數據接收顯示了!
4、主線程人臉識別數據接收顯示
(1)、在function_window.py文件末尾添加顯示信息方法
def get_seach_data(self
,data
):self
.plainTextEdit
.setPlainText
(data
)
(2)、在function_window.py文件中綁定子線程中信號接收
self
.detect
.transmit_data1
.connect
(self
.get_seach_data
)
添加位置如下圖:
到這里,人臉識別模塊基本完成,function_window.py文件也修改完成。
(3)function_window.py文件修改后的代碼內容如下所示:
import base64
import cv2
import requests
from PyQt5
.QtCore
import QTimer
from PyQt5
.QtGui
import QPixmap
from PyQt5
.QtWidgets
import QMainWindow
, QMessageBox
from cameraVideo
import camera
from mainWindow
import Ui_MainWindow
from detect
import detect_thread
class function_window(Ui_MainWindow
,QMainWindow
):'''初始化函數'''def __init__(self
):super(function_window
, self
).__init__
()self
.setupUi
(self
)self
.label
.setScaledContents
(True)self
.pushButton
.clicked
.connect
(self
.open_Sign
)self
.pushButton_2
.clicked
.connect
(self
.close_Sign
)self
.access_token
=self
.get_accessToken
()self
.start_state
=True'''打開簽到'''def open_Sign(self
):if self
.start_state
==True:self
.cameravideo
= camera
()self
.timeshow
= QTimer
(self
)self
.timeshow
.start
(10)self
.timeshow
.timeout
.connect
(self
.show_cameradata
)self
.detect
= detect_thread
(self
.access_token
) self
.detect
.start
() self
.faceshow
= QTimer
(self
)self
.faceshow
.start
(500)self
.faceshow
.timeout
.connect
(self
.get_cameradata
)self
.detect
.transmit_data
.connect
(self
.get_data
)self
.detect
.transmit_data1
.connect
(self
.get_seach_data
)self
.start_state
=Falseelse:QMessageBox
.about
(self
, "提示", "正在檢測,請先關閉!")'''關閉簽到'''def close_Sign(self
):if self
.start_state
==False:self
.faceshow
.stop
() self
.detect
.ok
= False self
.detect
.quit
() self
.timeshow
.stop
()self
.timeshow
.timeout
.disconnect
(self
.show_cameradata
)self
.cameravideo
.colse_camera
()self
.start_state
=Trueif self
.timeshow
.isActive
() == False:self
.label
.setPixmap
(QPixmap
("image/1.jpg"))self
.plainTextEdit_2
.clear
()else:QMessageBox
.about
(self
, "警告", "關閉失敗,存在部分沒有關閉成功!")else:QMessageBox
.about
(self
, "提示", "請先開始檢測!")def get_data(self
,data
):if data
['error_code']!=0:self
.plainTextEdit_2
.setPlainText
(data
['error_msg'])returnelif data
['error_msg'] == 'SUCCESS':self
.plainTextEdit_2
.clear
()face_num
= data
['result']['face_num']if face_num
== 0:self
.plainTextEdit_2
.setPlainText
("當前沒有人或人臉出現!")returnelse:self
.plainTextEdit_2
.clear
()self
.plainTextEdit_2
.appendPlainText
("檢測到人臉!")self
.plainTextEdit_2
.appendPlainText
("——————————————")for i
in range(face_num
):age
= data
['result']['face_list'][i
]['age'] beauty
= data
['result']['face_list'][i
]['beauty'] gender
= data
['result']['face_list'][i
]['gender']['type'] expression
= data
['result']['face_list'][i
]['expression']['type']face_shape
= data
['result']['face_list'][i
]['face_shape']['type'] glasses
= data
['result']['face_list'][i
]['glasses']['type'] emotion
= data
['result']['face_list'][i
]['emotion']['type'] mask
= data
['result']['face_list'][i
]['mask']['type'] self
.plainTextEdit_2
.appendPlainText
("第" + str(i
+ 1) + "個學生人臉信息:")self
.plainTextEdit_2
.appendPlainText
("——————————————")self
.plainTextEdit_2
.appendPlainText
("年齡:" + str(age
))if gender
== 'male':gender
= "男"else:gender
= "女"self
.plainTextEdit_2
.appendPlainText
("性別:" + str(gender
))self
.plainTextEdit_2
.appendPlainText
("表情:" + str(expression
))self
.plainTextEdit_2
.appendPlainText
("顏值分數:" + str(beauty
))self
.plainTextEdit_2
.appendPlainText
("臉型:" + str(face_shape
))self
.plainTextEdit_2
.appendPlainText
("情緒:" + str(emotion
))if glasses
== "none":glasses
="否"elif glasses
== "common":glasses
="是:普通眼鏡"else:glasses
="是:太陽鏡"self
.plainTextEdit_2
.appendPlainText
("是否佩戴眼鏡:" + str(glasses
))if mask
== 0:mask
= "否"else:mask
= "是"self
.plainTextEdit_2
.appendPlainText
("是否佩戴口罩:" + str(mask
))self
.plainTextEdit_2
.appendPlainText
("——————————————")else:print("人臉獲取失敗!")'''獲取圖像,并轉換為base64格式'''def get_cameradata(self
):camera_data1
= self
.cameravideo
.read_camera
()_
, enc
= cv2
.imencode
('.jpg', camera_data1
)base64_image
= base64
.b64encode
(enc
.tobytes
())self
.detect
.get_imgdata
(base64_image
)'''攝像頭數據顯示'''def show_cameradata(self
):pic
=self
.cameravideo
.camera_to_pic
()self
.label
.setPixmap
(pic
)'''獲取Access_token訪問令牌'''def get_accessToken(self
):host
= 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=TKGXdKC7WPWeADGHmFBN8xAr&client_secret=lsr1tAuxv3tRGmOgZTGgNyri667dfKGg'response
= requests
.get
(host
)if response
:data
= response
.json
()self
.access_token
= data
['access_token']return self
.access_token
else:QMessageBox
(self
,"提示","請檢查網絡連接!")def get_seach_data(self
,data
):self
.plainTextEdit
.setPlainText
(data
)
5、人臉識別運行結果測試
(1)運行程序,打開簽到
(2)開始簽到
可以看到,簽到的數據顯示到對應的信息框中,簽到成功!
(3)關閉簽到
以上就是本次博客的全部內容,遇到問題的小伙伴記得留言評論,學長看到會為大家進行解答的,這個學長不太冷!
沒有人永遠青春,但永遠有人正青春;只是,林君學長的青春暫告一段路而已!
陳一月的又一天編程歲月^ _ ^
總結
以上是生活随笔為你收集整理的百度AI人脸识别与检测五:学生人脸识别打卡签到系统之百度AI人脸识别的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。