引言
如今,基于人臉的技術(shù)和話題可以說(shuō)是炙手可熱,基于大數(shù)據(jù)和人工智能的人臉識(shí)別更是突破了我們的想象力的極限,如果應(yīng)用中不能集成人臉識(shí)別,那就太跟不上潮流了。人臉識(shí)別是一個(gè)算法密集型的項(xiàng)目,如果自行開(kāi)發(fā),需要很深厚的數(shù)學(xué)功底和算法底蘊(yùn),成本較高,我一個(gè)做C#的,自問(wèn)沒(méi)有那么高的水平能夠?qū)懗瞿敲磸?fù)雜的算法,即使能,我們的算法能和其它公司相比嗎。不過(guò)好在現(xiàn)在是一個(gè)互聯(lián)網(wǎng)時(shí)代,自己開(kāi)發(fā)不行,那么使用其它現(xiàn)成的人臉識(shí)別引擎可行嗎?答案當(dāng)然是可行的。
本系列文章就將先從靜態(tài)圖片的人臉檢測(cè)開(kāi)始,逐步講解C#是如何進(jìn)行人臉識(shí)別的。共分為以下四篇
- 人臉識(shí)別入門—靜態(tài)照片人臉檢測(cè)
- 人臉識(shí)別入門—基于視頻的人臉檢測(cè)
- 人臉識(shí)別入門—人臉識(shí)別初應(yīng)用
- 人臉識(shí)別入門—模擬簡(jiǎn)單的門禁系統(tǒng)應(yīng)用
在開(kāi)始之前,我們先來(lái)了解一些人臉識(shí)別的集成方式和基礎(chǔ)知識(shí),為下面的課程做準(zhǔn)備。
選擇人臉識(shí)別引擎的心路歷程
通過(guò)搜索引擎,可以大致確定集成人臉識(shí)別的可選方式有以下幾種
1. 集成WebAPI
目前以百度云,騰訊云為首的互聯(lián)網(wǎng)公司提供了基于WEBAPI的集成方式,可以通過(guò)HTTP的方式提交識(shí)別請(qǐng)求,識(shí)別結(jié)果通過(guò)JSON串的方式返回?;贖TTP的方式識(shí)別人臉是比較慢的,慢的原因在于IO性能,相對(duì)來(lái)講,離線版本的API則能夠充分利用本機(jī)的機(jī)器資源,不用往返于所謂的算法云服務(wù)器,直接在本地就能完成人臉識(shí)別和標(biāo)記工作。
2. 集成SDK
以Face++和訊飛語(yǔ)音為例,這些公司即提供了在線識(shí)別的方式也提供了基于SDK的本地識(shí)別方式。本地識(shí)別的優(yōu)點(diǎn)是速度快,集成度高。而且,作為C#,我們還可以搭建自己的云識(shí)別平臺(tái)。如果采用了WEBAPI的,每一筆請(qǐng)求都需要再經(jīng)過(guò)WEBAPI中轉(zhuǎn),性能上會(huì)大打折扣。
因此,如果我們的項(xiàng)目不需要在互聯(lián)網(wǎng)上訪問(wèn),可以供選擇的只有本地集成SDK一條路了。
收費(fèi) OR 免費(fèi):免費(fèi)最好
軟件的成本包括人力成本和采購(gòu)成本,在考慮成本的時(shí)候,自然會(huì)想到,我們使用的引擎是否收費(fèi)呢?即使收費(fèi)再便宜,一旦流量上來(lái)了,也是一筆不小的開(kāi)支。在做技術(shù)選型的時(shí)候,成本是一個(gè)必須要考慮的因素。有了成本因素,再搜索時(shí),就會(huì)悲劇的發(fā)現(xiàn),在百度排首頁(yè)的那些人臉識(shí)別引擎都不是免費(fèi)的。那么有沒(méi)有免費(fèi)的呢。有,網(wǎng)上搜索,這次使用Google搜索,可以發(fā)現(xiàn),github上有一系列的的人臉識(shí)別開(kāi)源代碼,但經(jīng)過(guò)試用,不太理想。
踏破鐵鞋無(wú)覓處,得來(lái)全不費(fèi)功夫
正在一籌莫展之際,突然今日頭條推送了一條消息,“人臉識(shí)別技術(shù)從此免費(fèi)!虹軟一舉顛覆人工智能“視”界”,踏破鐵鞋無(wú)覓處,得來(lái)全不費(fèi)功夫,這么好的機(jī)會(huì),何不試試呢。
由于當(dāng)時(shí)并不了解虹軟,就是看中了人臉識(shí)別和免費(fèi)去的,后來(lái)重新百度了一下虹軟,發(fā)現(xiàn)這個(gè)公司有點(diǎn)意意思,竟然同時(shí)拿下了OPPO和VIVO,SAMSUNG這三大手機(jī)巨頭的單子,還是有兩把刷子的
下載引擎發(fā)現(xiàn)只C++
想到就要做到,于是趕緊打開(kāi)電腦下載了SDK,吐槽下今日頭條,做新聞不放鏈接太不厚道了。只能百度了,鏈接在這里http://www.arcsoft.com.cn/ai/arcface.html。
可是下載后,傻眼了,不得不說(shuō)虹軟的誠(chéng)意,這次免費(fèi)的SDK可真夠厚道的,包括了人臉識(shí)別,人臉檢測(cè),人臉跟蹤所有的API。不過(guò)美中不足的是,這SDK竟然只有C++版本的,Windows版本不出C#,這虹軟有點(diǎn)不近人情啊。不過(guò)傷心歸傷心,活得還做,沒(méi)有C#,那我們就拿C++的包裹出C#來(lái)用。其實(shí)有了C++就等于有了C#,因?yàn)镃#本身是兼容C++的,可以直接調(diào)用C++的庫(kù)。
如何用C#調(diào)用C++的庫(kù)
那么,如何使用C#調(diào)用C++的庫(kù)呢,C#提供了兩種技術(shù)調(diào)用C++的DLL
- 靜態(tài)調(diào)用(DCOM+)
- 動(dòng)態(tài)調(diào)用(P/Invoke)
我們可以將C或者C++的函數(shù)封裝成COM組件,在C#中調(diào)用時(shí)比較方便,但是COM組件需要注冊(cè),而且多次注冊(cè)可能也會(huì)導(dǎo)致一些問(wèn)題,同時(shí)在處理C或者C++的類型與COM組件的類型轉(zhuǎn)換的時(shí)候也可能有些麻煩
采用動(dòng)態(tài)的方式就是直接用C#調(diào)用C或者C++已經(jīng)寫(xiě)好的動(dòng)態(tài)鏈接庫(kù),這幾種方式相對(duì)而言,P/Invoke要方便一些
** 因此我們選擇P/Invoke的方式**
** P/Invoke是什么*
P/Invoke的全稱是Platform Invoke (平臺(tái)調(diào)用) 它實(shí)際上是一種函數(shù)調(diào)用機(jī)制,通過(guò)P/Invoke我們就可以調(diào)用非托管DLL中的函數(shù) ,實(shí)際上很多NET基類庫(kù)中定義的類 型內(nèi)部部調(diào)用了從Kernel32.dll,User32.dll,gdi32.dll等非托管DLL中導(dǎo)出的函數(shù)。
來(lái)看一個(gè)簡(jiǎn)單的例子
[DllImportAttribute("user32.dll", EntryPoint = "SetCursorPos")] [return: MarshalAsAttribute(UnmanagedType.Bool)] //可寫(xiě)可不寫(xiě),定義如何封送返回參數(shù) public static extern bool SetCursorPos(int X, int Y);
這段代碼的目的就是調(diào)用系統(tǒng)中獲取鼠標(biāo)參數(shù)的方法。
P/INVOKE的過(guò)程
關(guān)于P/Invoke的過(guò)程,我找到了MSDN上的一張圖,如下所示。
P/Invoke示例圖
在使用P/Invoke調(diào)用C/C++方法時(shí),會(huì)依次執(zhí)行以下操作
1 查找包含該函數(shù)的非托管DLL
2 將該非托管DLL加載到內(nèi)存中
3 查找函數(shù)在內(nèi)存中的地址并將其參數(shù)按照函數(shù)的調(diào)用約定壓棧
4 將控制權(quán)轉(zhuǎn)移給非托管函數(shù)
注意:只在第一次調(diào)用函數(shù)時(shí),才會(huì)查找和加載非托管DLL并查找函數(shù)在內(nèi)存中的地址。當(dāng)非托管函數(shù)產(chǎn)生異常時(shí),P/Invoke會(huì)將異常傳遞給托管調(diào)用方
看起來(lái)很復(fù)雜,但使用起來(lái)卻很簡(jiǎn)單,只需要在C#中重新聲明函數(shù)的定義就可以了,然后可以像其它函數(shù)一樣調(diào)用。
注意:只在第一次調(diào)用函數(shù)時(shí),才會(huì)查找和加載非托管DLL并查找函數(shù)在內(nèi)存中的地址。當(dāng)非托管函數(shù)產(chǎn)生異常時(shí),P/Invoke會(huì)將異常傳遞給托管調(diào)用方
看起來(lái)很復(fù)雜,但使用起來(lái)卻很簡(jiǎn)單,只需要在C#中重新聲明函數(shù)的定義就可以了,然后可以像其它函數(shù)一樣調(diào)用。
有關(guān)本系列的全部代碼可以到我的資源中下載,也可以參考https://github.com/smartkids77/ArcSoft_FreeSDK_Demo
中提供的源代碼來(lái)尋找各個(gè)版本的實(shí)現(xiàn),本系列文章就是從這里找到的靈感.
下一篇我們將以項(xiàng)目實(shí)踐的方式來(lái)給大家具體介紹是怎么一步步來(lái)實(shí)現(xiàn)靜態(tài)照片的人臉檢測(cè)的。