本篇內容介紹了“Qt如何實現人臉識別嵌入式”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在橫峰等地區,都構建了全面的區域性戰略布局,加強發展的系統性、市場前瞻性、產品創新能力,以專注、極致的服務理念,為客戶提供成都網站設計、成都做網站、外貿網站建設 網站設計制作按需網站開發,公司網站建設,企業網站建設,品牌網站建設,全網營銷推廣,成都外貿網站建設,橫峰網站建設費用合理。
大概幾年前搞過一套嵌入式linux上的人臉識別程序,當然人臉識別的核心算法并不是自己開發的,關于人臉識別算法這一塊,雖然有眾多的開源庫可以用,甚至還可以用opencv搞算法訓練深度學習之類的,個人認為始終達不到準確度的要求,尤其是人臉比對的準確度,這個需要專業的人臉訓練模型才行。目前市面上絕大部分的人臉識別庫提供的都是X86的或者安卓ios的庫,并沒有嵌入式linux的庫,估計一方面因為嵌入式linux跑的板子性能比較低,還有一個就是依賴特定編譯器,版本眾多難以提供,市場也小,所以大部分的廠家都沒有提供嵌入式linux的開發包,這個就比較雞肋,所以很多終端廠家最終棄用linux而選用安卓作為載體系統,這樣就可以用上高大上的人臉識別庫了,比如螢火蟲開發板,RK3288 RK3399等。
記得當時還特意搞了一整套的非常詳細的通信協議,產品也初步成型,大概的設備有人臉識別終端、雙目門禁、人工訪客機、自助訪客機、人臉比對服務器等,也試運行了一些小區,效果還行,不過在抗逆光和晚上的情況下效果不是很好,當然這是所有人臉識別設備的通病,必須依賴補光或者調整安裝位置增加抗逆光攝像機來處理,這樣一來對施工就有要求了增加了復雜度,設備成本也上來了,對于小終端廠商來說,這個要選擇一個平衡點才行,只有用戶愿意付出對應的成本才提供對應的版本。
通信方式及端口:
客戶端和服務端等設備統一提供web訪問修改配置,端口6660。
人工訪客機客戶端與人工訪客機服務端通信采用TCP短連接,通信端口6661。
自助訪客機客戶端與自助訪客機服務端通信采用TCP長連接,通信端口6661。
人臉識別比對數據庫服務器采用TCP長連接,通信端口6662。
服務端與數據庫服務器通信采用TCP長連接,通信端口6666。
數據庫服務器下發人臉通行證數據采用TCP短連接,通信端口6667。
電腦PC端下發配置到雙目門禁采用TCP短連接,通信端口6668。
雙目門禁與數據庫服務器通信采用TCP長連接,通信端口6669。
雙目門禁電腦客戶端升級通信采用TCP短連接,通信端口6670。
檢測測試與手機app或者其他客戶端通信采用TCP長連接,通信端口6671。
支持的功能包括人臉識別、人臉比對、人臉搜索、活體檢測等。
在線版還支持身份證、駕駛證、行駛證、銀行卡等識別。
在線版的協議支持百度、曠視,離線版的支持百度,可定制。
除了支持X86架構,還支持嵌入式linux比如contex-A9、樹莓派等。
每個功能的執行除了返回結果還返回執行用時時間。
多線程處理,通過type控制當前處理類型。
支持單張圖片檢索相似度最高的圖片。
支持指定目錄圖片用來生成人臉特征值文件。
可設置等待處理圖片隊列中的數量。
每次執行都有成功或者失敗的信號返回。
人臉搜索的返回結果包含了原圖+最大相似度圖+相似度等。
人臉比對同時支持兩張圖片和兩個特征值比對。
相關功能自定義一套協議用于客戶端和服務端,可以通過TCP通信進行交互。
自定義人臉識別協議非常適用于中心一臺服務器,現場若干設備請求的場景。
每個模塊全部是獨立的一個類,代碼整潔、注釋完善。
void FaceLocalArm::imgToBgr(const QImage &img, quint8 *bgr, int w, int h) { for (int i = 0; i < h; ++i) { const quint8 *scanline = img.scanLine(i); for (int j = 0; j < w; ++j) { *bgr++ = scanline[j * 3 + 0]; *bgr++ = scanline[j * 3 + 1]; *bgr++ = scanline[j * 3 + 2]; } } } void FaceLocalArm::bgrToYuv(quint8 *yuv, const quint8 *bgr, int w, int h) { int b, g, r; for (int i = 0; i < w * h; ++i) { b = bgr[3 * i + 0]; g = bgr[3 * i + 1]; r = bgr[3 * i + 2]; yuv[i] = (quint8)((r * 30 + g * 59 + b * 11 + 50) / 100); } } void FaceLocalArm::init() { //如果已經正常則無需初始化 if (isOk) { return; } #ifdef __arm__ int res = CRface::FaceDetect_Init_ColorReco(sdkPath.toStdString()); if (res != 1) { qDebug() << TIMEMS << QString("FaceDetect_Init_ColorReco error: %1").arg(res); } else { qDebug() << TIMEMS << "FaceDetect_Init_ColorReco ok"; res = CRface::FaceReco_Init_ColorReco(sdkPath.toStdString()); if (res != 1) { qDebug() << TIMEMS << QString("FaceReco_Init_ColorReco error: %1").arg(res); } else { isOk = true; qDebug() << TIMEMS << "FaceReco_Init_ColorReco ok"; } } emit sdkInitFinsh(isOk); #endif } bool FaceLocalArm::getFaceRect(const QString &flag, const QImage &img, QRect &rect, int &msec) { if (!isOk) { return false; } #ifdef __arm__ //qDebug() << TIMEMS << flag << "getFaceRect"; QTime time; if (countTime) { time.start(); } int w = img.width(); int h = img.height(); //這里有隱患,如果圖片像素特別大會崩潰,應該改為quint8 *bgr=(quint8 *)calloc(w * h * 3, 1);然后后面free(bgr); quint8 yuv[w * h]; quint8 bgr[w * h * 3]; imgToBgr(img, bgr, w, h); int facebox[32 * 5]; bgrToYuv(yuv, bgr, w, h); facebox[0] = 0; int result = 0; if (findFast) { result = CRface::FaceDetect_Fast_ColorReco(yuv, w, h, facebox, true); } else { result = CRface::FaceDetect_Normal_ColorReco(yuv, w, h, facebox, true, w / percent); } if (result == 1) { rect = QRect(facebox[1], facebox[2], facebox[3], facebox[4]); msec = getTime(time); return true; } #endif return false; } bool FaceLocalArm::getFaceFeature(const QString &flag, const QImage &img, QList&feature, int &msec) { if (!isOk) { return false; } #ifdef __arm__ //qDebug() << TIMEMS << flag << "getFaceFeature" << img.width() << img.height() << img.size(); QTime time; if (countTime) { time.start(); } int w = img.width(); int h = img.height(); //這里有隱患,如果圖片像素特別大會崩潰,應該改為quint8 *bgr=(quint8 *)calloc(w * h * 3, 1);然后后面free(bgr); quint8 yuv[w * h]; quint8 bgr[w * h * 3]; imgToBgr(img, bgr, w, h); int facebox[32 * 5]; bgrToYuv(yuv, bgr, w, h); facebox[0] = 0; int result = 0; if (findFast) { result = CRface::FaceDetect_Fast_ColorReco(yuv, w, h, facebox, true); } else { result = CRface::FaceDetect_Normal_ColorReco(yuv, w, h, facebox, true, w / percent); } if (result == 1) { QRect rect = QRect(facebox[1], facebox[2], facebox[3], facebox[4]); msec = getTime(time); emit receiveFaceRect(flag, rect, msec); float fea[256]; int result = CRface::FaceReco_Extract_ColorReco(bgr, w, h, facebox + 1, fea); if (result == 256) { feature.clear(); for (int i = 0; i < 256; i++) { feature.append(fea[i]); } msec = getTime(time); return true; } } else { emit receiveFaceRectFail(flag); } #endif return false; } float FaceLocalArm::getFaceCompare(const QString &flag, const QList &feature1, const QList &feature2) { if (!isOk) { return 0; } #ifdef __arm__ //qDebug() << TIMEMS << flag << "getFaceCompareXXX"; float fea1[256], fea2[256]; for (int i = 0; i < 256; i++) { fea1[i] = feature1.at(i); fea2[i] = feature2.at(i); } float result = CRface::FaceReco_Match_ColorReco(fea1, fea2); result = result * 100; //過濾非法的值 result = result > 100 ? 0 : result; return result; #endif return 0; }
“Qt如何實現人臉識別嵌入式”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注創新互聯網站,小編將為大家輸出更多高質量的實用文章!