1. 項目介紹
近幾年,生物特征識别技術獲得快速發展。人臉作為一種生物特征,具有很強的自身穩定性和個體差異性,是進行身份驗證的最理想依據,主要方法包括步态識别、虹膜識别、皮膚晶片、臉像識别、多模态(即多生物特征融合)技術等。其中,人臉識别技術因為具有友善、直覺、易于普及等優點尤為受到關注與研究。
文章針對目前常用考勤方式中普遍存在的代簽到、考勤資料整合較慢等問題,利用華為雲的人臉識别技術實作了一種基于QT架構設計的線上考勤系統。該系統可大大提聯考勤效率,滿足各類場環境景下的考勤需求,具有識别度高、檢測速度快、操作簡單的特點,能夠為使用者提供更多便利幫助。
實作大緻流程:
- 注冊華為雲賬号
- 開通華為雲的人臉識别服務
- 通過API建立人臉庫
- 将需要考勤識别的人臉,添加到人臉庫
- 考勤時,調用本地攝像頭擷取人臉圖像,與人臉庫裡注冊的人臉進行對比,找到考勤人,完成考勤。
核心思路總結:
華為雲人臉識别服務支援,人臉庫建立,向人臉庫添加人臉,在人臉庫裡搜尋比對的人臉,.......很多功能。目前
考勤系統主要用到這3個功能。
建立人臉庫: 在建立人臉庫的時候,支援建立自定義字段,也就是每個人臉可以加一些自定義的屬性描述,但是不支援中文字元,如果是字元串字段,範圍是0~255長度;
向人臉庫添加人臉: 如果在建立人臉庫的時候,注冊了自定義字段,在添加人臉的時候就可以帶上自定義字段的描述,除了添加自定義字段,也可以添加ID,這個ID關聯資料庫友善考勤的時候進行查找對比。
在人臉庫搜尋人臉: 可以取一張本地的圖檔與人臉庫裡存在的人臉進行比對,得到相識度,在搜尋人臉的時候也可以設定過濾條件,常見的條件就是相識度閥值,低于設定閥值就不傳回,也可以設定自定義字段傳回,如果注冊人臉的時候添加了自定義屬性,在識别到人臉的時候就可以通過傳回的自定義屬性判斷這個人臉是誰。
考勤實作核心思路:
向人臉庫添加人臉的時候,可以指定
external_image_id
字段,這個是代表圖檔外部ID,與目前圖像綁定,這個字段可以存放在本地的資料庫裡,在考勤的時候,從目前攝像頭取一幀圖像與華為雲人臉庫裡的圖像進行對比,找到相識度最高的一張圖檔,然後這張圖檔的
external_image_id
字段,然後與資料庫裡的
external_image_id
字段比對,就找到這個人的詳細資訊了(詳細資訊是存放到本地資料庫裡的),然後就可以實作考勤邏輯了。
軟體最終的效果:
(1)主界面
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsQTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SNyYDM3UmMxcTZlJmNlZmMyYzXwEzNwkDM1EzLcNDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
(2)打開攝像頭
如果視訊裡沒有人臉,會有錯誤提示的。
(3)點選人臉注冊,添加工号自定義屬性
(4)點選人臉搜尋:搜尋到之後會把自定義的屬性顯示出來--工号
其他功能都不在示範了,詳細實作看下面章節的代碼流程。
項目源碼下載下傳位址: https://download.csdn.net/download/xiaolong1126626497/71245801
2. 建立人臉庫
2.1 開通人臉識别服務
官網位址: https://console.huaweicloud.com/frs/?region=cn-north-4&locale=zh-cn#/frs/manage/index
如果沒有華為雲賬号,打開上面位址時,需要先注冊,如果有賬号登入之後就可以看到下面的頁面,滑鼠移到最右邊,開通對應的服務。
2.2 建立人臉庫
官方幫助文檔位址: https://support.huaweicloud.com/api-face/face_02_0088.html
2.3 AK/SK、ID、域名參數擷取
在使用API通路接口時,需要填充很多的參數,
endpoint
,
project_id
等等。
關于這些API需要使用的簽名參數介紹在這個頁面裡:https://support.huaweicloud.com/devg-apisign/api-sign-provide-start.html
Endpoint 是代表地區與終端節點,即雲服務在不同Region有不同的通路域名。
檢視位址: https://developer.huaweicloud.com/endpoint
打開連結之後,選擇自己的服務,然後往下翻就可以看到對應服務的位址。
華北-北京四 cn-north-4 face.cn-north-4.myhuaweicloud.com HTTPS
擷取AK/SK
- 打開控制台頁面
- 将滑鼠移至使用者名,在下拉清單中單擊“我的憑證”。
- 單擊“通路密鑰”。
- 單擊“新增通路密鑰”,進入“新增通路密鑰”頁面。
- 輸入描述資訊,單擊“确定”,下載下傳密鑰,請妥善保管。
在API憑證頁面可以看到項目ID:
2.4 線上調試接口
華為雲提供了在調試API接口,非常友善,可以提前驗證功能是否正常。
位址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=FRS&api=CreateFaceSet
選擇自己要調試的API,然後填充對應的參考,進行調試即可。
下面的例子是建立人臉庫。
如果同一個人臉庫建立兩次,就會報錯,可以在調試頁面看到錯誤的提示,友善自己寫代碼時進行判斷,處理。
如果不清楚通路的域名位址是多少,在調試接口頁面是可以直接擷取檢視的。
建立人臉庫的時候,還可以指定自定義字段,友善對這張人臉進行打個性化标簽屬性,友善知道這張臉是誰的。
請求頭:
{
"User-Agent": "API Explorer",
"X-Auth-Token": "******",
"Content-Type": "application/json"
}
請求體:
{
"external_fields": {
"face_name": {
"type": "string"
},
"face_phone": {
"type": "string"
},
"face_class": {
"type": "string"
}
},
"face_set_name": "face3"
}
2.5 代碼實作
/*
功能: 建立人臉庫
*/
void Widget::HuaweiCreatesFaceDatabase(QString face_lib_name)
{
//表示建立人臉庫
function_select=2;
QString requestUrl;
QNetworkRequest request;
//設定請求位址
QUrl url;
//人臉注冊的請求位址
requestUrl = QString("https://face.%1.myhuaweicloud.com/v2/%2/face-sets")
.arg(SERVER_ID)
.arg(PROJECT_ID);
//自己建立的TCP伺服器,測試用
//requestUrl="http://10.0.0.6:8080";
//設定資料送出格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//設定token
request.setRawHeader("X-Auth-Token",Token);
//構造請求
url.setUrl(requestUrl);
request.setUrl(url);
//添加自定義字段 external_fields這個對象就是自定義字段
//我這裡隻是定義了3個字段,可以自己增加
//添加人臉的時候也需要添加這裡設定的自定義字段
QString post_param=QString("{"
"\"external_fields\": {"
"\"face_name\": {"
"\"type\": \"string\""
"},"
"\"face_phone\": {"
"\"type\": \"string\""
"},"
"\"face_class\": {"
"\"type\": \"string\""
"}"
"},"
"\"face_set_name\": \"%1\""
"}").arg(face_lib_name);
//發送請求
manager->post(request, post_param.toUtf8());
}
3. 如何擷取X-Subject-Token
使用API通路華為雲的所有服務接口,都需要填X-Subject-Token參數,下面介紹步驟:
3.1 建立一個新的IAM帳戶
滑鼠懸停在右上角的使用者名稱上,彈出下拉框,選擇統一身份認證。
3.2 選擇建立使用者
3.3 使用調試接口測試擷取oken
調試接口位址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IAM&api=KeystoneCreateUserTokenByPassword
右邊響應頭裡的
X-Subject-Token
就是擷取的token。
3.4 上面的這些賬戶名稱從哪裡擷取?
3.5 請求位址和資料格式
**擷取X-Subject-Token請求的位址:**https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens
請求頭資料:
{
"User-Agent": "API Explorer",
"X-Auth-Token": "******",
"Content-Type": "application/json;charset=UTF-8"
}
請求體資料:
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"domain": {
"name": "xxxxx" //這裡填目前主賬戶名稱
},
"name": "xxxx", //這個建立的子賬戶名稱
"password": "xxxxx" //這個是建立的子賬戶密碼
}
}
},
"scope": {
"project": {
"name": "cn-north-4"
}
}
}
}
3.5 代碼實作
/*
功能: 擷取token
*/
void Widget::GetToken()
{
//表示擷取token
function_select=3;
QString requestUrl;
QNetworkRequest request;
//設定請求位址
QUrl url;
//擷取token請求位址
requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")
.arg(SERVER_ID);
//自己建立的TCP伺服器,測試用
//requestUrl="http://10.0.0.6:8080";
//設定資料送出格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));
//構造請求
url.setUrl(requestUrl);
request.setUrl(url);
QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":"
"{\"user\":{\"domain\": {"
"\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}},"
"\"scope\":{\"project\":{\"name\":\"%4\"}}}}")
.arg(MAIN_USER)
.arg(IAM_USER)
.arg(IAM_PASSWORD)
.arg(SERVER_ID);
//發送請求
manager->post(request, text.toUtf8());
}
4. 向人臉庫添加人臉
4.1 調試接口
官方位址: https://support.huaweicloud.com/api-face/face_02_0093.html
添加人臉調試接口位址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=FRS&api=AddFacesByFile
4.2 請求接口與位址總結
請求位址: https://face.cn-north-4.myhuaweicloud.com/v2/項目ID/face-sets/人臉庫名稱/faces
請求方式: post
請求頭:
{
"User-Agent": "API Explorer",
"X-Auth-Token": "******", //替換成自己的token
"Content-Type": "application/json"
}
請求體:
{
"image_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAk..........."
}
4.3 查詢人臉
文檔位址: https://support.huaweicloud.com/api-face/face_02_0094.html
調試位址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=FRS&api=ShowFaceSet
4.4 代碼實作: 添加人臉時增加自定義字段
//注冊人臉,添加人臉,添加自定義資料
//QString name 這個是自定義字段,0~255 位元組,隻能英文字母和數字
void Widget::RegFace2(const QImage image,QString face_lib,QString name)
{
function_select=0;
QString requestUrl;
QNetworkRequest request;
//存放圖檔BASE64編碼
QString imgData;
//設定請求位址
QUrl url;
//人臉注冊的請求位址
requestUrl = QString("https://face.%1.myhuaweicloud.com/v2/%2/face-sets/%3/faces")
.arg(SERVER_ID)
.arg(PROJECT_ID)
.arg(face_lib);
qDebug()<<"requestUrl:"<<requestUrl;
// requestUrl="http://192.168.1.100:8080";
//設定資料送出格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//将圖檔進行Base64編碼
imgData = QString(toBase64(image)); //編碼後的圖檔大小不超過2M
//設定token
request.setRawHeader("X-Auth-Token",Token);
//構造請求
url.setUrl(requestUrl);
request.setUrl(url);
QString post_param=QString
("{"
"\"image_base64\": \"%1\","
"\"external_fields\":{\"face_name\":\"%2\"},"
"\"single\": true"
"}").arg(imgData).arg(name);
//發送請求
manager->post(request, post_param.toUtf8());
}
5. 從人臉庫搜尋比對的人臉
5.1 參數介紹
官方文檔位址: https://support.huaweicloud.com/api-face/face_02_0086.html
5.2 調試接口
接口位址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=FRS&api=SearchFaceByFile
我這裡調試接口裡選擇本地指定檔案與人臉庫的人臉進行比對,傳回相識度。
傳回的結果:
{
"faces": [
{
"face_id": "6ED4NSsS",
"external_image_id": "FPhviHgr",
"bounding_box": {
"width": 197,
"top_left_x": 201,
"top_left_y": 80,
"height": 241
},
"similarity": 1
},
{
"face_id": "EpBvdmp5",
"external_image_id": "ubxcVUpN",
"bounding_box": {
"width": 104,
"top_left_x": 111,
"top_left_y": 100,
"height": 123
},
"similarity": 0.9802261
},
{
"face_id": "cSKntQmF",
"external_image_id": "nBoRpVab",
"bounding_box": {
"width": 113,
"top_left_x": 65,
"top_left_y": 106,
"height": 127
},
"similarity": 0.97810614
},
{
"face_id": "TZGv2cKI",
"external_image_id": "49y0pLG9",
"bounding_box": {
"width": 104,
"top_left_x": 90,
"top_left_y": 97,
"height": 125
},
"similarity": 0.9768342
},
{
"face_id": "3p1Ho8Vw",
"external_image_id": "vpuYDUvU",
"bounding_box": {
"width": 108,
"top_left_x": 100,
"top_left_y": 108,
"height": 122
},
"similarity": 0.9619592
},
{
"face_id": "nIuMJ1fA",
"external_image_id": "v8mNyJSY",
"bounding_box": {
"width": 102,
"top_left_x": 58,
"top_left_y": 141,
"height": 98
},
"similarity": 0.95380914
},
{
"face_id": "IamCTWR9",
"external_image_id": "KzUyJDxU",
"bounding_box": {
"width": 108,
"top_left_x": 32,
"top_left_y": 142,
"height": 97
},
"similarity": 0.5663861
}
]
}
5.3 接口總結
這是總結的bas64編碼的接口,友善編寫代碼進行搜尋人臉。
請求位址: https://face.cn-north-4.myhuaweicloud.com/v2/項目ID/face-sets/人臉庫名稱/search
請求方式: POST
請求頭:
{
"User-Agent": "API Explorer",
"X-Auth-Token": "******", 自己的token
"Content-Type": "application/json"
}
請求體:
{
"image_base64": "..........................................." 圖檔BAS64編碼後的資料
}
5.4 代碼實作
//人臉搜尋功能
// threshold參數表示人臉相似度門檻值,低于這個門檻值則不傳回,取值範圍0~1,一般情況下建議取值0.93,預設為0。
void Widget::FindFace(const QImage image,QString face_lib,double threshold)
{
function_select=1;
QString requestUrl;
QNetworkRequest request;
//存放圖檔BASE64編碼
QString imgData;
//設定請求位址
QUrl url;
//人臉搜尋請求位址
requestUrl = QString("https://face.%1.myhuaweicloud.com/v2/%2/face-sets/%3/search")
.arg(SERVER_ID)
.arg(PROJECT_ID)
.arg(face_lib);
//設定資料送出格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//将圖檔進行Base64編碼
imgData = QString(toBase64(image)); //編碼後的圖檔大小不超過2M
//設定token
request.setRawHeader("X-Auth-Token",Token);
//構造請求
url.setUrl(requestUrl);
request.setUrl(url);
QString post_param=QString
("{"
"\"image_base64\": \"%1\","
"\"return_fields\":[\"face_name\"]," //需要傳回的自定義字段
"\"threshold\":%2"
"}").arg(imgData).arg(threshold);
//發送請求
manager->post(request, post_param.toUtf8());
}
6. 删除人臉庫
文檔位址: https://support.huaweicloud.com/api-face/face_02_0091.html
請求接口: https://face.cn-north-4.myhuaweicloud.com/v2/項目ID/face-sets/人臉庫名稱