1. 方案簡介
本方案為類人臉門禁機的產(chǎn)品級解決方案,已為用戶構(gòu)建一個帶調(diào)度框架的UI應(yīng)用工程;準備好我司的easyeai-api鏈接調(diào)用;準備好UI的開發(fā)環(huán)境。具備低模塊耦合度的特點。其目的在于方便用戶快速拓展自定義的業(yè)務(wù)功能模塊,以及快速更換UI皮膚。
2. 快速上手
2.1 開發(fā)環(huán)境準備
如果您初次閱讀此文檔,請閱讀《入門指南/開發(fā)環(huán)境準備/Easy-Eai編譯環(huán)境準備與更新》,并按照其相關(guān)的操作,進行編譯環(huán)境的部署。
在PC端Ubuntu系統(tǒng)中執(zhí)行run腳本,進入EASY-EAI編譯環(huán)境,具體如下所示。
cd ~/develop_environment ./run.sh
2.2 源碼下載以及實例編譯
在EASY-EAI編譯環(huán)境下創(chuàng)建存放源碼倉庫的管理目錄:
cd /opt mkdir EASY-EAI-Toolkit cd EASY-EAI-Toolkit
通過git工具,在管理目錄內(nèi)克隆遠程倉庫
git clone https://github.com/EASY-EAI/EASY-EAI-Toolkit-C-UiSolution.git
注:
* 此處可能會因網(wǎng)絡(luò)原因造成卡頓,請耐心等待。
* 如果實在要在gitHub網(wǎng)頁上下載,也要把整個倉庫下載下來,不能單獨下載本實例對應(yīng)的目錄。
進入到對應(yīng)的例程目錄執(zhí)行編譯操作,具體命令如下所示:
cd EASY-EAI-Toolkit-C-UiSolution/qSolu-facialGate/ ./build.sh
注:
* 由于依賴庫部署在板卡上,因此交叉編譯過程中必須保持adb連接。
2.3 模型獲取
【百度網(wǎng)盤】
鏈接:https://pan.baidu.com/s/1mrhVHxHWJ8cY9Fl9k5KtYg
提取碼:0k7j
本方案用到兩個模型:face_detect.model和face_recognition.model
直接把模型下載到本地Windows主機,復(fù)制
進入PC端Ubuntu創(chuàng)建存放model目錄:
cd /opt mkdir model
然后把模型從本地Windows主機粘貼到PC端Ubuntu中:
2.4 方案部署
使用下方命令再次回到開發(fā)實例目錄
cd /opt/EASY-EAI-Toolkit-C-UiSolution/qSolu-facialGate/
然后,通過執(zhí)行以下命令,將編譯結(jié)果手動部署到板卡中。
cp Release/qSolu-* /mnt/userdata/apps/facialGate cp QResource/audio -r /mnt/userdata/apps/facialGate
最后,將準備好的模型部署到板卡中(注意:模型要放到編譯結(jié)果的同一目錄中),執(zhí)行命令如下所示。
cp /opt/model/face_detect.model /mnt/userdata/apps/facialGate cp /opt/model/face_recognition.model /mnt/userdata/apps/facialGate
2.5 示例方案運行
通過按鍵Ctrl+Shift+T創(chuàng)建一個新窗口,執(zhí)行adb shell命令,進入板卡運行環(huán)境。
adb shell
進入板卡后,定位到例程部署的位置:
cd /userdata/apps/facialGate
運行例程命令如下所示:
./qSolu-facialGate
2.6 運行效果
運行打?。?/p>
液晶顯示屏上會顯示如下畫面:
點擊“歡迎”按鈕,可以呼出或者關(guān)閉鍵盤。
在對準攝像頭時,點擊注冊,即可完成人臉錄入,錄入后回到待機頁面。
當(dāng)用戶再次對準攝像頭,即可識別相關(guān)的用戶信息,如下圖所示:
3. QtCreator配置
3.1 運行qtcreator
在EASY-EAI編譯環(huán)境中的任意位置,通過下方命令,后臺打開qtcreator:
qtcreator &
注:若虛擬機配置較低,打開qtcreator可能要等待10幾秒。
3.2 打開Qt工程
3.3 配置遠程調(diào)試參數(shù)
注:進行遠程調(diào)試前,首先要用build.sh腳本把相關(guān)的資源拷貝到【開發(fā)板】相對應(yīng)的目錄上,否則會因缺少文件導(dǎo)致運行異常。
3.4 遠程運行Qt應(yīng)用
3.5 調(diào)試打印輸出&遠程停止應(yīng)用進程
3.6 修改應(yīng)用編譯輸出位置
注:任何修改*.pro或者*.pri的操作,都要clean掉Makefile后,再重新編譯。
4. 設(shè)計講解
本章節(jié)側(cè)重于講解代碼組織架構(gòu),以便于對代碼的輔助閱讀和理解,因此不涉及具體的操作指導(dǎo)和詳盡的代碼內(nèi)容解析。若需要進行上手操作的調(diào)試和開發(fā),可直接參考“開發(fā)指南”章節(jié)。
4.1 設(shè)計目的
本方案為產(chǎn)品級別的解決方案,需要調(diào)度種類繁多的各種資源,而且為了應(yīng)對不同用戶各自豐富多樣的需求,則需要對功能模塊進行解耦。故而針對該種情況設(shè)計了一套模塊調(diào)度框架。
4.2 模塊靜態(tài)關(guān)系
框架概覽 & 源碼目錄分布
源碼目錄說明:
組件子目錄 | 描述 |
QSrcCode/business/ | 應(yīng)用框架的核心代碼,用于實現(xiàn)、創(chuàng)建、各個業(yè)務(wù)功能模塊,以及協(xié)調(diào)各模塊間的相互調(diào)度。 |
QSrcCode/ui/ | 構(gòu)建界面相關(guān)的代碼,用于描述頁面的布局與顯示。 |
QSrcCode/common/ | 用戶的自定義代碼,也可以是存放和管理第三方代碼。 |
QSrcCode/apiWrapper/ | 若easyeai-api的代碼不能完全滿足產(chǎn)品要求,用戶可以在此目錄對easyeai-api進行抽象再封裝。 |
4.3 模塊動態(tài)交互
模板間的交互分為兩種,一種是非界面模塊間的交互,另一種是界面模塊間的交互。
4.3.1 非界面模塊之間的交互
非界面模塊間的交互,其特點是通過“應(yīng)用調(diào)度器”進行相互調(diào)度。
4.3.2 界面間的模塊交互
界面模塊間的交互,應(yīng)用了信號槽和事件機制,該種機制也是Qt為了去耦合而進行的針對性設(shè)計。而且Qt規(guī)定,非gui線程不能操作gui線程,因此從UIManager(非界面)到mainWidget(界面)的調(diào)用操作,也必須通過信號槽來完成。
4.4 模塊設(shè)計細節(jié)
4.4.1 應(yīng)用調(diào)度器
EASY-EAI-Toolkit-C-UiSolution/qSolu-facialGate/QSrcCode/ui/main.cpp是程序入口,應(yīng)用調(diào)度器在此處被創(chuàng)建,是本程序首個被創(chuàng)建的對象,具體代碼如下所示:
AppScheduler App;
應(yīng)用調(diào)度器類的構(gòu)成與功能:
class AppScheduler { public: AppScheduler(); ~AppScheduler(); int PosDataTo(Modeler mod, void *pData); private: int InitBusinessModel(); int Register(Modeler mod, BusinessCB pCBFunc); int UnRegister(Modeler mod); std::map m_BusinessModel; };
應(yīng)用調(diào)度器實質(zhì)上是一個回調(diào)函數(shù)映射表,在創(chuàng)建基礎(chǔ)業(yè)務(wù)功能塊時,需要把業(yè)務(wù)功能塊的回調(diào)函數(shù)注冊到應(yīng)用調(diào)度器的映射中(具體的注冊代碼,會在“開發(fā)指南”章節(jié)中的“添加一個新的業(yè)務(wù)功能模塊”涉及)。
4.4.2 基礎(chǔ)業(yè)務(wù)功能塊
所有的業(yè)務(wù)功能塊,都要繼承于基礎(chǔ)業(yè)務(wù)功能塊(BaseModel)。應(yīng)用調(diào)度器是各個BaseModel實例化對象之間的橋梁。
BaseModel源碼位于:
EASY-EAI-Toolkit-C-UiSolution/qSolu-facialGate/QSrcCode/business/basemodel.cpp
EASY-EAI-Toolkit-C-UiSolution/qSolu-facialGate/QSrcCode/business/basemodel.h
class BaseModel { public: explicit BaseModel(); ~BaseModel(); int SetScheduler(AppScheduler *pScheduler); /// 輸出>>>>: 向其他模塊輸出數(shù)據(jù) virtual int SendDataToDataAnnouncement(int cmdType, int dataLen, void *data); virtual int SendDataToDataBase(int cmdType, int dataLen, void *data); virtual int SendDataToMainThread(int cmdType, int dataLen, void *data); virtual int SendDataToMsgAdapter(int cmdType, int dataLen, void *data); virtual int SendDataToUI(int tagPage, int cmdType, int dataLen, void *data); private: int SendDataTo(Modeler mod, void *pData); AppScheduler *m_pScheduler; };
BaseModel在初始化時通過SetScheduler方法向子模塊綁定應(yīng)用調(diào)度器對象的指針。在程序交互的過程中通過調(diào)用SendDataTo方法向其他子模塊回調(diào)發(fā)送數(shù)據(jù)。
5. 開發(fā)指南
5.1 示例文件&目錄結(jié)構(gòu)
UiSolution git倉庫僅會放置兩個解決方案。
一是最簡潔的UI調(diào)用方案,用戶可以基于此方案,快速進行需要帶界面交互的產(chǎn)品開發(fā)。
二是帶調(diào)度框架的UI應(yīng)用方案,該方案為類人臉門禁機的產(chǎn)品級解決方案,其特點是模塊之間的耦合度低,用戶可以快速拓展自定義的業(yè)務(wù)功能模塊,以及快速更換UI皮膚。
5.1.1 UiSolution git倉庫目錄介紹。
UiSolution工程構(gòu)成如下所示,由功能組件easyeai-api和各個解決方案構(gòu)成。
功能組件的描述如下所示,easyeai-api是經(jīng)過高度封裝的易用性組件接口,便于用戶直接調(diào)用板卡資源。
功能 | 組件目錄 | 組件子目錄 | 描述 |
功能組件 | easyeai-api | algorithm_api | 算法組件 |
common_api | 通用組件 | ||
media_api | 多媒體組件 | ||
netProtocol_api | 網(wǎng)絡(luò)協(xié)議組件 | ||
peripheral_api | 外設(shè)硬件組件 |
解決方案的描述如下所示,單個“qSolu-”開頭的目錄即為一個解決方案案例,代碼內(nèi)調(diào)用“EASY EAI-API”來滿足某一實際應(yīng)用場景的需求。
功能 | 工程目錄 | 描述 |
解決方案 | qSolu-QDemo | 最簡單的UI交互方案 |
qSolu-facialGate | 類人臉識別門禁機解決方案 |
5.1.2 qSolu-facialGate解決方案的目錄結(jié)構(gòu)
每個解決方案就是一個獨立的項目,facialGate項目內(nèi)包含部分如下所示,項目使用qmake構(gòu)建自動編譯部署。
具體介紹如下所示。
組成部分 | 描述 |
build.sh | 編譯腳本,用于管理生成可執(zhí)行文件后的部署準備工作,用戶可自定義shell命令。 |
qSolu-facialGate.pro | 工程管理文件,用于組織整個工程結(jié)構(gòu),指導(dǎo)qmake生成Makefile。 |
resource.qrc | 工程管理文件,用于組織管理貼圖資源,樣式表資源等。 |
api.pri | 工程管理文件,用于組織管理“對easyeai-api拓展封裝”子模塊相關(guān)源碼。 |
business.pri | 工程管理文件,用于組織管理“業(yè)務(wù)功能”子模塊相關(guān)源碼。 |
common.pri | 工程管理文件,用于組織管理“第三方”子模塊相關(guān)源碼。 |
ui.pri | 工程管理文件,用于組織管理“UI界面效果”相關(guān)源碼。 |
QResource | 用于存放貼圖資源,樣式表資源等。 |
QSrcCode | 用于存放工程源代碼。 |
5.2 *.pro和*.pri文件解析
5.2.1 *.pro文件:
第一部分為輸出配置,如下所示:
配置信息如下所示。
配置項 | 描述 |
TARGET | 輸出文件名稱 |
TEMPLATE | 輸出文件類型,app為可執(zhí)行文件,lib為庫文件 |
第二部分為全局編譯選項配置,如下所示:
配置信息如下所示。
配置項 | 描述 |
LIBS | 全局鏈接庫,通常是本Ubuntu系統(tǒng)提供的庫 |
QMAKE_CXXFLAGS | 全局C++編譯參數(shù),可傳入一些宏或者C++編譯配置 |
第三部分為加載自定義子模塊,如下所示:
第四部分為加載資源管理,如下所示:
第五部分為指定文件輸出目錄,如下所示:
5.2.2 api.pri文件:
本工程文件是對我司的功能組件庫的管理,若用戶有“對我司的功能組件庫進行拓展封裝”的需求,則可通過本文件來管理。(針對當(dāng)前方案進行:配置EASY EAI API頭文件目錄、庫文件目錄以及配置庫鏈接參數(shù)):
配置信息如下所示。
配置項 | 描述 |
INCLUDEPATH | 向工程指定頭文件的查找路徑 |
LIBS | 指定對應(yīng)的easyeai-api庫文件以及其依賴的編譯參數(shù) |
SOURCES | 向工程添加需要編譯的源文件 |
HEADERS | 向工程添加需要編譯的頭文件 |
5.2.3 business.pri文件:
本工程文件是具體的應(yīng)用業(yè)務(wù)功能管理,用戶封裝的業(yè)務(wù)功能模塊可放置此處進行管理:
配置信息如下所示。
配置項 | 描述 |
INCLUDEPATH | 向工程指定頭文件的查找路徑 |
SOURCES | 向工程添加需要編譯的源文件 |
HEADERS | 向工程添加需要編譯的頭文件 |
5.2.4 common.pri文件:
本工程文件是第三方的庫的配置(針對當(dāng)前方案進行:配置第三方頭文件目錄、庫文件目錄、配置第三方庫鏈接參數(shù)以及配置源碼目錄):
配置信息如下所示。
配置項 | 描述 |
INCLUDEPATH | 向工程指定頭文件的查找路徑 |
SOURCES | 向工程添加需要編譯的源文件 |
HEADERS | 向工程添加需要編譯的頭文件 |
5.2.5 ui.pri文件:
本工程文件是交互界面相關(guān)的源碼文件配置,內(nèi)容如下所示:
配置項如下所示。
配置項 | 描述 |
SOURCES | 向工程添加需要編譯的源文件 |
HEADERS | 向工程添加需要編譯的頭文件 |
FORMS | 向工程添加Qt設(shè)計師產(chǎn)生的界面文件 |
5.3 build.sh編譯腳本:
5.3.1 路徑定位部分
第一部分用于提取目錄用于編譯操作,內(nèi)容如下所示:(進入build.sh腳本所在目錄,并且提取當(dāng)前目錄絕對路徑,提取當(dāng)前目錄名稱)
5.3.2 編譯參數(shù)部分
第二部分清除操作,清除目錄為Release,內(nèi)容如下所示:(執(zhí)行build.sh腳本時,帶入了參數(shù)“clear”,則清空編譯輸出;帶入了參數(shù)“all”,則重新編譯)
5.3.3 編譯操作
第三部分,編譯直接調(diào)用qmake,內(nèi)容如下所示:(重新編譯,并生成部署目錄)
5.4 添加一個新的業(yè)務(wù)功能模塊:
以名字為“myModel”為例:
從工程目錄EASY-EAI-Toolkit-C-UiSolution/qSolu-facialGate切換到business目錄:
cd QSrcCode/business/
5.4.1 創(chuàng)建model源碼文件
在business目錄下執(zhí)行:
mkdir myModel touch myModel/myModel.cpp touch myModel/myModel.h
在myModel.h中填入源代碼,具體操作為:
輸入命令:
vim myModel/myModel.h
在vim環(huán)境下,按“i”后,開始輸入代碼:
#ifndef __MYMODEL_H__ #define __MYMODEL_H__ #include "business/basemodel.h" /* *說明:由于每個模塊都是一個單例對象,因此: * 1,只能通過調(diào)用MyModel::createMyModel()去創(chuàng)建。 * 2,除了示例展示的2處new以外,其它地方不能使用new MyModel 去創(chuàng)建,否則會引發(fā)程序崩潰 */ class MyModel : public BaseModel { public: explicit MyModel(); ~MyModel(); static MyModel *instance() { if(m_pSelf == NULL){ once_flag oc; call_once(oc, [&] { m_pSelf = new MyModel; }); } return m_pSelf; } static void createMyModel(); private: static MyModel *m_pSelf; }; #endif // __MYMODEL_H__
輸入代碼完畢后,依次按下“Esc鍵”、“:鍵”、“w鍵”、“q鍵”、“回車鍵”保存代碼。(注意:w、q是小寫)
同myModel.h的操作方法,對myModel.cpp填入代碼:
#include "system.h" #include "myModel.h" MyModel *MyModel::m_pSelf = NULL; /* *說明:本回調(diào)為“阻塞回調(diào)”。因此有以下注意事項: * 1,返回值能夠直接在調(diào)用模塊中獲取。 * 2,通過修改輸入?yún)?shù)的指針指向的數(shù)據(jù),也能進行數(shù)據(jù)取回。 * 3,若在此回調(diào)進行阻塞操作,調(diào)用模塊也會被阻塞。 */ int MyModelCallback(void *data) { /*此回調(diào)處理其他模塊送入的消息*/ return 0; } MyModel::MyModel() { /*特別注意:不建議在構(gòu)造函數(shù)內(nèi)部使用跨模塊調(diào)度(m_pScheduler->PosDataTo(mod,data)),目標業(yè)務(wù)模塊有可能未被注冊*/ } MyModel::~MyModel() { if(m_pSelf){ delete m_pSelf; m_pSelf = NULL; } } void MyModel::createMyModel() { if(m_pSelf == NULL){ once_flag oc; call_once(oc, [&] { m_pSelf = new MyModel; }); } }
5.4.2 修改business.pri文件
在business目錄下執(zhí)行命令:
vim business.pri
同myModel.h的操作方法,添加下圖所示兩行代碼:
保存退出:
:wq
5.4.3 修改bsprotocol.h文件
在business目錄下執(zhí)行命令:
vim bsprotocol.h
在模塊映射枚舉中,加入“MYMODEL”索引。
保存退出:
:wq
5.4.4 修改appscheduler.cpp文件
在business目錄下執(zhí)行命令:
vim appscheduler.app
在appscheduler.cpp文件原有結(jié)構(gòu)基礎(chǔ)上,添加以下代碼:
新增模塊的頭文件:
#include "myModel/myModel.h"
新增模塊的回調(diào)函數(shù)聲明:
extern int MyModelCallback(void *data);
在AppScheduler中創(chuàng)建并注冊新增模塊:
MyModel::createMyModel(); MyModel::instance()->SetScheduler(this); Register(MYMODEL, MyModelCallback);
保存退出:
:wq
5.4.5 編譯與驗證
回到工程目錄EASY-EAI-Toolkit-C-UiSolution/qSolu-facialGate中,執(zhí)行命令:
./build.sh all
結(jié)果為:編譯成功,且在Release目錄中生成有myModel.o文件。則說明“myModel”業(yè)務(wù)功能被成功添加
編譯成功截圖:
myModel.o截圖:
5.5 屏蔽某個業(yè)務(wù)模塊功能:
此操作為本應(yīng)用調(diào)度框架的核心設(shè)計,若項目不需要某個功能。僅需在appscheduler.cpp的構(gòu)造函數(shù)中注釋掉其創(chuàng)建與注冊即可。除此以外無須改動任何代碼!因此本調(diào)度框架具備極強的靈活性以及低耦合度。
示例:
↓↓↓↓↓
審核編輯 黃宇
-
門禁系統(tǒng)
+關(guān)注
關(guān)注
17文章
395瀏覽量
46012 -
API
+關(guān)注
關(guān)注
2文章
1554瀏覽量
63287 -
人臉識別
+關(guān)注
關(guān)注
76文章
4054瀏覽量
83373
發(fā)布評論請先 登錄
相關(guān)推薦
基于RV1126開發(fā)板實現(xiàn)人臉識別方案

基于RV1126開發(fā)板實現(xiàn)人臉識別方案

評論