C#人臉識別入門篇-STEP BY STEP人臉識別--入門篇

引言

如今,基于人臉的技術(shù)和話題可以說是炙手可熱谭梗,基于大數(shù)據(jù)和人工智能的人臉識別更是突破了我們的想象力的極限忘晤,如果應(yīng)用中不能集成人臉識別,那就太跟不上潮流了激捏。人臉識別是一個(gè)算法密集型的項(xiàng)目设塔,如果自行開發(fā),需要很深厚的數(shù)學(xué)功底和算法底蘊(yùn)远舅,成本較高闰蛔,我一個(gè)做C#的,自問沒有那么高的水平能夠?qū)懗瞿敲磸?fù)雜的算法图柏,即使能序六,我們的算法能和其它公司相比嗎。不過好在現(xiàn)在是一個(gè)互聯(lián)網(wǎng)時(shí)代蚤吹,自己開發(fā)不行例诀,那么使用其它現(xiàn)成的人臉識別引擎可行嗎随抠?答案當(dāng)然是可行的。

本系列文章就將先從靜態(tài)圖片的人臉檢測開始繁涂,逐步講解C#是如何進(jìn)行人臉識別的拱她。共分為以下四篇

1. 人臉識別入門—靜態(tài)照片人臉檢測

2. 人臉識別入門—基于視頻的人臉檢測

3. 人臉識別入門—人臉識別初應(yīng)用

4. 人臉識別入門—模擬簡單的門禁系統(tǒng)應(yīng)用

在開始之前,我們先來了解一些人臉識別的集成方式和基礎(chǔ)知識扔罪,為下面的課程做準(zhǔn)備秉沼。

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

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

1. 集成WebAPI

目前以百度云矿酵,騰訊云為首的互聯(lián)網(wǎng)公司提供了基于WEBAPI的集成方式唬复,可以通過HTTP的方式提交識別請求,識別結(jié)果通過JSON串的方式返回全肮≈迅В基于HTTP的方式識別人臉是比較慢的,慢的原因在于IO性能倔矾,相對來講,離線版本的API則能夠充分利用本機(jī)的機(jī)器資源柱锹,不用往返于所謂的算法云服務(wù)器哪自,直接在本地就能完成人臉識別和標(biāo)記工作。

2. 集成SDK

以Face++和訊飛語音為例禁熏,這些公司即提供了在線識別的方式也提供了基于SDK的本地識別方式壤巷。本地識別的優(yōu)點(diǎn)是速度快,集成度高瞧毙。而且胧华,作為C#,我們還可以搭建自己的云識別平臺宙彪。如果采用了WEBAPI的矩动,每一筆請求都需要再經(jīng)過WEBAPI中轉(zhuǎn),性能上會大打折扣释漆。

因此悲没,如果我們的項(xiàng)目不需要在互聯(lián)網(wǎng)上訪問,可以供選擇的只有本地集成SDK一條路了男图。

收費(fèi) OR 免費(fèi):免費(fèi)最好

軟件的成本包括人力成本和采購成本示姿,在考慮成本的時(shí)候,自然會想到逊笆,我們使用的引擎是否收費(fèi)呢栈戳?即使收費(fèi)再便宜,一旦流量上來了难裆,也是一筆不小的開支子檀。在做技術(shù)選型的時(shí)候,成本是一個(gè)必須要考慮的因素。有了成本因素命锄,再搜索時(shí)堰乔,就會悲劇的發(fā)現(xiàn),在百度排首頁的那些人臉識別引擎都不是免費(fèi)的脐恩。那么有沒有免費(fèi)的呢镐侯。有,網(wǎng)上搜索驶冒,這次使用Google搜索苟翻,可以發(fā)現(xiàn),github上有一系列的的人臉識別開源代碼骗污,但經(jīng)過試用崇猫,不太理想。

踏破鐵鞋無覓處需忿,得來全不費(fèi)功夫

正在一籌莫展之際诅炉,突然今日頭條推送了一條消息,“人臉識別技術(shù)從此免費(fèi)屋厘!虹軟一舉顛覆人工智能“視”界”涕烧,踏破鐵鞋無覓處,得來全不費(fèi)功夫汗洒,這么好的機(jī)會议纯,何不試試呢。

由于當(dāng)時(shí)并不了解虹軟溢谤,就是看中了人臉識別和免費(fèi)去的瞻凤,后來重新百度了一下虹軟,發(fā)現(xiàn)這個(gè)公司有點(diǎn)意意思世杀,竟然同時(shí)拿下了OPPO和VIVO阀参,SAMSUNG這三大手機(jī)巨頭的單子,還是有兩把刷子的

下載引擎發(fā)現(xiàn)只C++

想到就要做到瞻坝,于是趕緊打開電腦下載了SDK结笨,吐槽下今日頭條,做新聞不放鏈接太不厚道了湿镀。只能百度了炕吸,鏈接在這里http://www.arcsoft.com.cn/ai/arcface.html

可是下載后勉痴,傻眼了赫模,不得不說虹軟的誠意,這次免費(fèi)的SDK可真夠厚道的蒸矛,包括了人臉識別瀑罗,人臉檢測胸嘴,人臉跟蹤所有的API。不過美中不足的是斩祭,這SDK竟然只有C++版本的劣像,Windows版本不出C#,這虹軟有點(diǎn)不近人情啊摧玫。不過傷心歸傷心耳奕,活得還做,沒有C#诬像,那我們就拿C++的包裹出C#來用屋群。其實(shí)有了C++就等于有了C#,因?yàn)镃#本身是兼容C++的坏挠,可以直接調(diào)用C++的庫芍躏。

