C# 虹軟arcface人臉識別入門篇


引言

如今,基於人臉的技術和話題可以說是炙手可熱,基於大數據和人工智能的人臉識別更是突破了我們的想象力的極限,如果應用中不能集成人臉識別,那就太跟不上潮流了。人臉識別是一個算法密集型的項目,如果自行開發,需要很深厚的數學功底和算法底蘊,成本較高,我一個做C#的,自問沒有那么高的水平能夠寫出那么復雜的算法,即使能,我們的算法能和其它公司相比嗎。不過好在現在是一個互聯網時代,自己開發不行,那么使用其它現成的人臉識別引擎可行嗎?答案當然是可行的。
本系列文章就將先從靜態圖片的人臉檢測開始,逐步講解C#是如何進行人臉識別的。共分為以下四篇
1. 人臉識別入門—靜態照片人臉檢測
2. 人臉識別入門—基於視頻的人臉檢測
3. 人臉識別入門—人臉識別初應用
4. 人臉識別入門—模擬簡單的門禁系統應用

在開始之前,我們先來了解一些人臉識別的集成方式和基礎知識,為下面的課程做准備。

 

選擇人臉識別引擎的心路歷程

通過搜索引擎,可以大致確定集成人臉識別的可選方式有以下幾種

 

1. 集成WebAPI

目前以百度雲,騰訊雲為首的互聯網公司提供了基於WEBAPI的集成方式,可以通過HTTP的方式提交識別請求,識別結果通過JSON串的方式返回。基於HTTP的方式識別人臉是比較慢的,慢的原因在於IO性能,相對來講,離線版本的API則能夠充分利用本機的機器資源,不用往返於所謂的算法雲服務器,直接在本地就能完成人臉識別和標記工作。

 

2. 集成SDK

以Face++和訊飛語音為例,這些公司即提供了在線識別的方式也提供了基於SDK的本地識別方式。本地識別的優點是速度快,集成度高。而且,作為C#,我們還可以搭建自己的雲識別平台。如果采用了WEBAPI的,每一筆請求都需要再經過WEBAPI中轉,性能上會大打折扣。
因此,如果我們的項目不需要在互聯網上訪問,可以供選擇的只有本地集成SDK一條路了。

 

收費 OR 免費:免費最好

軟件的成本包括人力成本和采購成本,在考慮成本的時候,自然會想到,我們使用的引擎是否收費呢?即使收費再便宜,一旦流量上來了,也是一筆不小的開支。在做技術選型的時候,成本是一個必須要考慮的因素。有了成本因素,再搜索時,就會悲劇的發現,在百度排首頁的那些人臉識別引擎都不是免費的。那么有沒有免費的呢。有,網上搜索,這次使用Google搜索,可以發現,github上有一系列的的人臉識別開源代碼,但經過試用,不太理想。

 

踏破鐵鞋無覓處,得來全不費功夫

正在一籌莫展之際,突然今日頭條推送了一條消息,“人臉識別技術從此免費!虹軟一舉顛覆人工智能“視”界”,踏破鐵鞋無覓處,得來全不費功夫,這么好的機會,何不試試呢。


由於當時並不了解虹軟,就是看中了人臉識別和免費去的,后來重新百度了一下虹軟,發現這個公司有點意意思,竟然同時拿下了OPPO和VIVO,SAMSUNG這三大手機巨頭的單子,還是有兩把刷子的

 


下載引擎發現只C++

想到就要做到,於是趕緊打開電腦下載了SDK,吐槽下今日頭條,做新聞不放鏈接太不厚道了。只能百度了,鏈接在這里http://www.arcsoft.com.cn/ai/arcface.html。
可是下載后,傻眼了,不得不說虹軟的誠意,這次免費的SDK可真夠厚道的,包括了人臉識別,人臉檢測,人臉跟蹤所有的API。不過美中不足的是,這SDK竟然只有C++版本的,Windows版本不出C#,這虹軟有點不近人情啊。不過傷心歸傷心,活得還做,沒有C#,那我們就拿C++的包裹出C#來用。其實有了C++就等於有了C#,因為C#本身是兼容C++的,可以直接調用C++的庫。

 

如何用C#調用C++的庫

那么,如何使用C#調用C++的庫呢,C#提供了兩種技術調用C++的DLL
* 靜態調用(DCOM+)
* 動態調用(P/Invoke)
我們可以將C或者C++的函數封裝成COM組件,在C#中調用時比較方便,但是COM組件需要注冊,而且多次注冊可能也會導致一些問題,同時在處理C或者C++的類型與COM組件的類型轉換的時候也可能有些麻煩
采用動態的方式就是直接用C#調用C或者C++已經寫好的動態鏈接庫,這幾種方式相對而言,P/Invoke要方便一些

* 因此我們選擇P/Invoke的方式*

* P/Invoke是什么
P/Invoke的全稱是Platform Invoke (平台調用) 它實際上是一種函數調用機制,通過P/Invoke我們就可以調用非托管DLL中的函數 ,實際上很多NET基類庫中定義的類 型內部部調用了從Kernel32.dll,User32.dll,gdi32.dll等非托管DLL中導出的函數。
來看一個簡單的例子
[DllImportAttribute("user32.dll", EntryPoint = "SetCursorPos")]
[return: MarshalAsAttribute(UnmanagedType.Bool)] //可寫可不寫,定義如何封送返回參數
public static extern bool SetCursorPos(int X, int Y);

這段代碼的目的就是調用系統中獲取鼠標參數的方法。
P/INVOKE的過程
關於P/Invoke的過程,我找到了MSDN上的一張圖,如下所示。

 

在使用P/Invoke調用C/C++方法時,會依次執行以下操作
1 查找包含該函數的非托管DLL
2 將該非托管DLL加載到內存中
3 查找函數在內存中的地址並將其參數按照函數的調用約定壓棧  
4 將控制權轉移給非托管函數
注意:只在第一次調用函數時,才會查找和加載非托管DLL並查找函數在內存中的地址。當非托管函數產生異常時,P/Invoke會將異常傳遞給托管調用方
看起來很復雜,但使用起來卻很簡單,只需要在C#中重新聲明函數的定義就可以了,然后可以像其它函數一樣調用。

注意:只在第一次調用函數時,才會查找和加載非托管DLL並查找函數在內存中的地址。當非托管函數產生異常時,P/Invoke會將異常傳遞給托管調用方
看起來很復雜,但使用起來卻很簡單,只需要在C#中重新聲明函數的定義就可以了,然后可以像其它函數一樣調用。

有關本系列的全部代碼可以到我的資源中下載,也可以參考https://github.com/smartkids77/ArcSoft_FreeSDK_Demo 中提供的源代碼來尋找各個版本的實現,本系列文章就是從這里找到的靈感
下一篇我們將以項目實踐的方式來給大家具體介紹是怎么一步步來實現靜態照片的人臉檢測的。
本教程人臉識別的Demo,可以到下面的地址下載
http://download.csdn.net/download/feishixin/9942684
設置為1分,下載后評論可以返回1分。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM