溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Qt如何實(shí)現(xiàn)人臉識(shí)別嵌入式

發(fā)布時(shí)間:2021-12-15 10:14:28 來(lái)源:億速云 閱讀:259 作者:iii 欄目:互聯(lián)網(wǎng)科技

本篇內(nèi)容介紹了“Qt如何實(shí)現(xiàn)人臉識(shí)別嵌入式”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

一、前言

大概幾年前搞過(guò)一套嵌入式linux上的人臉識(shí)別程序,當(dāng)然人臉識(shí)別的核心算法并不是自己開(kāi)發(fā)的,關(guān)于人臉識(shí)別算法這一塊,雖然有眾多的開(kāi)源庫(kù)可以用,甚至還可以用opencv搞算法訓(xùn)練深度學(xué)習(xí)之類的,個(gè)人認(rèn)為始終達(dá)不到準(zhǔn)確度的要求,尤其是人臉比對(duì)的準(zhǔn)確度,這個(gè)需要專業(yè)的人臉訓(xùn)練模型才行。目前市面上絕大部分的人臉識(shí)別庫(kù)提供的都是X86的或者安卓ios的庫(kù),并沒(méi)有嵌入式linux的庫(kù),估計(jì)一方面因?yàn)榍度胧絣inux跑的板子性能比較低,還有一個(gè)就是依賴特定編譯器,版本眾多難以提供,市場(chǎng)也小,所以大部分的廠家都沒(méi)有提供嵌入式linux的開(kāi)發(fā)包,這個(gè)就比較雞肋,所以很多終端廠家最終棄用linux而選用安卓作為載體系統(tǒng),這樣就可以用上高大上的人臉識(shí)別庫(kù)了,比如螢火蟲(chóng)開(kāi)發(fā)板,RK3288 RK3399等。

記得當(dāng)時(shí)還特意搞了一整套的非常詳細(xì)的通信協(xié)議,產(chǎn)品也初步成型,大概的設(shè)備有人臉識(shí)別終端、雙目門禁、人工訪客機(jī)、自助訪客機(jī)、人臉比對(duì)服務(wù)器等,也試運(yùn)行了一些小區(qū),效果還行,不過(guò)在抗逆光和晚上的情況下效果不是很好,當(dāng)然這是所有人臉識(shí)別設(shè)備的通病,必須依賴補(bǔ)光或者調(diào)整安裝位置增加抗逆光攝像機(jī)來(lái)處理,這樣一來(lái)對(duì)施工就有要求了增加了復(fù)雜度,設(shè)備成本也上來(lái)了,對(duì)于小終端廠商來(lái)說(shuō),這個(gè)要選擇一個(gè)平衡點(diǎn)才行,只有用戶愿意付出對(duì)應(yīng)的成本才提供對(duì)應(yīng)的版本。

通信方式及端口:

  • 客戶端和服務(wù)端等設(shè)備統(tǒng)一提供web訪問(wèn)修改配置,端口6660。

  • 人工訪客機(jī)客戶端與人工訪客機(jī)服務(wù)端通信采用TCP短連接,通信端口6661。

  • 自助訪客機(jī)客戶端與自助訪客機(jī)服務(wù)端通信采用TCP長(zhǎng)連接,通信端口6661。

  • 人臉識(shí)別比對(duì)數(shù)據(jù)庫(kù)服務(wù)器采用TCP長(zhǎng)連接,通信端口6662。

  • 服務(wù)端與數(shù)據(jù)庫(kù)服務(wù)器通信采用TCP長(zhǎng)連接,通信端口6666。

  • 數(shù)據(jù)庫(kù)服務(wù)器下發(fā)人臉通行證數(shù)據(jù)采用TCP短連接,通信端口6667。

  • 電腦PC端下發(fā)配置到雙目門禁采用TCP短連接,通信端口6668。

  • 雙目門禁與數(shù)據(jù)庫(kù)服務(wù)器通信采用TCP長(zhǎng)連接,通信端口6669。

  • 雙目門禁電腦客戶端升級(jí)通信采用TCP短連接,通信端口6670。

  • 檢測(cè)測(cè)試與手機(jī)app或者其他客戶端通信采用TCP長(zhǎng)連接,通信端口6671。

二、功能特點(diǎn)

  1. 支持的功能包括人臉識(shí)別、人臉比對(duì)、人臉?biāo)阉?、活體檢測(cè)等。

  2. 在線版還支持身份證、駕駛證、行駛證、銀行卡等識(shí)別。

  3. 在線版的協(xié)議支持百度、曠視,離線版的支持百度,可定制。

  4. 除了支持X86架構(gòu),還支持嵌入式linux比如contex-A9、樹(shù)莓派等。

  5. 每個(gè)功能的執(zhí)行除了返回結(jié)果還返回執(zhí)行用時(shí)時(shí)間。

  6. 多線程處理,通過(guò)type控制當(dāng)前處理類型。

  7. 支持單張圖片檢索相似度最高的圖片。

  8. 支持指定目錄圖片用來(lái)生成人臉特征值文件。

  9. 可設(shè)置等待處理圖片隊(duì)列中的數(shù)量。

  10. 每次執(zhí)行都有成功或者失敗的信號(hào)返回。

  11. 人臉?biāo)阉鞯姆祷亟Y(jié)果包含了原圖+最大相似度圖+相似度等。

  12. 人臉比對(duì)同時(shí)支持兩張圖片和兩個(gè)特征值比對(duì)。

  13. 相關(guān)功能自定義一套協(xié)議用于客戶端和服務(wù)端,可以通過(guò)TCP通信進(jìn)行交互。

  14. 自定義人臉識(shí)別協(xié)議非常適用于中心一臺(tái)服務(wù)器,現(xiàn)場(chǎng)若干設(shè)備請(qǐng)求的場(chǎng)景。

  15. 每個(gè)模塊全部是獨(dú)立的一個(gè)類,代碼整潔、注釋完善。

三、效果圖

Qt如何實(shí)現(xiàn)人臉識(shí)別嵌入式

四、核心代碼

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()
{
    //如果已經(jīng)正常則無(wú)需初始化
    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();

    //這里有隱患,如果圖片像素特別大會(huì)崩潰,應(yīng)該改為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<float> &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();

    //這里有隱患,如果圖片像素特別大會(huì)崩潰,應(yīng)該改為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<float> &feature1, const QList<float> &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;
    //過(guò)濾非法的值
    result = result > 100 ? 0 : result;
    return result;
#endif

    return 0;
}

“Qt如何實(shí)現(xiàn)人臉識(shí)別嵌入式”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

qt
AI