帶你玩轉(zhuǎn)OpenHarmony AI:基于Seetaface2的人臉識別

簡介

隨著時代的進步,全民刷臉已經(jīng)成為一種新型的生活方式,這也是全球科技進步的又一階梯,人臉識別技術(shù)已經(jīng)成為一種大趨勢,無論在智慧出行、智能家居、智慧辦公等場景均有較廣泛的應(yīng)用場景,本文介紹了基于SeetaFace2人臉識別引擎在OpenAtom OpenHarmony(以下簡稱“OpenHarmony”)上實現(xiàn)人臉識別的AI能力。

什么是SeetaFace2

SeetaFace2是由中科視拓(北京)科技有限公司開發(fā)并使用BSD開源協(xié)議開源出來的一款人臉識別引擎庫,其搭建了一套全自動人臉識別系統(tǒng)所需的三個核心模塊,即:人臉檢測模塊FaceDetector、面部關(guān)鍵點定位模塊 FaceLandmarker 以及人臉特征提取與比對模塊FaceRecognizer。除了三個核心模塊外,它還提供了兩個輔助模塊FaceTracker和QualityAssessor用于人臉跟蹤和質(zhì)量評估。下圖是SeetaFace2人臉識別算法組件:

SeetaFace2能做什么

SeetaFace2采用標準C++開發(fā),全部模塊均不依賴任何第三方庫,支持x86架構(gòu)(Windows、Linux)和ARM架構(gòu),可以輕松地移植到OpenHarmony上。SeetaFace2支持的上層應(yīng)用包括但不限于人臉門禁、無感考勤、人臉比對等。如下圖展示了SeetaFace2支持的應(yīng)用矩陣:

SeetaFace2人臉識別原理

SeetaFace2人臉識別引擎搭建了一套全自動人臉識別系統(tǒng)所需的三個核心模塊:

1. 人臉檢測(FaceDetector)

在圖像中首先定位出人臉的位置,然后裁剪(crop)出包含人臉位置的矩形框,一般還會進行填充、縮放到指定尺寸,還可能會對人臉圖像進行標準化normalize;

2. 面部關(guān)鍵點定位(FaceLandmarker)

提取人臉關(guān)鍵點坐標,然后使用放射變化或相似變換等進行人臉對齊變換。面部關(guān)鍵點定位的目標就是把所有的人臉圖片統(tǒng)一到一個固定的正臉姿態(tài)大小,從而提高模型對人臉姿態(tài)變化的魯棒性。

3. 人臉特征提取與比對模塊(FaceRecognizer)

主要使用深度學習等方法提取人臉的特征,然后通過特征對比,計算人臉的相似度。

SeetaFace2人臉識別的具體過程如下圖所示:

兩步帶你實現(xiàn)人臉識別

關(guān)于SeetaFace2的如何移植到OpenHarmony移植請參照文檔:SeetaFace2移植開發(fā)文檔(請參考文章末尾相關(guān)文檔鏈接),這里我們主要分析通過SeetaFace2如何實現(xiàn)人臉識別。

從上面人臉識別的流程圖可以知道人臉識別主要包含2個大塊:人臉注冊和人臉識別。

1. 人臉注冊

人臉注冊首先需要對傳入的圖片進行人臉檢測,當檢測到人臉后會提取對應(yīng)的人臉信息,并將信息保存用于對比。

人臉信息檢測實現(xiàn):

std::vector<SeetaFaceInfo> DetectFace(const SeetaImageData &image)
{
  auto faces = FD.detect(image);
  return std::vector<SeetaFaceInfo>(faces.data, faces.data + faces.size);
}

其中FD是三大模塊中的人臉檢測模塊(FaceDetector),其加載了人臉檢測模型:

seeta::ModeStting FD_model("fd_2_00.dat", seeta::ModeStting::CPU, 0);

而返回SeetaFaceInfo數(shù)據(jù)則是檢測到的人臉信息,其中包含了人臉個數(shù),人臉區(qū)域坐標以及人臉置信度得分數(shù)據(jù)。然后通過人臉信息檢測返回的數(shù)據(jù)進行面部關(guān)鍵點定位。

面部關(guān)鍵點定位實現(xiàn):

