Qt 下的虹軟人臉識別SDK使用介紹
本文主要會對虹軟人臉識別SDK在 Qt 平臺下的使用過程做簡要介紹,其中包含材料準備、環境搭建、程式碼實現三個主要步驟,幫助我們有過程上的參考。
開發環境 : win10 Qt5.11.2(Mingw 32位)
1. 材料準備
1.1. 人臉識別SDK(ArcSoft_ArcFace)下載。
虹軟對外有免費的AI開發平臺,包括人臉識別SDK、活體檢測SDK、人證核驗SDK,這裡我們使用的是人臉檢測SDK,詳細可以登陸虹軟官網進行具體功能查閱。
登陸http://ai.arcsoft.com.cn/product/arcface.html 進行註冊後下載ArcSoft_ArcFace 2.0版本。 需要注意的是,*下載SDK的版本要與qt編譯器版本一致*。這裡選擇下載 windous(x86)版本。
下載完成後,首先閱讀 releasenotes.txt -> ARCSOFT_ARC_FACE_DEVELOPER'S_GUIDE.pdf。
2.2. openCV 下載。
這裡我們直接下載編譯好的 OpenCV(x86 MinGW 版)https://github.com/huihut/Ope...。
下載完成後,首先閱讀 README.md。
2. 環境搭建
2.1 新建Qt工程
在 .pro 檔案裡面新增OpenCV相關庫: win32 { INCLUDEPATH += D:\OpenCV-MinGW-Build-OpenCV-3.3.1\include\ INCLUDEPATH += D:\OpenCV-MinGW-Build-OpenCV-3.3.1\include\opencv INCLUDEPATH += D:\OpenCV-MinGW-Build-OpenCV-3.3.1\include\opencv2 LIBS += D:\OpenCV-MinGW-Build-OpenCV-3.3.1\bin\libopencv_*.dll } 開啟 Qt 工程,新增ArcSoft_ArcFace相關庫: a 滑鼠右鍵,新增庫,外部庫; b 平臺選中 windows,連結選中 動態,其它不做勾選; c 庫檔案指下載好的 ArcSoft_ArcFace 的lib、dll 檔案; d 包含路徑指下載好的 ArcSoft_ArcFace 庫相關的標頭檔案;
c 滑鼠右鍵,新增現有檔案,把 ArcSoft_ArcFace 庫相關的標頭檔案新增到工程中。
HEADERS += \
ArcSoft_ArcFace/inc/amcomdef.h \
ArcSoft_ArcFace/inc/arcsoft_face_sdk.h \
ArcSoft_ArcFace/inc/asvloffscreen.h \
ArcSoft_ArcFace/inc/merror.h
2.2 複製執行相關 dll 檔案
將ArcSoft_ArcFace 與 OpenCV 相關的 dll 檔案複製到工程生成的應用程式資料夾。如果沒有新增完整,生成的應用程式執行時,將提示“由於找不到 xxx_.dll,無法繼續執行程式碼。重新安裝程式可能會解決此問題”或者“應用程式無法正常啟動0xc000007b”等問題。
3. 程式碼實現
3.1 UI介面實現。
a 使用 Axure 畫介面原型圖,元件採用絕對定位方式。
void Wigdet::initUI()
{
m_photoBox.setParent(this);
m_photoBox.move(8, 7);
m_photoBox.resize(422, 278);
m_idCardBox.setParent(this);
m_idCardBox.move(440, 7);
m_idCardBox.resize(276, 154);
m_valLab.setParent(this);
m_valLab.move(482, 171);
m_valLab.resize(33, 16);
m_valLab.setText("閾 值:");
m_valSpinBox.setParent(this);
m_valSpinBox.move(544, 166);
m_valSpinBox.resize(159, 24);
m_valSpinBox.setSingleStep(0.01);
m_valSpinBox.setMinimum(0.01);
m_valSpinBox.setMaximum(1.00);
m_valSpinBox.setValue(0.82);
m_loadPhotoBtn.setParent(this);
m_loadPhotoBtn.move(454, 197);
m_loadPhotoBtn.resize(249, 24);
m_loadPhotoBtn.setText("影象匯入");
m_loadIdCardBtn.setParent(this);
m_loadIdCardBtn.move(454, 228);
m_loadIdCardBtn.resize(249, 24);
m_loadIdCardBtn.setText("ID卡匯入");
m_compareBtn.setParent(this);
m_compareBtn.move(454, 257);
m_compareBtn.resize(249, 24);
m_compareBtn.setText("面部識別");
setWindowIcon(QIcon(":/pic/pic/icon.png"));
setWindowTitle("AI Changes life [ [email protected] -- TianSong ]");
setFixedSize(726, 295);
}
b 關鍵的槽函式
void Wigdet::initSLot()
{
connect(&m_loadPhotoBtn, SIGNAL(clicked()), this, SLOT(onLoadPhotoBtnClicked()));
connect(&m_loadIdCardBtn, SIGNAL(clicked()), this, SLOT(onLoadIdCardBtnClicked()));
connect(&m_compareBtn, SIGNAL(clicked()), this, SLOT(onCompareBtnClicked()));
}
void Wigdet::onLoadPhotoBtnClicked();
void Wigdet::onLoadIdCardBtnClicked();
void Wigdet::onCompareBtnClicked();
c 重寫 painEvent 事件函式
void Wigdet::paintEvent(QPaintEvent*);
d 人臉識別處理 (查閱幫助文件與示例程式碼)
#define APPID "申請的APPID" //APPID
#define SDKKey "申請的SDKKey" //SDKKey
#define MERR_ASF_BASE_ALREADY_ACTIVATED (0x16002)
bool Wigdet::doCompare(Imag& img_photo, Imag& img_idcard, float val)
{
bool pResult = false;
/** 1. 啟用SDK */
MRESULT res = ASFActivation(const_cast<char*>(APPID), const_cast<char*>(SDKKey));
if (MOK == res || MERR_ASF_BASE_ALREADY_ACTIVATED == res)
{
qDebug() << "ALActivation sucess: " << res;
}
else
{
qDebug() << "ALActivation fail: " << res;
}
/** 2. 初始化引擎 */
MHandle handle = NULL;
MInt32 mask = ASF_FACE_DETECT | ASF_FACERECOGNITION | ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE;
res = ASFInitEngine(static_cast<MInt32>(ASF_DETECT_MODE_IMAGE), ASF_OP_0_ONLY, 16, 5, mask, &handle);
if (res == MOK)
{
qDebug() << "ALInitEngine sucess: " << res;
}
else
{
qDebug() << "ALInitEngine fail: " << res;
}
/** 3. 人臉檢測 */
img_photo.img.scaled(img_photo.img.width()/4*4, img_photo.img.height()/4*4).save("img1.png");
img_idcard.img.scaled(img_idcard.img.width()/4*4, img_idcard.img.height()/4*4).save("img2.png");
IplImage* img1 = cvLoadImage("img1.png");
IplImage* img2 = cvLoadImage("img2.png");
if (img1 && img2)
{
/** 3.1 第一張人臉特徵提取 */
ASF_MultiFaceInfo detectedFaces1 = { 0 };
ASF_SingleFaceInfo SingleDetectedFaces1 = { 0 };
ASF_FaceFeature feature1 = { 0 };
ASF_FaceFeature copyfeature1 = { 0 };
res = ASFDetectFaces(handle, img1->width, img1->height, ASVL_PAF_RGB24_B8G8R8, (MUInt8*)img1->imageData, &detectedFaces1);
if (MOK == res)
{
SingleDetectedFaces1.faceRect.left = detectedFaces1.faceRect[0].left;
SingleDetectedFaces1.faceRect.top = detectedFaces1.faceRect[0].top;
SingleDetectedFaces1.faceRect.right = detectedFaces1.faceRect[0].right;
SingleDetectedFaces1.faceRect.bottom = detectedFaces1.faceRect[0].bottom;
SingleDetectedFaces1.faceOrient = 0x05;
qDebug() << detectedFaces1.faceNum;
res = ASFFaceFeatureExtract(handle, img1->width, img1->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast<MUInt8*>(img1->imageData), &SingleDetectedFaces1, &feature1);
if (res == MOK)
{
/** 3.1.1 拷貝feature */
copyfeature1.featureSize = feature1.featureSize;
copyfeature1.feature = reinterpret_cast<MByte*>(malloc(static_cast<size_t>(feature1.featureSize)));
memset(copyfeature1.feature, 0, static_cast<size_t>(feature1.featureSize));
memcpy(copyfeature1.feature, feature1.feature, static_cast<size_t>(feature1.featureSize));
int x = SingleDetectedFaces1.faceRect.left;
int y = SingleDetectedFaces1.faceRect.top;
int w = SingleDetectedFaces1.faceRect.right - SingleDetectedFaces1.faceRect.left;
int h = SingleDetectedFaces1.faceRect.bottom - SingleDetectedFaces1.faceRect.top;
img_photo.rect = QRect(x, y, w, h);
/** 3.1.2 人臉資訊檢測 */
MInt32 processMask = ASF_AGE | ASF_GENDER;
res = ASFProcess(handle, img1->width, img1->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast<MUInt8*>(img1->imageData), &detectedFaces1, processMask);
if (res == MOK)
{
qDebug() << "ASFProcess sucess: " << res;
}
else
{
qDebug() << "ASFProcess fail: " << res;
}
/** 3.1.3 獲取年齡 */
ASF_AgeInfo ageInfo = { 0 };
res = ASFGetAge(handle, &ageInfo);
if (res == MOK)
{
img_photo.age = ageInfo.ageArray[0];
qDebug() << ageInfo.ageArray[0];
qDebug() << "ASFGetAge sucess: " << res;
}
else
{
qDebug() << "ASFGetAge fail: " << res;
}
/** 3.1.4 獲取性別 */
ASF_GenderInfo genderInfo = { 0 };
res = ASFGetGender(handle, &genderInfo);
if (res == MOK)
{
img_photo.gender = genderInfo.genderArray[0];
qDebug() << genderInfo.genderArray[0];
qDebug() << "ASFGetGender sucess: " << res;
}
else
{
qDebug() << "ASFGetGender fail: " << res;
}
qDebug() << "ASFFaceFeatureExtract 1 Success";
}
else
{
qDebug() << "ASFFaceFeatureExtract 1 fail: " << res;
}
}
else
{
qDebug() << "ASFDetectFaces 1 fail: " << res;
}
/** 3.2 第二張人臉特徵提取 */
ASF_MultiFaceInfo detectedFaces2 = { 0 };
ASF_SingleFaceInfo SingleDetectedFaces2 = { 0 };
ASF_FaceFeature feature2 = { 0 };
res = ASFDetectFaces(handle, img2->width, img2->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast<MUInt8*>(img2->imageData), &detectedFaces2);
if (MOK == res)
{
SingleDetectedFaces2.faceRect.left = detectedFaces2.faceRect[0].left;
SingleDetectedFaces2.faceRect.top = detectedFaces2.faceRect[0].top;
SingleDetectedFaces2.faceRect.right = detectedFaces2.faceRect[0].right;
SingleDetectedFaces2.faceRect.bottom = detectedFaces2.faceRect[0].bottom;
SingleDetectedFaces2.faceOrient = detectedFaces2.faceOrient[0];
res = ASFFaceFeatureExtract(handle, img2->width, img2->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast<MUInt8*>(img2->imageData), &SingleDetectedFaces2, &feature2);
if (res == MOK)
{
int x = SingleDetectedFaces2.faceRect.left;
int y = SingleDetectedFaces2.faceRect.top;
int w = SingleDetectedFaces2.faceRect.right - SingleDetectedFaces2.faceRect.left;
int h = SingleDetectedFaces2.faceRect.bottom - SingleDetectedFaces2.faceRect.top;
img_idcard.rect = QRect(x, y, w, h);
qDebug() << "ASFFaceFeatureExtract 2 Success";
}
else
{
qDebug() << "ASFFaceFeatureExtract 2 fail: " << res;
}
}
else
{
qDebug() << "ASFDetectFaces 2 fail: " << res;
}
/** 3.3 單人臉特徵比對 */
MFloat confidenceLevel;
res = ASFFaceFeatureCompare(handle, ©feature1, &feature2, &confidenceLevel);
if (res == MOK)
{
qDebug() << "ASFFaceFeatureCompare sucess: " << confidenceLevel;
if( confidenceLevel >= val ) pResult = true;
}
else
{
qDebug() << "ASFFaceFeatureCompare fail: " << res;
}
}
/** 4. 反初始化 */
res = ASFUninitEngine(handle);
if (res != MOK)
{
qDebug() << "ALUninitEngine fail: " << res;
}
else
{
qDebug() << "ALUninitEngine sucess: " << res;
}
return pResult;
}
以上步驟完成後,就可以正常的編譯運行了。
(因篇幅的限制,部分函式實現沒有展開,可以根據文章末尾連結到github 中下載檢視)
4. 注意的地方
ArcSoft_ArcFace_S 版本與 Qt 編譯器一致 x64 或者 x86
opencv 版本與 Qt 編譯器一致 x64 或者 x86.
相關推薦
Qt 下的虹軟人臉識別SDK使用介紹
本文主要會對虹軟人臉識別SDK在 Qt 平臺下的使用過程做簡要介紹,其中包含材料準備、環境搭建、程式碼實現三個主要步驟,幫助我們有過程上的參考。 開發環境 : win10 Qt5.11.2(Mingw 32位) 1. 材料準備 1.1. 人臉識別SDK(ArcS
Android虹軟人臉識別sdk使用工具類
public class FaceUtil { private static final String TAG = Fac
關於虹軟人臉識別SDK的接入
背景: 虹軟的人臉識別還是不錯的,在官方註冊一個賬號,成為開發者,下載SDK的jar包,在開發者中心,找一個demo就可以開始做了
虹軟人臉識別SDK在網路攝像頭中的實際應用
市面上目前有很多款網路攝像頭,以海康攝像頭為例。海康SDK包含很多介面,接入有一定難度,這裡只介紹獲取視訊幀相關的介面。 1.海康SDK接入基本流程 a.初始化並登入驗證 NET_DVR_Init(); NET_DVR_DEVICEINFO
虹軟人臉識別 - faceId及IR活體檢測的介紹
虹軟人臉識別 - faceId及IR活體檢測的介紹 前幾天虹軟推出了 Android ArcFace 2.2版本的SDK,相比於2.1版本,2.2版本中的變化如下: VIDEO模式新增faceId(類似於之前文章中提到的trackId) 新增IR活體檢測功能 新增IR、RGB的活體閾值設定
虹軟人臉識別——官方 Qt Demo 移植到 Linux
## 一、前言 最近需要在 Linux 平臺下開發一個人臉識別相關的應用,用到了虹軟的人臉識別 SDK。之前在 Windows 平臺用過,感覺不錯,SDK 裡面還帶了 Demo 可以快速看到效果。開啟 Linux 版本的 SDK 裡面沒有發現 Demo,於是想著把 Windows 的 Demo 移植到 Li
虹軟人臉識別速度測試征集
width cso 線程數 比對 場景 最快 xtra 1-1 PE 場景是一張有10張臉的圖片(下圖),在包含1萬張人臉的庫(準備了100張人臉的特征文件,循環100次當做1萬個樣本)裏面進行比對。想得出在不同cpu的情況下,多少線程數是最快的?要多少時間(包括:總體、圖
虹軟人臉識別iOS SDK2.0
最近公司要在APP上新增一個人臉識別功能,在網上搜了一圈,發現虹軟的人臉識別SDK挺好用的,而且還免費,所以就下載了他們的SDK研究了一下。總的來看功能挺好用的,只是demo上面部分功能不是很完善,所以就在官方demo的基礎上改動了一些小的功能。 新增功能:1. 通過圖片註冊人臉2. 增加列表頁面可以檢視和
OC-虹軟人臉識別使用
1.匯入檔案中FaceID壓縮包中的內容到專案中。(去github下載也可以) 2.在虹軟官網建立專案並下載該專案對應的SDK,然後匯入專案中。 3.將官網上該專案的各種key值填到AFVideoProcessor.m對應的位置 4.Target->g
虹軟人臉識別在 linux中so檔案載入不到的問題
其實是可以載入到的,不過是so檔案放的位置不一對,最簡單的方式是放在 /usr/lib64 目錄下,也可自己設定。 so檔案載入不到會報這個錯誤:
虹軟人臉識別AndroidDEMO學習總結,利用SurfaceView預覽,以及相機呼叫的一些坑
第一篇部落格獻給了虹軟人臉識別,寫的不好歡迎指正。這幾天,接到需求要加上人臉識別的功能,抱著面向百度程式設計的心態,我果然搜到了虹軟人臉識別API。閱讀開發文件,研究DEMO實現流程,經過這幾天的鬥爭,終於搞了一個適合需求的DEMO出來。將這幾天的成果總結一下,有需要的朋友可
android自定義虹軟人臉識別框/人臉抓拍框/人臉追蹤框
有一兩個月沒有更新部落格了,最近一直在忙人臉識別的專案,先將專案中更改虹軟人臉框的方法抽取出來,希望對大家有所幫助。 為什麼要改? 先來看看sdk demo中提供的人臉框樣式,這個框看上去並不是非常美觀(個人覺得) 再看看下面這個框是不是就要順眼一點 怎麼
C# 虹軟人臉識別SDK2.0版實例
mod x86 res element handle aac uid resize tid 虹軟SDK推出了2.0版本,這個版本的所有API都集合在一個動態庫裏面,再通過引擎庫調用,比1.2版本相對輕便了很多。 了解詳情戳這裏 小西瓜也迫不及待弄了一個新版本的C#實例,
虹軟人臉識別的應用開發過程分享
虹軟的人臉識別是應用與離線開發的,因為不需要網路,所以它的識別速度較快。 好了,廢話不多說,接下來就開始教大家怎樣使用了。 1.首
【分享】虹軟人臉識別應用開發過程
趁晚上的時間向大家分享一波乾貨。 虹軟的人臉識別是應用與離線開發的,因為不需要網路,所以它的識別速度較快。好了,廢話不多說,接下來
基於虹軟人臉識別API和Qt5的人臉識別
測試和使用了虹軟的人臉API在QT5環境下設計了一個簡單的人臉識別軟體,實現了對人臉的跟蹤和人臉識別。攝像頭的控制以及影象格式的轉
虹軟人臉識別—版本升級介面修改說明(C#)
自虹軟釋出了免費、離線版本人臉識別SDK,在Github上陸續分享了各個版本對應的 C# Demo。因為公司專案一直在使用虹軟的SDK,因此每當虹軟官網有新版本釋出,我都會進行了解,並結合Demo進行功能驗證。在虹軟官方群裡及論壇上,看到有朋友反饋**升級SDK**後出現如下問題: 1\. **替換SDK檔
基於虹軟人臉識別,實現身份認證和自助髮卡
去年下半年開始從BS開發轉戰CS開發了,相繼做了一些大大小小的專案。最近在做的一個人臉識別挺有意思,作為一個初學者我也是摸著石頭過河。這個專案主要是通過攝像頭捕獲的人臉特徵與身份證資訊中的人臉照片進行比對,比對通過的話,可以通過髮卡機寫入資訊至卡片並吐出這張卡片,使用者拿著這張卡片進行後續操作。對於髮卡機
虹軟免費人臉識別SDK註冊指南
開發者 管理 內容 單元 其他 疑問 登錄 ESS 標識 成為開發者三步完成賬號的基本註冊與認證:STEP1:點擊註冊虹軟AI開放平臺右上角註冊選項,完成註冊流程。STEP2:首次使用,登錄後進入開發者中心,點擊賬號管理完成企業或者個人認證,若未進行實名認證,部分功能將受
Android 虹軟免費人臉識別 SDK開發
一次 tst 足夠 到手 柵格 roi sta 開發 true 目前我們的應用內使用了 ArcFace 的人臉檢測功能,其他的我們並不了解,所以這裏就和大家分享一下我們的集成過程和一些使用心得集成ArcFace FD 的集成過程非常簡單在 ArcFace FD 的文檔上有說