1、通用流程概述
根據實際應用場景以及硬件配置,活體檢測和特征提取可選擇是否采用并行的方式。
如上圖所示,人臉識別的核心業務流程可以分為以下四個步驟:
a)人臉檢測:采集視頻幀或靜態圖,傳入算法進行檢測,輸出人臉數據,用于后續的檢測。 b)活體檢測:在人臉識別過程中判斷操作用戶是否為真人,有效防御照片、視頻、紙張等不同類型的作弊攻擊,提高業務安全性,可根據應用場景選擇是否接入; c)特征提取:對待比對的圖像進行特征提取、人臉庫的預提取,用于之后的比對; d)人臉識別:1:1比對主要是判斷「你是你」,用于核實身份的真實性;1:N搜索主要識別「你是誰」,用于明確身份的具體所屬。
虹軟產品:
ArcFace 離線SDK,包含人臉檢測、性別檢測、年齡檢測、人臉識別、圖像質量檢測、RGB活體檢測、IR活體檢測等能力,初次使用時需聯網激活,激活后即可在本地無網絡環境下工作,可根據具體的業務需求結合人臉識別SDK靈活地進行應用層開發。
2、ArcFace接入集成及示例
2.1 SDK的獲取
訪問ArcSoft AI開放平臺門戶:https://ai.arcsoft.com.cn,注冊開發者賬號并登錄。
SDK下載
創建對應的應用,并選擇需要下載的SDK、對應平臺以及版本,確認后即可下載SDK。
查看APP_ID、SDK_KEY ,點擊下載圖標獲取SDK開發包。
2.2 SDK包結構
|---doc | |---ARCSOFT_ARC_FACE_JAVA_DEVELOPER'S_GUIDE.pdf 開發說明文檔 |---lib |---|---Win32/x64 | |---|---libarcsoft_face.dll 算法庫 | |---|---libarcsoft_face_engine.dll 引擎庫 | |---|---libarcsoft_face_engine_jni.dll 引擎庫 | |---arcsoft-sdk-face-3.0.0.0.jar java依賴庫 |---samplecode | |---FaceEngineTest.java 示例代碼 |---releasenotes.txt 說明文件
2.3 指標
算法檢測指標受硬件配置、圖像數據質量、測試方法等因素影響,以下實驗數據僅供參考,具體數據以實際應用場景測試結果為準。
2.3.1 算法性能
硬件信息:
安裝內存(RAM):16.0GB(15.9GB可用)
系統類型:win10 64位操作系統
分辨率:1280 x 720
不同人臉庫條件下人臉比對+RGB活體檢測全流程體感耗時
人臉庫 | 性能(ms) |
---|---|
1000 | < 200 |
5000 | < 300 |
10000 | < 600 |
2.3.2 閾值推薦
活體取值范圍為[0~1],推薦閾值如下,高于此閾值的即可判斷為活體。
RGB 活體:0.5
IR 活體:0.7
人臉比對取值范圍為[0~1],推薦閾值如下,高于此閾值的即可判斷為同一人。
用于生活照之間的特征比對,推薦閾值0.80
用于證件照或生活照與證件照之間的特征比對,推薦閾值0.82
2.3.3 圖像質量要求
建議待檢測的圖像人臉角度上、下、左、右轉向小于30度;
圖片中人臉尺寸不小于50 x 50像素;
圖片大小小于10MB;
圖像清晰;
2.4 在項目中引入 SDK 包
com.arcsoft.face arcsoft-sdk-face 3.0.0.0 system ${project.basedir}/lib/arcsoft-sdk-face-3.0.0.0.jar
2.4.1?簡要集成示例
package com.arcsoft; import com.arcsoft.face.*; import?com.arcsoft.face.enums.ImageFormat; import javax.imageio.ImageIO; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.ColorConvertOp; import java.awt.image.DataBufferByte; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class FaceEngineTest { public static void main(String[] args) { new FaceEngineTest().faceEngineTest(); } public void faceEngineTest() { String appId = ""; ????????String?sdkKey?=?""; FaceEngine faceEngine = new FaceEngine(); //激活引擎 faceEngine.active(appId, sdkKey); EngineConfiguration engineConfiguration = EngineConfiguration.builder().functionConfiguration( FunctionConfiguration.builder() .supportAge(true) .supportFace3dAngle(true) .supportFaceDetect(true) .supportFaceRecognition(true) .supportGender(true) .supportLiveness(true) .build()).build(); //初始化引擎 faceEngine.init(engineConfiguration); ImageInfo imageInfo = getRGBData(new File("d:\1.jpg")); ImageInfo imageInfo2 = getRGBData(new File("d:\2.jpg")); //人臉檢測 ListfaceInfoList = new ArrayList (); faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList); List faceInfoList2 = new ArrayList (); ????????faceEngine.detectFaces(imageInfo.getRgbData(),?imageInfo.getWidth(),?imageInfo.getHeight(),?ImageFormat.CP_PAF_BGR24,?faceInfoList2); //提取人臉特征 FaceFeature faceFeature = new FaceFeature(); faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList.get(0), faceFeature); FaceFeature faceFeature2 = new FaceFeature(); faceEngine.extractFaceFeature(imageInfo2.getRgbData(), imageInfo2.getWidth(), imageInfo2.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList2.get(0), faceFeature2); //人臉對比 FaceFeature targetFaceFeature = new FaceFeature(); targetFaceFeature.setFeatureData(faceFeature.getFeatureData()); FaceFeature sourceFaceFeature = new FaceFeature(); sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData()); FaceSimilar faceSimilar = new FaceSimilar(); ????????faceEngine.compareFaceFeature(targetFaceFeature,?sourceFaceFeature,?faceSimilar); int processResult = faceEngine.process(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList, FunctionConfiguration.builder().supportAge(true).supportFace3dAngle(true).supportGender(true).supportLiveness(true).build()); //性別提取 List genderInfoList = new ArrayList (); int genderCode = faceEngine.getGender(genderInfoList); //年齡提取 List ageInfoList = new ArrayList (); int ageCode = faceEngine.getAge(ageInfoList); //3D信息提取 List face3DAngleList = new ArrayList (); int face3dCode = faceEngine.getFace3DAngle(face3DAngleList); //活體信息 List livenessInfoList = new ArrayList (); int livenessCode = faceEngine.getLiveness(livenessInfoList); System.out.println(); ????} public ImageInfo getRGBData(File file) { if (file == null) return null; ImageInfo imageInfo; try { //將圖片文件加載到內存緩沖區 BufferedImage image = ImageIO.read(file); imageInfo = bufferedImage2ImageInfo(image); } catch (IOException e) { e.printStackTrace(); return null; } return imageInfo; ????} private ImageInfo bufferedImage2ImageInfo(BufferedImage image) { ImageInfo imageInfo = new ImageInfo(); int width = image.getWidth(); int height = image.getHeight(); // 使圖片居中 width = width & (~3); height = height & (~3); imageInfo.setWidth(width); imageInfo.setHeight(height); //根據原圖片信息新建一個圖片緩沖區 BufferedImage resultImage = new BufferedImage(width, height, image.getType()); //得到原圖的rgb像素矩陣 int[] rgb = image.getRGB(0, 0, width, height, null, 0, width); //將像素矩陣 繪制到新的圖片緩沖區中 resultImage.setRGB(0, 0, width, height, rgb, 0, width); //進行數據格式化為可用數據 BufferedImage dstImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) { ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints()); colorConvertOp.filter(resultImage, dstImage); } else { dstImage = resultImage; } //獲取rgb數據 imageInfo.setRgbData(((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData()); return imageInfo; } class ImageInfo { public byte[] rgbData; public int width; ????????public?int?height; public byte[] getRgbData() { return rgbData; ????????} public void setRgbData(byte[] rgbData) { this.rgbData = rgbData; ????????} public int getWidth() { return width; ????????} public void setWidth(int width) { this.width = width; ????????} public int getHeight() { return height; ????????} public void setHeight(int height) { this.height = height; } } }
參考文獻:https://ai.arcsoft.com.cn/manual/docs
編輯:黃飛
評論
查看更多