日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

人脸识别Demo解析C#

發布時間:2023/12/10 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 人脸识别Demo解析C# 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

不管你注意到沒有,人臉識別已經走進了生活的角角落落,釘釘已經支持人臉打卡,火車站實名認證已經增加了人臉自助驗證通道,更別提各個城市建設的『智能城市』和智慧大腦了。在人臉識別業界,通常由人臉識別提供商和人臉識別應用接入方組成,從頭到尾研發人臉識別技術需要極強的專用技術知識和數學算法功底,對于大多數企業來說,選擇人工智能AI公司現成的人臉識別技術引擎是一個比較適合的解決方法。虹軟公司在2017年開放了人臉識別平臺1.0版本,經過三年的技術迭代和更新,目前已經推出了2.2版本,主打離線,免費,適合場景比較廣泛。為了方便開發者接入,虹軟官方提供了各個語言版本的Demo程序,由于虹軟并沒有提供C#版本的SDK,因此,他們提供的C#版本的SDK就更有參考價值了。

虹軟Demo的下載地址如下:https://github.com/ArcsoftEscErd/ArcfaceDemo_CSharp_2.2 在開始之前,建議你下載它。

什么是人臉識別

人臉識別,是基于人的臉部特征信息進行身份識別的一種生物識別技術。用攝像機或攝像頭采集含有人臉的圖像或視頻流,并自動在圖像中檢測和跟蹤人臉,進而對檢測到的人臉進行臉部識別的一系列相關技術,通常也叫做人像識別、面部識別。
而人臉識別的過程可以簡的概括為:檢測人臉框->提取人臉特征信息->人臉庫檢索匹配信息三個過程。

人臉識別的應用場景

人臉識別主要用于身份識別。由于視頻監控正在快速普及,眾多的視頻監控應用迫切需要一種遠距離、用戶非配合狀態下的快速身份識別技術,以求遠距離快速確認人員身份,實現智能預警。人臉識別技術無疑是最佳的選擇,采用快速人臉檢測技術可以從監控視頻圖象中實時查找人臉,并與人臉數據庫進行實時比對,從而實現快速身份識別。
在現實生活中,從最常見的人臉門禁,到實名制安檢,景區驗票,公司或者學校的人臉簽到,無人超市等都有廣泛的應用。

什么是活體檢測

活體檢測檢測顧名思義就是通過識別活體上的生理信息,來區分用照片、硅膠、塑料等非生命物質偽造的生物特征。人臉識別應用中的活體檢測技術用來判斷系統采集到的人臉圖像是否來源于真實的人臉,以防止照片、視頻等偽造的人臉圖像被輸入到系統造成誤判,活體檢測在無人值守場景下的人臉識別商業應有中顯得至關重要。

虹軟人臉識別SDK

目前市面上有很多人臉識別技術方案,從是否需要使用時聯網可以分為在線和離線,從接入方式上可以分為本地識別和服務器大數據識別等方式,虹軟提供的是基于本地算法特征的離線識別SDK,其基礎算法使用C編寫,提供全平臺的離線支持.

虹軟視覺視覺開放平臺

虹軟人臉識別SDK通過視覺開放平臺提供,包含人臉識別場景中最常用到的功能組件,例如:人臉檢測,人臉識別,年齡性別檢測,活體檢測 等,其中人臉檢測針對靜態和動態檢測場景分別進行了算法優化,從中派生的性別和年齡檢測擴充了人臉識別的使用場景,活體檢測組件可以有效的保證人臉識別應用的安全性。
訪問 https://ai.arcsoft.com.cn/third/mobile.html?csdn 按照網站的提示,可以注冊用戶和下載SDK包。

虹軟的人臉識別Demo簡介

虹軟的SDK,和大量基于Restful風格的接口不同,沒有使用普通的基于HTTP的方式,也并沒有提供C#語言的SDK包,僅提供了C語言的SDK,對于C#接入有一定的困難,在發布之初有不少大神自行編寫接入Demo程序,后來,虹軟官方也出了Demo程序,從2018年1月的第一個版本到現在隨著SDK更新的2.2版本,代碼結構和注釋更為清晰。

