無論你注意到沒有,人臉識別已經走進了生活的角角落落,釘釘已經支持人臉打卡,火車站實名認證已經增長了人臉自助驗證通道,更別提各個城市建設的『智能城市』和智慧大腦了。在人臉識別業界,一般由人臉識別提供商和人臉識別應用接入方組成,從頭至尾研發人臉識別技術須要極強的專用技術知識和數學算法功底,對於大多數企業來講,選擇人工智能AI公司現成的人臉識別技術引擎是一個比較適合的解決方法。虹軟公司在2017年開放了人臉識別平臺1.0版本,通過三年的技術迭代和更新,目前已經推出了2.2版本,主打離線,免費,適合場景比較普遍。爲了方便開發者接入,虹軟官方提供了各個語言版本的Demo程序,因爲虹軟並無提供C#版本的SDK,所以,他們提供的C#版本的SDK就更有參考價值了。php
虹軟Demo的下載地址以下:https://github.com/ArcsoftEscErd/ArcfaceDemo_CSharp_2.2 在開始以前,建議你下載它。html
人臉識別,是基於人的臉部特徵信息進行身份識別的一種生物識別技術。用攝像機或攝像頭採集含有人臉的圖像或視頻流,並自動在圖像中檢測和跟蹤人臉,進而對檢測到的人臉進行臉部識別的一系列相關技術,一般也叫作人像識別、面部識別。
而人臉識別的過程能夠簡的歸納爲:檢測人臉框->提取人臉特徵信息->人臉庫檢索匹配信息三個過程。git
人臉識別主要用於身份識別。因爲視頻監控正在快速普及,衆多的視頻監控應用迫切須要一種遠距離、用戶非配合狀態下的快速身份識別技術,以求遠距離快速確認人員身份,實現智能預警。人臉識別技術無疑是最佳的選擇,採用快速人臉檢測技術能夠從監控視頻圖象中實時查找人臉,並與人臉數據庫進行實時比對,從而實現快速身份識別。
在現實生活中,從最多見的人臉門禁,到實名制安檢,景區驗票,公司或者學校的人臉簽到,無人超市等都有普遍的應用。github
活體檢測檢測顧名思義就是經過識別活體上的生理信息,來區分用照片、硅膠、塑料等非生命物質僞造的生物特徵。人臉識別應用中的活體檢測技術用來判斷系統採集到的人臉圖像是否來源於真實的人臉,以防止照片、視頻等僞造的人臉圖像被輸入到系統形成誤判,活體檢測在無人值守場景下的人臉識別商業應有中顯得相當重要。算法
目前市面上有不少人臉識別技術方案,從是否須要使用時聯網能夠分爲在線和離線,從接入方式上能夠分爲本地識別和服務器大數據識別等方式,虹軟提供的是基於本地算法特徵的離線識別SDK,其基礎算法使用C編寫,提供全平臺的離線支持.數據庫
虹軟人臉識別SDK經過視覺開放平臺提供,包含人臉識別場景中最經常使用到的功能組件,例如:人臉檢測,人臉識別,年齡性別檢測,活體檢測 等,其中人臉檢測針對靜態和動態檢測場景分別進行了算法優化,從中派生的性別和年齡檢測擴充了人臉識別的使用場景,活體檢測組件能夠有效的保證人臉識別應用的安全性。
訪問 https://ai.arcsoft.com.cn/third/mobile.html?segmentfault 按照網站的提示,能夠註冊用戶和下載SDK包。segmentfault
虹軟的SDK,和大量基於Restful風格的接口不一樣,沒有使用普通的基於HTTP的方式,也並無提供C#語言的SDK包,僅提供了C語言的SDK,對於C#接入有必定的困難,在發佈之初有很多大神自行編寫接入Demo程序,後來,虹軟官方也出了Demo程序,從2018年1月的第一個版本到如今隨着SDK更新的2.2版本,代碼結構和註釋更爲清晰。api
Demo是標準的C# WINFORM工程樣式,經過GitHub,下載下來以後,能夠直接使用VS打開.
打開以後,有一個readme.md文件,十分重要,在開始以前,請務必仔細看一下。這裏把要點給你們總結一下。安全
若是上述幾步都OK,程序能夠正常運行,若是中間有問題,能夠參考readme中的內容進行排查。服務器
通常OK以後,系統彈出正常運行的窗口,網上找幾張明星照片進行註冊,對比。
以下圖所示:
能夠看到,虹軟Demo已經能夠正確的識別人臉信息。
Demo中還提供了活體檢測功能,若是你的機器沒有攝像頭,能夠外插一個USB的攝像頭,點擊啓用攝像頭,打開它。
若是咱們用本身的人臉識別,會顯示RGB活體,若是是用照片或者視頻嘗試識別,會顯示『RGB假體』
接下來進入正題,讓咱們打開工程視圖,從代碼角度解析一下虹軟人臉識別Demo的代碼結構及主要流程。
從上圖中能夠發現代碼結構仍是很清晰
目錄 | 說明 |
---|---|
Entity | 用於放置一些實體類 |
lib | 放置的第三庫,主要是用於獲取視頻幀的內容 |
SDKModels | SDK的字段模型類,主要是和SDK進行交互,普通使用時無需關注 |
SDKUtils | 針對SDK功能的C#封裝,建議使用Utils中的二次封裝類 |
Utils | 提供的一些工具類,這些類將複雜的SDK操做變得簡單,咱們能夠在項目中直接使用這些類 |
全部的界面功能都在FaceForm.cs中,咱們打開代碼視圖,代碼各個區域的代碼結構清晰,咱們來看一下主要部分的功能。
參數定義部分主要是針對一些參數進行定義,有相應的註釋,咱們須要關注的是圖片大小和類似度。
private long maxSize = 1024 * 1024 * 2;
這個參數定義了能夠識別的最大圖片大小,能夠根據須要進行調整。
private float threshold = 0.8f;
這個參數定義了置信度,也就是當類似度達到多少時,咱們認爲是一我的
初始化部分的一個重要的方法 InitEngines(),做用是用來初始化人臉識別引擎。
這部分的代碼首先獲取配置文件的信息,而後讀取這些信息,並進行引擎的激活操做,若是出現錯誤,則彈出提示信息。
這裏須要注意的是,因爲C#是支持多CPU架構的,虹軟SDK的32和64位的版本對應的dll並不相同,因此須要咱們自行判斷當前是運行在哪一個模式下的。
var is64CPU = Environment.Is64BitProcess;
在判斷CPU以後,嘗試加載對應的DLL,並調用激活過程。
int retCode = 0; try { retCode = ASFFunctions.ASFActivation(appId, is64CPU ? sdkKey64 : sdkKey32); } catch (Exception ex) { //禁用相關功能按鈕 ControlsEnable(false, chooseMultiImgBtn, matchBtn, btnClearFaceList, chooseImgBtn); if (ex.Message.Contains("沒法加載 DLL")) { MessageBox.Show("請將sdk相關DLL放入bin對應的x86或x64下的文件夾中!"); } else { MessageBox.Show("激活引擎失敗!"); } return; }
虹軟SDK須要激活才能使用,在激活時,必須保證你的設備能夠鏈接到互聯網。若是沒法鏈接會激活失敗。
接下來的代碼,對於引擎的功能進行配置,在大多數狀況下,咱們保持默認配置便可。若是須要調整,能夠重點關注下面的參數
//人臉在圖片中所佔比例,若是須要調整檢測人臉尺寸請修改此值,有效數值爲2-32 int detectFaceScaleVal = 16; //最大須要檢測的人臉個數 int detectFaceMaxNum = 5;
detectFaceScaleVal 爲人臉佔用圖片的比例,簡單的說,就是一張臉在圖片中的比例,這個數值越大,可以檢測到的人臉越小。detectFaceMaxNum 就是檢測到的最大人臉數,檢測人臉越多,程序須要佔用的內存也就越多。
接下來的參數combinedMask,定義了引擎的能力,建議默認保持全開,若是對性能有所要求,能夠只開啓必要的功能。
//引擎初始化時須要初始化的檢測功能組合 int combinedMask = FaceEngineMask.ASF_FACE_DETECT | FaceEngineMask.ASF_FACERECOGNITION | FaceEngineMask.ASF_AGE | FaceEngineMask.ASF_GENDER | FaceEngineMask.ASF_FACE3DANGLE;
調用 ASFFunctions.ASFInitEngine 就能夠初始化引擎
retCode = ASFFunctions.ASFInitEngine(detectMode, imageDetectFaceOrientPriority, detectFaceScaleVal, detectFaceMaxNum, combinedMask, ref pImageEngine);
retCode返回值爲0時表明初始化成功。
按照相同的方法初始化其它引擎,包括 人臉檢測FR引擎,RGB專用FR引擎,IR專用RGB引擎,它們只是參數不一樣,在實際使用中,咱們能夠根據須要進行微調。
其它相似的操做,能夠在此頁面中查看,因爲虹軟Demo已經對操做進行了詳細的封裝,展示在FaceForm.cs中的代碼都是一些和控件交互的代碼,再詳細分析意義並不大,接下來咱們分析一些比較細緻的代碼,也就是潛藏在FaceUtil類中的一些函數的實現.
檢測人臉信息有兩種方式,從照片中檢測和從視頻中檢測,先看從照片中檢測
public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, Image image) { lock (locks) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); if (image != null) { /*若是照片大小過大,則進行縮放並對齊*/ if (image.Width > 1536 || image.Height > 1536) { image = ImageUtil.ScaleImage(image, 1536, 1536); } else { /*若是照片大小正常,直接進行對齊*/ image = ImageUtil.ScaleImage(image, image.Width, image.Height); } if(image == null) { return multiFaceInfo; } /*轉化爲SDK專用格式,後面須要手工釋放內存*/ ImageInfo imageInfo = ImageUtil.ReadBMP(image); if(imageInfo == null) { return multiFaceInfo; } /*調用引擎*/ multiFaceInfo = DetectFace(pEngine, imageInfo); /*釋放圖片佔用的內存*/ MemoryUtil.Free(imageInfo.imgData); return multiFaceInfo; } else { return multiFaceInfo; } } }
注意上述代碼中兩個比較重要的 ScaleImage 和 ReadBMP 方法,其中ScaleImage方法是將圖片處理成虹軟人臉引擎建議的格式,須要圖片的寬度爲4的整數倍。
public static ImageInfo ReadBMP(Image image) { ImageInfo imageInfo = new ImageInfo(); Image<Bgr, byte> my_Image = null; try { //圖像灰度轉化 my_Image = new Image<Bgr, byte>(new Bitmap(image)); imageInfo.format = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8; imageInfo.width = my_Image.Width; imageInfo.height = my_Image.Height; imageInfo.imgData = MemoryUtil.Malloc(my_Image.Bytes.Length); MemoryUtil.Copy(my_Image.Bytes, 0, imageInfo.imgData, my_Image.Bytes.Length); return imageInfo; } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (my_Image != null) { my_Image.Dispose(); } } return null; }
這裏須要注意,此方法中調用了 MemoryUtil.Malloc 方法分配了非託管內存,在後面須要調用 MemoryUtil.Free() 方法釋放內存。
檢測結果返回爲 ASF_MultiFaceInfo 結構體,其中的faceRects 爲人臉結果集,faceNum 爲人臉數目,經過下面的代碼,可獲得人臉識別的位置信息
MRECT rect = MemoryUtil.PtrToStructure<MRECT>(multiFaceInfo.faceRects);
FaceUtil類中還提供了 年領檢測和性能檢測的方法。AgeEstimation和GenderEstimation,其基本操做方式也是先申請內存,而後調用原生的Native的對應方法,再釋放內存的過程。
public static ASF_AgeInfo AgeEstimation(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out int retCode) { retCode = -1; IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_MultiFaceInfo>()); MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { return new ASF_AgeInfo(); } //人臉信息處理 retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_AGE); if (retCode == 0) { //獲取年齡信息 IntPtr pAgeInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_AgeInfo>()); retCode = ASFFunctions.ASFGetAge(pEngine, pAgeInfo); Console.WriteLine("Get Age Result:" + retCode); ASF_AgeInfo ageInfo = MemoryUtil.PtrToStructure<ASF_AgeInfo>(pAgeInfo); //釋放內存 MemoryUtil.Free(pMultiFaceInfo); MemoryUtil.Free(pAgeInfo); return ageInfo; } else { return new ASF_AgeInfo(); } }
須要注意的是,要使用性別和年齡檢測,必須在人臉檢測SDK初始化的時候開啓對應的功能,也就是說combinedMask值中必須包含 FFaceEngineMask.ASF_AGE |FaceEngineMask.ASF_GENDER;
上一步獲取人臉框後,就能夠調用人臉識別引擎獲取人臉特徵信息了,將照片信息傳入人臉識別引擎,返回人臉模型信息
IntPtr pFaceModel = ExtractFeature(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo);
咱們來看看 ExtractFeature 方法,這裏的Demo寫的比較複雜,並且幾個方法都是同名的方法,咱們來詳細分析一下
首先找到IntPtr ExtractFeature(IntPtr pEngine, Image image, out ASF_SingleFaceInfo singleFaceInfo)
方法.
因爲人臉識別的第一步是先檢測到人臉框的位置,所以這個方法就是對傳入的圖片進行一個預先處理的分析,而且調用了人臉檢測的方法檢測人臉。
.... 其它代碼,主要是對傳入圖片進行分析,轉換大小,若是爲空或者圖片不合法,直接返回空的特徵。 ASF_MultiFaceInfo multiFaceInfo = DetectFace(pEngine, imageInfo); singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr pFaceModel = ExtractFeature(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo); return pFaceModel;
咱們按照調用順序看一下 IntPtr ExtractFeature(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out ASF_SingleFaceInfo singleFaceInfo)
方法,
public static IntPtr ExtractFeature(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out ASF_SingleFaceInfo singleFaceInfo) { /*定義要返回的單我的臉信息結構體*/ singleFaceInfo = new ASF_SingleFaceInfo(); /*若是沒有人臉框,直接返回空特徵*/ if (multiFaceInfo.faceRects == null) { ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return pEmptyFeature; } /*將FaceDetect中的人臉框和人臉角度賦值到out對象*/ singleFaceInfo.faceRect = MemoryUtil.PtrToStructure<MRECT>(multiFaceInfo.faceRects); singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure<int>(multiFaceInfo.faceOrients); /*將單我的臉對象轉化成非託管結構體*/ IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_SingleFaceInfo>()); MemoryUtil.StructureToPtr(singleFaceInfo, pSingleFaceInfo); IntPtr pFaceFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_FaceFeature>()); /*調用人臉識別接口提取人臉特徵*/ int retCode = ASFFunctions.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); Console.WriteLine("FR Extract Feature result:" + retCode); if (retCode != 0) { /*異常處理,注:因爲使用了非託管對象,須要釋放內存*/ MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return pEmptyFeature; } //處理返回值,這裏又是一堆互操做訪問 ASF_FaceFeature faceFeature = MemoryUtil.PtrToStructure<ASF_FaceFeature>(pFaceFeature); byte[] feature = new byte[faceFeature.featureSize]; MemoryUtil.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize); ASF_FaceFeature localFeature = new ASF_FaceFeature(); localFeature.feature = MemoryUtil.Malloc(feature.Length); MemoryUtil.Copy(feature, 0, localFeature.feature, feature.Length); localFeature.featureSize = feature.Length; IntPtr pLocalFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_FaceFeature>()); MemoryUtil.StructureToPtr(localFeature, pLocalFeature); //最後,別忘記釋放內存 MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); /*返回提取到的人臉特徵數據*/ return pLocalFeature; }
人臉檢索時要先創建本地人臉素材庫,上一步提取到的人臉特徵是一串二進制的數據,實際使用時,咱們能夠將特徵存儲到數據庫或者本地文件中,Demo爲了演示方便,直接放置在imagesFeatureList變量中.
在進行人臉檢索時,獲取到了待檢索的人臉特徵後,調用ASFFunctions.ASFFaceFeatureCompare
方法就能夠完成檢索了。
for (int i = 0; i < imagesFeatureList.Count; i++) { IntPtr feature = imagesFeatureList[i]; float similarity = 0f; int ret = ASFFunctions.ASFFaceFeatureCompare(pImageEngine, image1Feature, feature, ref similarity); //增長異常值處理 if(similarity.ToString().IndexOf("E") > -1) { similarity = 0f; } AppendText(string.Format("與{0}號比對結果:{1}\r\n", i, similarity)); imageList.Items[i].Text = string.Format("{0}號({1})", i, similarity); if (similarity > compareSimilarity) { compareSimilarity = similarity; compareNum = i; } }
ASFFunctions.ASFFaceFeatureCompare 方法實際上調用的是SDK的對應方法,其返回值 simiarity爲類似度。
Demo將獲取到的人臉和人臉庫中全部人臉都進行了對比,找出最爲接近的一個特徵。
在實際應用中,若是找到了一個符合咱們置信度要求的特徵,就能夠直接退出循環了。
小提示:在實際應用中,若是人臉庫的基數很大,能夠開啓多個FR實例進行檢索,也能夠啓用人臉檢測中的 性別 ,年齡數據縮小查詢的範圍
若是說從照片中檢測人臉是人臉識別的基礎,那麼從視頻中檢測人臉則人臉識別最爲實際的應用,實際的人臉實時檢測系統都是基於視頻檢測的,活體檢測也是基於視頻模式下的人臉檢測。
簡單說來講,從視頻中檢測人臉的方式就是從視頻中抓取包含人臉的幀並分析識別的過程。在FaceForm的videoSource_Paint
方法中對這一過程進行了詳細的描述。
從攝像頭(RGB攝像頭)中抓取一幀 調用適用於視頻的人臉檢測引擎,檢測到人臉 根據返回的人臉位置畫人臉框,利用上一幀的檢測結果標識識別到的人臉信息 根據返回的人臉信息調用活體檢測功能 判斷是活體的狀況下調用人臉識別引擎提取人臉特徵 將人臉特徵和人臉庫的信息進行匹配 記錄結果 等待捕獲下一幀
第一個要注意的點是pVideoEngine
ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pVideoEngine, bitmap);
這個pVideoEngine是首先,是視頻模式下的人臉檢測引擎,它是在InitEngines()方法中啓用的
uint detectModeVideo = DetectionMode.ASF_DETECT_MODE_VIDEO; int combinedMaskVideo = FaceEngineMask.ASF_FACE_DETECT | FaceEngineMask.ASF_FACERECOGNITION; retCode = ASFFunctions.ASFInitEngine(detectModeVideo, videoDetectFaceOrientPriority, detectFaceScaleVal, detectFaceMaxNum, combinedMaskVideo, ref pVideoEngine);
這裏調用的是pVideoEngine,和基於圖片的pImageEngine使用的是不一樣的引擎,兩個引擎的區別是pVideoEngine在初始化的時候,使用的是視頻模式,在視頻檢測的場景下,建議使用視頻模式,在基於圖片處理的狀況下,建議使用圖像模式。
這裏由於 視頻(攝像頭)狀況下 ,每秒產生數據有25-30幀,因爲算法實現上的不一樣,每秒只能作20次左右的圖像模式的檢測,因此視頻狀況下,用圖像模式來作人臉檢測是不適合的,由於算力不夠;但視頻模式能夠每秒運行100次 ,並且在2.2版本,視頻模式還增長了TrackID參數輸出,更容易判斷同一我的。而單張圖片檢測狀況下,通常都採用圖像模式來作人臉檢測,圖像模式的檢測更爲細緻,並且對多人臉和大圖片的支持較好,因爲是單張檢測,圖片模式的性能也不存在問題,通常狀況1s內作5-10張就知足產品要求了。
這裏須要注意的一點,Demo中也指出來了,必定要保證同一時刻只檢測一幀,不能同時檢測多幀,以避免頁面在顯示時出現卡頓。另外,提取特徵值和信息比對是比較耗時的,須要另外開線程以免主線程界面的卡頓。
目前經常使用的活體識別算法主要有 交互式 活體檢測和非交互式的兩種方式,咱們在登陸支付寶時候張張嘴,搖搖頭都屬於交互式,若是不須要其它動做,就屬於非交互式,虹軟的SDK針對識別攝像頭的不一樣,提供了基於RGB攝像頭和基於紅外深度攝像頭的兩種非交互算法。
只需單目RGB攝像頭便可完成硬件搭設成本低,靜默識別無需用戶動做配合,只須要普通的攝像頭就能夠。人性化程度高,應用場景普遍
經過紅外成像原理(屏幕沒法成像、不一樣材質反射率不一樣等)以及深度學習算法,實現高魯棒性的活體判斷,靜默式識別,可有效防護圖片、視頻、屏幕、面具等攻擊,可知足雙目人臉識別終端產品活體檢測應用
有一個簡單判斷,若是你的攝像頭只一個一個彩色鏡頭,沒有IR紅外鏡頭,那麼就可使用RGB活體,若是你的是雙目攝像頭,而且一個是紅外的,那麼就可使用IR活體,從可信度上來講,IR活體的可信度更多,但須要專用的設備。
虹軟SDK在2.1以前的版本中,只提供了RGB活體檢測功能,若是你須要使用IR活體檢測功能,須要使用2.2版本的SDK。
虹軟的活體檢測內置於FR(面部識別)引擎之中,要使用活體檢測功能,就必須先啓用它,在Demo的InitEngines()方法中,咱們能夠看到關於FR引擎初始化的方法.
根據使用攝像頭不一樣,啓用不一樣的活體檢測引擎,下面這段代碼啓用了RGB模式的FR引擎
//RGB視頻專用FR引擎 detectFaceMaxNum = 1; combinedMask = FaceEngineMask.ASF_FACE_DETECT | FaceEngineMask.ASF_FACERECOGNITION | FaceEngineMask.ASF_LIVENESS; retCode = ASFFunctions.ASFInitEngine(detectMode, imageDetectFaceOrientPriority, detectFaceScaleVal, detectFaceMaxNum, combinedMask, ref pVideoRGBImageEngine);
其中FaceEngineMask.ASF_LIVENESS
爲普通的RGB活體,若是是紅外雙射,則爲FaceEngineMask.ASF_IR_LIVENESS
進行人臉檢測的最好時機是在分析人臉特徵以前,抓取到人臉框以後,這個時候只須要調用faceUtil的LivenessInfo_RGB方法就能夠。其返回的liveInfo中isLive是否爲一判斷是否活體。
LivenessInfo_RGB 在內部調用了SDK的ASFProcess 方法
retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_LIVENESS); if (retCode == 0) { //獲取活體檢測結果 IntPtr pLivenessInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf<ASF_LivenessInfo>()); retCode = ASFFunctions.ASFGetLivenessScore(pEngine, pLivenessInfo); Console.WriteLine("Get Liveness Result:" + retCode); ASF_LivenessInfo livenessInfo = MemoryUtil.PtrToStructure<ASF_LivenessInfo>(pLivenessInfo); //釋放內存 MemoryUtil.Free(pMultiFaceInfo); MemoryUtil.Free(pLivenessInfo); return livenessInfo; }
其返回值livenessInfo 中的 isLive 定義了人臉活體的結果,當爲1時爲活體,爲-1時爲假體,程序判斷爲假體後,就再也不進行特徵提取和匹配的動做了。
待補充。。。
在C#程序中,咱們常常和託管內存打交道,常用new 來新建對象。可是虹軟提供的SDK是基於原生代碼的,採用C語言編寫,其在使用時須要分配和使用非託管內存,參數也使用C的結構體類型,爲了方便使用,Demo程序提供了MemoryUtil類,它經過對Marshal類相應方法的封裝,提供了直接調用C方法的便捷使用方式.
在使用Demo代碼編寫本身的程序時,要注意到有些FaceUtils的方法調用了Malloc方法分配了內存,但沒有釋放內存,而是在其它的方法中釋放.有一個非託管內存管理原則很重要:調用Marshal.AllocHGlobal必須調用 Marshal.FreeHGlobal(ptr)來手動釋放內存,即便調用GC.Collect();方法也沒法釋放,致使內存泄露。
Marshal 類是.net 互操做訪問中須要使用到的最重要的一個類,它提供了一個方法集合,這些方法用於分配非託管內存、複製非託管內存塊、將託管類型轉換爲非託管類型,此外還提供了在與非託管代碼交互時使用的其餘雜項方法。具體能夠參考MSDN的文檔 https://docs.microsoft.com/zh...
VS不一樣版本對於DLL的放置有必定的要求,選擇程序的CPU類型也會影響到最終DLL的使用,通常來講,若是 使用的是32位程序,就放入x86文件夾,若是是x64就放64文件夾。
2.2版本的SDK在首次使用時,須要自動聯網激活,所以,請在首次使用時,鏈接互聯網。
若是在啓動程序時報90118設備不匹配,一般是硬件信息發生了變化,這時候只須要刪除SDK目錄下面的ArcFace32.dat或者ArcFace64.dat文件,SDK在檢測不到這個文件會自動聯網激活。
這個固然是能夠的,咱們能夠根據官方的Demo按照本身的業務邏輯改形成asp.net 應用或者WPF應用。
Demo已經對大部的功能進行了封裝,在瞭解業務邏輯以後,能夠直接使用FaceUtil中的方法。不過當使用WPF或者asp.net時,可能會遇到堆棧內存不足,這是由於.net默認的堆棧大小爲256K或者如下,而SDK須要使用512KB以上。只須要在新建線程時調整堆棧大小就能夠解決了,參見下面的方法
new Thread(new ThreadStart(delegate { ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pEngine, imageInfo); }), 1024 * 512).Start();
虹軟開放平臺論壇提供了官方的信息交流平臺,能夠訪問https://ai.arcsoft.com.cn/bbs/index.php 瞭解更多信息,上面有技術人員蹲守解決你的問題,若是你有好的Demo須要分享給其它小夥伴兒,也能夠在論壇中上傳你的做品。