std::vector<SeetaPointF> DetectPoints(const SeetaImageData &image, const SeetaRect &face)
{
  std::vector<SeetaPointF> points(PD.number());
  PD.mark(image, face, points.data());
  return std::move(points);
}

其中的PD是三大模塊中的關(guān)鍵點定位模塊(FaceLandmarker),關(guān)鍵點定位需要根據(jù)面部特征模型進行對比分析的,SeetaFace2提供2種面部特征模型。分別是通過5點定位和通過81點定位,此實例中我們使用的是81點定位模型:

seeta::ModeStting PD_model("pd_2_00_pts81.dat", seeta::ModeStting::CPU, 0);

獲取完面部特征數(shù)據(jù)后,SeetaFace2提供了一個人臉數(shù)據(jù)庫進行保存對應(yīng)的人臉信息數(shù)據(jù),以此來完成人臉信息的注冊:

int64_t Register(const SeetaImageData &image)
{
  auto faces =  DetectFace(image);
  auto points =  DetectPoints(image, faces.pos);
 
  return FDB.Register(image, points.data());
}   

其中FDB是SeetaFace2實現(xiàn)的FaceDatabase數(shù)據(jù)庫管理。該數(shù)據(jù)庫也為人臉識別提供面部特征數(shù)據(jù)的對比結(jié)果,面部特征對比也需要一個人臉數(shù)據(jù)模型:

seeta::ModeStting FDB_model("fr_2_00.dat", seeta::ModeStting::CPU, 0);

通過以上步驟,我們就已經(jīng)完成了人臉的注冊。

2. 人臉識別

人臉識別和人臉注冊步驟類似,都需要先檢測人臉信息及提取面部特征數(shù)據(jù)。唯一的區(qū)別在于提取面部特征時需要進行人臉質(zhì)量評估,最后根據(jù)質(zhì)量評估結(jié)果進行識別,具體實現(xiàn)如下:

int64_t RecogizePoint(const SeetaImageData &image)
{
    int64_t result = 0;
  seeta::ModeStting FD_model("fd_2_00.dat", seeta::ModeStting::CPU, 0);        // 此3步創(chuàng)建3個模型
  seeta::ModeStting PD_model("pd_2_00_pts81.dat", seeta::ModeStting::CPU, 0);
  seeta::ModeStting FDB_model("fr_2_00.dat", seeta::ModeStting::CPU, 0);
   
  seeta::FaceDetector FD(FD_model);    // 創(chuàng)建人臉檢測模塊
  seeta::FaceLandmarker PD(PD_model);   // 創(chuàng)建面部關(guān)鍵點定位模塊
  seeta::FaceDatabase FDB(FDB_model);    // 創(chuàng)建人臉特征信息數(shù)據(jù)庫模塊
   
  auto faces = FD.detect(image);        // 獲取人臉特征信息
    for (SeetaFaceInfo &face : faces) {    // 對比每個人臉信息
        int64_t index = -1;
        float similarity = 0;
        std::vector<SeetaPointF> points(PD.number());
      PD.mark(image, face, points.data());            // 獲取人臉框信息
        auto score = QA.evaluate(image, face.pos, points.data());   // 獲取人臉質(zhì)量評分
        if (score == 0) {
            HILOGI("no ignored\r\n");
        } else {
            auto queried = FDB.QueryTop(image, points.data(), 1, &index, &similarity);    // 從注冊的人臉數(shù)據(jù)庫中對比相似度
            if (queried < 1) {
                continue;
            }
            if (similarity > threshold) {
                HILOGI("get recognized face!! \r\n");
                result++;
            }
        }
    }
     
    return result;
}

寫在最后

  • 如果你覺得這篇內(nèi)容對你還蠻有幫助,我想邀請你幫我三個小忙:
  • 點贊,轉(zhuǎn)發(fā),有你們的 『點贊和評論』,才是我創(chuàng)造的動力。
  • 關(guān)注小編,同時可以期待后續(xù)文章ing??,不定期分享原創(chuàng)知識。
  • 想要獲取更多完整鴻蒙最新學習知識點,請移步前往小編:https://gitee.com/MNxiaona/733GH/blob/master/jianshu
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容