虹軟AI 人臉識別SDK接入 — 性能優化篇(多線程)

你們都嫌公司之前使用的刷卡門禁太麻煩,正好借這個機會開發一我的臉識別的門禁系統,採用的SDK是虹軟公司開發的,接口調用比較簡單。多線程

1、虹軟SDK接口性能性能

在配置爲i5-7400 、16G內存的PC上測試性能以下:測試

1.FT 單次3ms左右優化

2.FD 單次10ms左右線程

3.FR 單次170ms左右 2、業務層須要解決的問題code

1.FT和FR單次性能相差較大,速度不匹配視頻

2.FT支持多人臉,單次檢測人臉較多,而FR只支持單人臉blog

3.視頻幀單次處理可能會超過幀間隔時間接口

3、優化方案內存

人臉識別過程包括三個步驟,檢測人臉、人臉特徵提取、特徵匹配,以人臉識別的門禁系統爲例,主要步驟獲取視頻幀、檢

測視頻幀人臉、提取特徵、特徵匹配,門禁系統對於實時性要求比較高。

流程圖大概以下:

下面說下開發過程當中多線程方面的優化點。

  1. 獲取視頻幀

攝像頭視頻的幀率正常在25~30幀左右,而且通常的視頻幀的分辨率爲1280x720,固然有的攝像頭能夠達到更大的分辨率,

可是通過測試多款攝像頭,發現分辨率設置過大會致使獲取視頻幀的過程當中卡頓。而且分辨率適中,會提高後面的FT的速度。獲取視頻幀的操做是在主線程進行的。

lock_guard<std::mutex> locker(g_CameraMutex);

if (m_camera->getFrame(m_curFrame))
{
    return;
}

ftProcessor->faceDetect(m_curFrame, m_resizeImage);
  1. 人臉識別處理優化

採用了獲取視頻幀和FT串行的方式,須要保證從獲取視頻幀一直處處理完成,必須在幀間隔時間內(幀率爲25時,在40ms左右),不然可能會出現卡幀的狀況。經測試,獲取視頻幀和FT串行的單次時間在幀間隔時間內,所以採用串行的方式。 FT支持多人臉檢測,我將檢測最大人臉數設置爲5,因此在極限狀態下,人數較多的話,待識別的人數可能一直維持在5人,這就須要提升FR的有效識別率。

FR使用了一個自定義threadsafe_queue簡化多線程數據同步操做,在FT中將須要進行FR的人臉框以及對應的視頻幀和人臉框的trackid push_back到threadsafe_queue中,FR線程從中取人臉框信息和視頻幀,作提取特徵和特徵匹配處理。

我從如下幾個點優化人臉識別效率:

a.增長FR線程數量。 對於我來講,開線程池的方式可行性並不過高。首先機器的內核數限制的線程數,動態增長線程數聽起來不錯,可是門禁使用的一體機畢竟跟開發機器不同,性能限制太多,而且線程切換和數據同步都會更加複雜。可是爲了提升FR的識別速度,我最終開了兩個FR線程,經測試,在i5-7400T 8G內存 配置的機器上,CPU大概處於40%左右。

b.提升FR識別效率 優化FR識別效率要求FR作到每次識別都是有效的,也就是說FR不作垃圾幀的處理。

1)每次在獲取到人臉後,判斷是否與前一幀檢測到的人臉結果屬於同一我的(經過trackid斷定,這一部分留到後面的文章說明,敬請期待)。若是某我的臉框首次出現,或者若是某個trackid對應的人臉框仍未識別成功,都須要作FR操做。

case FTSucceed:
case FRFailed:
{
    newFaceInfo.faceStatus = FRWaiting;
    FRParam frParam = { 0 };
    frParam.curImageInfo = m_curImageInfo;
    frParam.faceInfo.faceOrient = newFaceInfo.faceOrient;
    frParam.faceInfo.faceRect = {
        newFaceInfo.faceRect.wleft,
        newFaceInfo.faceRect.wtop,
        newFaceInfo.faceRect.wright,
        newFaceInfo.faceRect.wbottom };

    frParam.trackid = newFaceInfo.trackid;

    m_frParamsQueue.push(frParam);
}

當某個trackid對應的人臉已經在等待或者在作FR的時候,在後面檢測到的該trackid對應人臉將再也不作FR,一直到FR檢測結果出來之後,再作處理。

case FRProcessing:
case FRWaiting:
{
    //default color
}
break;

2)識別成功後,一樣將該trackid所對應的人臉都設置爲識別到的人,這樣下次就不須要再次作FR,不會浪費FR的時間片。 3)每次在從threadsafe_queue獲取的待處理的人臉框、trackid和視頻幀時,都檢測該trackid是否已消失,若是消失,就不作FR,由於拿到的結果毫無用處,直接丟棄。

std::lock_guard<std::mutex> locker(m_faceInfoListMutex);
//找到對應的trackid 對應的人臉,設置爲FRProcessing
auto iter = find_if(m_prevFacesRes.begin(), m_prevFacesRes.end(), [=](const FaceInfo& lhs)
{
    return lhs.trackid == frParam.trackid;
});

if (iter != m_prevFacesRes.end())
{
    iter->faceStatus = FRProcessing;
}
else
{
    //找不到 就不用作FR了
    continue;
}

好了,此次就說到這,你們有什麼問題的話,能夠留言,謝謝。 參考連接: 1.trackid 介紹:https://www.jianshu.com/p/4ae90634a79e

相關文章
相關標籤/搜索