如何用C#調(diào)用C++的庫

那么,如何使用C#調(diào)用C++的庫呢降狠,C#提供了兩種技術(shù)調(diào)用C++的DLL

* 靜態(tài)調(diào)用(DCOM+)

* 動態(tài)調(diào)用(P/Invoke)

我們可以將C或者C++的函數(shù)封裝成COM組件对竣,在C#中調(diào)用時(shí)比較方便,但是COM組件需要注冊榜配,而且多次注冊可能也會導(dǎo)致一些問題否纬,同時(shí)在處理C或者C++的類型與COM組件的類型轉(zhuǎn)換的時(shí)候也可能有些麻煩

采用動態(tài)的方式就是直接用C#調(diào)用C或者C++已經(jīng)寫好的動態(tài)鏈接庫,這幾種方式相對而言,P/Invoke要方便一些

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

* P/Invoke是什么

P/Invoke的全稱是Platform Invoke (平臺調(diào)用) 它實(shí)際上是一種函數(shù)調(diào)用機(jī)制芥牌,通過P/Invoke我們就可以調(diào)用非托管DLL中的函數(shù) ,實(shí)際上很多NET基類庫中定義的類 型內(nèi)部部調(diào)用了從Kernel32.dll聂使,User32.dll壁拉,gdi32.dll等非托管DLL中導(dǎo)出的函數(shù)。

來看一個(gè)簡單的例子

[DllImportAttribute("user32.dll", EntryPoint = "SetCursorPos")]

[return: MarshalAsAttribute(UnmanagedType.Bool)]? //可寫可不寫,定義如何封送返回參數(shù)

public static extern bool SetCursorPos(int X, int Y);

這段代碼的目的就是調(diào)用系統(tǒng)中獲取鼠標(biāo)參數(shù)的方法柏靶。

P/INVOKE的過程

關(guān)于P/Invoke的過程弃理,我找到了MSDN上的一張圖,如下所示屎蜓。

在使用P/Invoke調(diào)用C/C++方法時(shí)痘昌,會依次執(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í),才會查找和加載非托管DLL并查找函數(shù)在內(nèi)存中的地址炬转。當(dāng)非托管函數(shù)產(chǎn)生異常時(shí)辆苔,P/Invoke會將異常傳遞給托管調(diào)用方

看起來很復(fù)雜,但使用起來卻很簡單扼劈,只需要在C#中重新聲明函數(shù)的定義就可以了驻啤,然后可以像其它函數(shù)一樣調(diào)用。

注意:只在第一次調(diào)用函數(shù)時(shí)荐吵,才會查找和加載非托管DLL并查找函數(shù)在內(nèi)存中的地址骑冗。當(dāng)非托管函數(shù)產(chǎn)生異常時(shí)赊瞬,P/Invoke會將異常傳遞給托管調(diào)用方

看起來很復(fù)雜,但使用起來卻很簡單贼涩,只需要在C#中重新聲明函數(shù)的定義就可以了巧涧,然后可以像其它函數(shù)一樣調(diào)用。

有關(guān)本系列的全部代碼可以到我的資源中下載遥倦,也可以參考https://github.com/smartkids77/ArcSoft_FreeSDK_Demo中提供的源代碼來尋找各個(gè)版本的實(shí)現(xiàn)谤绳,本系列文章就是從這里找到的靈感

下一篇我們將以項(xiàng)目實(shí)踐的方式來給大家具體介紹是怎么一步步來實(shí)現(xiàn)靜態(tài)照片的人臉檢測的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谊迄,一起剝皮案震驚了整個(gè)濱河市闷供,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌统诺,老刑警劉巖歪脏,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異粮呢,居然都是意外死亡婿失,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門啄寡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豪硅,“玉大人,你說我怎么就攤上這事挺物±粮。” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵识藤,是天一觀的道長砚著。 經(jīng)常有香客問我,道長痴昧,這世上最難降的妖魔是什么稽穆? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮赶撰,結(jié)果婚禮上舌镶,老公的妹妹穿的比我還像新娘。我一直安慰自己豪娜,他們只是感情好餐胀,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瘤载,像睡著了一般骂澄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惕虑,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天坟冲,我揣著相機(jī)與錄音磨镶,去河邊找鬼。 笑死健提,一個(gè)胖子當(dāng)著我的面吹牛琳猫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播私痹,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼脐嫂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了紊遵?” 一聲冷哼從身側(cè)響起账千,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎暗膜,沒想到半個(gè)月后匀奏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡学搜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年娃善,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瑞佩。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡聚磺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炬丸,到底是詐尸還是另有隱情瘫寝,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布稠炬,位于F島的核電站焕阿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏酸纲。R本人自食惡果不足惜捣鲸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一瑟匆、第九天 我趴在偏房一處隱蔽的房頂上張望闽坡。 院中可真熱鬧,春花似錦愁溜、人聲如沸疾嗅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽代承。三九已至,卻和暖如春渐扮,著一層夾襖步出監(jiān)牢的瞬間论悴,已是汗流浹背掖棉。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膀估,地道東北人幔亥。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像察纯,于是被迫代替她去往敵國和親帕棉。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容