Demo效果展示

Demo是標準的C# WINFORM工程樣式,通過GitHub,下載下來之后,可以直接使用VS打開.
打開之后,有一個readme.md文件,十分重要,在開始之前,請務必仔細看一下。這里把要點給大家總結一下。

  • 注冊并登錄虹軟開發者賬號,下載Win32/Win64的ArcFace的SDK,建議下載2.2版本的。
  • 將下載時生成的APPID和KEY填放app.config文件中的對應位置。
  • 將下載的文件解壓,根據本平臺將dll解壓到對應平臺的目錄下面
    如果上述幾步都OK,程序可以正常運行,如果中間有問題,可以參考readme中的內容進行排查。
  • 一般OK之后,系統彈出正常運行的窗口,網上找幾張明星照片進行注冊,對比。
    如下圖所示:

    可以看到,虹軟Demo已經可以正確的識別人臉信息。

    Demo中還提供了活體檢測功能,如果你的機器沒有攝像頭,可以外插一個USB的攝像頭,點擊啟用攝像頭,打開它。

    如果我們用自己的人臉識別,會顯示RGB活體,如果是用照片或者視頻嘗試識別,會顯示『RGB假體』

    人臉識別Demo代碼解析

    接下來進入正題,讓我們打開工程視圖,從代碼角度解析一下虹軟人臉識別Demo的代碼結構及主要流程。

    從上圖中可以發現代碼結構還是很清晰

    目錄說明
    Entity用于放置一些實體類
    lib放置的第三庫,主要是用于獲取視頻幀的內容
    SDKModelsSDK的字段模型類,主要是和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-32int 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活體

    只需單目RGB攝像頭即可完成硬件搭設成本低,靜默識別無需用戶動作配合,只需要普通的攝像頭就可以。人性化程度高,應用場景廣泛

    IR活體

    通過紅外成像原理(屏幕無法成像、不同材質反射率不同等)以及深度學習算法,實現高魯棒性的活體判斷,靜默式識別,可有效防御圖片、視頻、屏幕、面具等攻擊,可滿足雙目人臉識別終端產品活體檢測應用

    有一個簡單判斷,如果你的攝像頭只一個一個彩色鏡頭,沒有IR紅外鏡頭,那么就可以使用RGB活體,如果你的是雙目攝像頭,并且一個是紅外的,那么就可以使用IR活體,從可信度上來說,IR活體的可信度更多,但需要專用的設備。

    虹軟SDK在2.1之前的版本中,只提供了RGB活體檢測功能,如果你需要使用IR活體檢測功能,需要使用2.2版本的SDK。

    RGB活體接口解析

    虹軟的活體檢測內置于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時為假體,程序判斷為假體后,就不再進行特征提取和匹配的動作了。

    IR活體接口解析

    待補充。。。

    問題及解決思路分享

    非托管內存的管理與內存溢出

    在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-cn/dotnet/api/system.runtime.interopservices.marshal?redirectedfrom=MSDN&view=netframework-4.8#methods

    找不到dll

    VS不同版本對于DLL的放置有一定的要求,選擇程序的CPU類型也會影響到最終DLL的使用,一般來說,如果 使用的是32位程序,就放入x86文件夾,如果是x64就放64文件夾。

    激活失敗

    2.2版本的SDK在首次使用時,需要自動聯網激活,因此,請在首次使用時,連接互聯網。
    如果在啟動程序時報90118設備不匹配,通常是硬件信息發生了變化,這時候只需要刪除SDK目錄下面的ArcFace32.dat或者ArcFace64.dat文件,SDK在檢測不到這個文件會自動聯網激活。

    Demo中的代碼可以在WPF或者Asp.net中使用嗎

    這個當然是可以的,我們可以根據官方的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需要分享給其它小伙伴兒,也可以在論壇中上傳你的作品。

    總結

    以上是生活随笔為你收集整理的人脸识别Demo解析C#的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。