開源推薦 | 可實現門禁、AI測溫敏捷開發的人臉識別應用套件

隨着人臉識別技術的不斷髮展,尤爲是在部分算法平臺對外開放算法以後,人臉識別的應用門檻獲得了極大下降。可是從算法到一款真正可落地的人臉識別產品,在完整的應用開發中,不只須要考慮底層算法的運行邏輯,也須要上層業務邏輯完整自洽。而這個從0到1的過程,每每會讓大部分中下企業及開發者,在項目商用化落地過程當中無從下手。html

所以,在這裏推薦一款開源的人臉識別應用套件ArcFaceGo。基於該套件,能夠快速甚至零代碼搭建人臉識別閘機通行、刷臉考勤以及近來大火的人臉識別測溫等應用。同時,利用它的開源屬性,也徹底可以在此基礎上開發成一款符合自身業務需求的產品,並投入商用。算法

【簡單易用 ArcFaceGo****應用套件構成】網絡

在應用套件中,已經內置了虹軟視覺開放平臺的離線人臉識別SDK。涵蓋人臉檢測、人臉比對、活體檢測、人臉屬性分析等一系列核心算法,即便無網絡狀態下也能夠運行。在虹軟視覺開放平臺完成下載後,能夠看到該應用套件由人臉識別軟件APK、中心管理端兩部分構成。ide

中心管理端:擁有人員註冊、考勤統計、出入查詢等功能,也能夠雲端進一步對接已有的業務平臺。模塊化

人臉識別設備端應用APK****:負責採集人臉信息、進行身份比對,並向中心管理端報備識別結果以及通知相關聯通控制器。在該部分其代碼中,已經針對人臉檢測、人臉比對、活體檢測等算法,模塊化的集成了相應算法運轉邏輯。開發者無需考慮各算法之間複雜運轉流程,只需傳入camera數據流,即可以回調識別結果。性能

同時,針對人臉圖像傳輸、處理中須要用到的多媒體圖像技術,在代碼中也一樣模塊化的封裝好了NV2一、RGBA、BGR等不一樣顏色格式自動轉化及圖像的四字節對齊等功能。ui

在運行性能方面,該開源應用套件在底層算法邏輯中維護「人臉底庫」,能夠充分提高人臉識別速度,以RK3288 -10000人爲例,相比在上層邏輯中進行人臉比對須要100ms ,而目前僅需10ms。this

【適配靈活 可應用於各種實際場景****】.net

基於開源代碼,開發者能夠自行定義交互界面及交互邏輯,並開發應用於各種場景的人臉識別應用。好比智慧辦公的人臉識別考勤機、智慧社區的人臉識別出入閘機、智慧商業的VIP迎賓系統、智慧醫院的人臉識別掛號機、智慧酒店的人臉識別入住等等產品。htm

1.針對具體場景,可視化適配硬件

不一樣場景的不一樣應用,也意味着須要適配不一樣的分辨率設備,適配單攝、雙攝、寬動態等各種攝像頭。ArcFaceGo****人臉識別應用套件提供了可視化的硬件適配頁面,方便預覽顯示及識別設置。

用戶也能自行改寫該部分代碼,譬如不但願用戶自行調節相關參數,以致於影響識別效果,甚至能夠將該部分功能進行封裝,以避免用戶誤觸。

2.可供對接硬件的多種廣播形式。

Action 描述
com.arcsoft.arcfacesingle.ACTION_IDENTIFY_SUCCESSFUL 人員識別成功
com.arcsoft.arcfacesingle.ACTION_IDENTIFY_SUCCESS_PERSON_SERIAL 人員識別成功後,會向外發送「personSerial」惟一標識號」
com.arcsoft.arcfacesingle.ACTION_OPEN_DOOR 開門(在人員識別成功後會發送該廣播)
com.arcsoft.arcfacesingle.ACTION_CLOSE_DOOR 關門(發送開門廣播後,延遲一段時間會發送該廣播)
com.arcsoft.arcfacesingle.ACTION_FACE_DETECT_HAS_FACE 檢測到人臉框
com.arcsoft.arcfacesingle.ACTION_FACE_DETECT_NO_FACE 人臉框丟失

場景1

在室內走廊或樓梯過道等光線不佳的地方,能夠對接ACTION_FACE_DETECT_HAS_FACE和ACTION_FACE_DETECT_NO_FACE廣播,在檢測到人臉時打開補光燈,這樣能夠提升識別率。

場景2

在一些單次受權經過的場景好比取藥房,可對接ACTION_IDENTIFY_SUCCESS_PERSON_SERIAL廣播,在受權而且識別經過以後能夠刪除該人受權以達到目的。

【人臉識別測溫機開發實例】

疫情期間,不少智慧門禁設備都會增長測溫模組,在經過人臉識別實現身份權限管理的同時,一併測量體溫。

目前這類產品的市場反響很是火熱,不管是要實現抗疫常態化的國內,仍是感染人數持續暴增的國外,都對該產品有迫切需求。

這款應用套件能夠與測溫模塊快速集成,以實現測溫結果與識別身份綁定的效果。具體如何實現,如下是代碼示例。

如下是具體實現的代碼示例,以主流的HTPA32x32d爲例。

private ConcurrentMap<Integer, Float> temperatureMap = new ConcurrentHashMap<>();

private byte[] rawData = new byte[2048];
private ReadThread.ReadListener readListener = (data, size) -> {synchronized (temperatureLocker) {
       System.arraycopy(data, 1, rawData, 0, 2048);
  }
};

public void start() {
   ReadThread readThread = new ReadThread();
readThread.setListener(readListener);
readThread.start();

FaceEngine faceEngine = new FaceEngine();
Config config = new Config();
   faceEngine.setRecognizeCallback(this);
faceEngine.init(this, config);
}
   
@Override
public void onRecognizeComplete(RecognitionResult recognitionResult) {
   FaceInfo faceInfo = recognitionResult.faceInfo;        
   if (recognitionResult.result == ErrorInfo.MOK) {
       if(temperatureMap.get(faceInfo.faceId)<=37.3) {
           //溫度低於預警值而且識別成功,進行後續操做
      }
  }  
}

@Override
public void onCameraPreview(byte[] bytes, ICamera iCamera) {
FaceInfo faceInfo = new FaceInfo();
faceEngine.faceRecognize(rgbData, irData, width, height, true, faceInfo);

if (faceInfo.faceId != -1 && temperatureMap.get(faceInfo.faceId) != null) {
       //把額頭區域映射至32x32溫度矩陣中,取出對應的溫度
       float temperature = getTemperature(faceInfo.forehead, rawData);
       temperatureMap.put(faceInfo.faceId, temperature);
}
}

public class ReadThread extends Thread {private static final String HEIMANN_PATH = "/dev/ttyS2";
   private static final int BAUDRATE = 115200;
private static final byte[] command = {(byte) 0XEE, (byte) 0xE1, (byte) 0x01, (byte) 0x55, (byte) 0xFF, (byte) 0xFC, (byte) 0xFD, (byte) 0xFF};    
   private FileOutputStream outputStream;
   private FileInputStream inputStream;
   private Object locker = new Object();
   
   public ReadThread() {
       try {mSerialPort = SerialPort
                  .newBuilder(HEIMANN_PATH, BAUDRATE)
                  .parity(0)
                  .dataBits(8)
                  .stopBits(1)
                  .build();
           mInputStream = (FileInputStream) mSerialPort.getInputStream();
           mOutputStream = (FileOutputStream) mSerialPort.getOutputStream();
      } catch (IOException e) {
           e.printStackTrace();
      }
  }
   
   public void sendCommand(byte[] data) {
       if (mOutputStream != null) {
           try {synchronized (locker) {
                   mOutputStream.write(data);
                   offset = 0;
              }
          } catch (IOException e) {
               e.printStackTrace();
          }
      }
  }
   
   @Override
   public void run() {
       super.run();
       while (!isInterrupted()) {
           int size;
           try {synchronized (locker) {
                   if (mInputStream == null) {
                       return;
                  }
                   size = mInputStream.available();
                   if (size > 0) {
                       mInputStream.read(rawData, offset, size);
                       offset += size;
                  }
              }

               if (offset == rawData.length) {
                   if (getListener() != null) {
                       getListener().onDataReceived(rawData, offset);
                  }
                   offset = 0;
              }
               
               if (offset == 0) {
                   SystemClock.sleep(50);
                   sendCommand(command);
              }
          } catch (IOException e) {
               e.printStackTrace();
          }
      }
  }
}

對該產品感興趣的話能夠到虹軟視覺開放平臺進一步瞭解哦~

相關文章
相關標籤/搜索