閱讀115 返回首頁    go 阿裏雲 go 技術社區[雲棲]


用100美元攢一個懂人臉識別又能對話的門鈴


0?wx_fmt=png

使用Amazon Echo和樹莓派來自己動手做一個門鈴:每個月僅花費幾分錢就可以識別在你門口成千上萬的訪客。

最近我準備在新房子裏安裝一個門鈴時想到:為什麼不讓我的門鈴告訴我誰在門口?

我自己動手做的大部分項目的成本都高於其它同等產品,即便我已經把自己的時間價值定為每小時0美元。我想這可能是跟供應鏈和經濟規模相關。但是我在自己製作這些東西的過程中得到了更多的樂趣。在這個項目中我攢了一個門口攝像頭,它不僅比我的Dropcam便宜而且還有一些真正有用的功能,由於某些原因這些功能我在市場還沒有見到過。

0?wx_fmt=jpeg

圖1 我的前門有一個門鈴、一個August鍵盤鎖和一個用於人臉識別的樹莓派。圖片由Lukas Biewald提供

我們會攢一個成本60美元的基於樹莓派的安全攝像頭裝置,用來拍攝照片並將其傳到雲端然後進行人臉識別。你還可以將數據流上傳到Amazon S3,使其成為一個完整的Dropcam替代品。Nest為保存最近10天的視頻每年會收取100美元,但你可以隻花費大約20美元在S3中保留一年的視頻文件。如果你使用Amazon Glacier,這筆費用將會降到4美元左右。


使用Amazon ReKognition進行機器學習


本教程會重點關注機器學習的部分——使用亞馬遜新的Rekogniction服務來對你的訪客進行人臉識別,然後將識別結果發送到你的Amazon Echo,這樣你就可以始終知道誰在你的門口了。為了構建可靠的服務,我們還會使用Amazon最酷、最有用的產品之一:Lambda。

組成部件:

Amazon Echo Dot(50美元)

樹莓派3代(38美元)(該項目也可以使用樹莓派2代加上無線USB網卡)

樹莓派兼容相機(16美元)

樹莓派保護殼(6美元)

16GB SD卡(8美元)

總計:118美元

我們會使用Amazon的S3、 Lambda和Rekognition 服務來進行人臉匹配。這些服務開始是免費的,之後你每月僅花費幾分錢就可以識別在你門口成千上萬的訪客。


配置樹莓派係統


如果你已經完成了我的任何一篇樹莓派教程,那麼你將會很熟悉這篇教程的大部分內容。

首先從樹莓派基金會上下載Noobs,並按照安裝說明進行操作。這主要包括將Noobs複製到SD卡上,再將SD卡插到你的板子上,然後將鼠標、鍵盤和顯示器插到你的板子上並按照安裝說明操作。這些操作自從新的桌麵環境Pixel推出以來就變得更容易了。

0?wx_fmt=jpeg

圖2 我桌子上連著微型顯示器和鍵盤的樹莓派。圖片由Lukas Biewald提供

然後將你的樹莓派係統命名成你可以記住的名字,以便你可以SSH訪問它。這在howtogeek上有很好的說明指南——你需要修改/etc/hosts和/etc/hostname文件並給你的樹莓派係統命名。我喜歡將所有的安保攝像頭樹莓派用我最喜歡的電視節目“費城總是晴朗”中的角色來命名,所以我將前門的攝像頭命名為“Dennis”。這意味著我不需要記住一個IP地址就可以隨時SSH訪問到dennis.local,即使重置了路由器也可以。

接下來你應該將攝像頭連接到樹莓派板子上。記住帶狀電纜正麵應該麵向以太網插孔——這個問題我可能已經Google了一百次了。備注:如果你想要一個更廣的視野,你可以買一個廣角攝像頭;如果你想要增加夜視功能,你可以買一個紅外線攝像頭。

0?wx_fmt=jpeg

圖3 準備安裝的帶有攝像頭和外殼的樹莓派。圖片由Lukas Biewald提供

你可能也想把整個裝置都放在一個保護殼中,以保護它免受天氣的影響。你還需要將樹莓派通過微型USB電纜連接到電源。(我已經在牆上鑽了一個小洞將我的Dropcam連接到室內電源插座上,所以我在合適的位置上已經有了一個USB電纜。)

目前為止我已經在房子周圍安裝了幾個這樣的裝置了。相機帶狀電纜很薄,你可以將樹莓派安裝在房間內部,並將電纜就像我在我的實驗室(車庫)裏做的那樣從門上穿過。

0?wx_fmt=jpeg

圖4 樹莓派上的攝像頭從我的車庫門上穿出來。 圖片由Lukas Biewald提供

接下來你需要安裝RPi-Cam-Web界麵。這是一個非常有用的軟件,它通過http協議從攝像頭中提供連續的數據流。請遵循安裝說明,並選擇NGINX作為Web服務器。在/etc/raspimjpeg中有一個非常有用的配置文件可以用來配置大量選項。


配置Amazon S3和Amazon Rekognition


如果你尚未創建AWS賬號,則需要現在創建。你應該先創建一個IAM用戶,並讓該用戶可以訪問S3、Rekognition和Lambda(稍後我們會使用Lambda)。

安裝AWS命令行界麵:

sudo apt install awscli

將你的樹莓派的地區設置為美東(截止本文撰寫時間,Rekognition僅在此區域可用)

創建一個人臉識別組:

aws create-collection –collection-id friends

你可以使用我寫的unix shell腳本來快速添加你朋友的人臉圖片:

aws s3 cp $1 s3://doorcamera > output

aws rekognition index-faces \

–image “{\”S3Object\”:{\”Bucket\”:\”doorcamera\”,\”Name\”:\”$1\”}}” \

–collection-id “friends” –detection-attributes “ALL” \

–external-image-id “$2”

將其複製到一個文件中作為shell腳本。或者在命令行裏輸入它,並將$1替換成你朋友圖片的本地文件名,把$2換成你朋友的名字。

Amazon的 Rekognition服務使用機器學習來得到人臉圖片上點與點之間的距離,然後使用這些點來匹配其索引中的人臉圖像。因此你可以僅使用你朋友的一張圖像來訓練係統就可能得到很好的結果。

現在你可以用類似的腳本來測試這個人臉識別係統:

aws s3 cp $1 s3://doorcamera > output

aws rekognition search-faces-by-image –collection-id “friends” \

–image “{\”S3Object\”:{\”Bucket\”:\”doorcamera\”,\”Name\”:\”$2\”}}”

你會得到返回的一個很大的JSON文件,其中不僅僅有匹配結果,還有圖像的其它方麵信息,包括性別、表情、麵部毛發和一堆其它有趣的東西。

{

“FaceRecords”: [

{

“FaceDetail”: {

“Confidence”: 99.99991607666016,

“Eyeglasses”: {

“Confidence”: 99.99878692626953,

“Value”: false

},

“Sunglasses”: {

接下來我們可以編寫一個Python腳本從我們的樹莓派攝像機中下載一個圖片並檢查其中的臉部。實際上我用了第二台樹莓派來實現這一功能,但是運行在同一台機器上會更容易。隻需要查看/dev/shm/mjepg/cam.jpg文件,你就會知道一個所對應的攝像頭的圖像文件。

無論哪種方式,我們需要在Web服務器中暴露此接口功能以供後麵使用。我使用Flask作為我的Web服務器。

from flask import Flask, request

import cameras as c

app = Flask(__name__)

@app.route(‘/faces/’)

def face_camera(camera):

data = c.face_camera(camera)

return “,”.join(data)

if __name__ == ‘__main__’:

app.run(host=’0.0.0.0′, port=5000)

我把解析代碼(以及本文提到的所有其它代碼)都放在了github.com/lukas/facerec上。

如果你已經操作到了這一步,你已經能有一些非常有趣的可以用來玩的東西了。我發現Amazon服務在識別我朋友的方麵是極好的。唯一看起來有些麻煩的地方就是識別我的情緒(盡管這可能更多的是我的問題而不是Amazon)。

實際上我將其中一個樹莓派攝像頭縫進了一個毛絨玩具裏,並把一個非常令人毛骨悚然的能進行人臉識別的泰迪熊哨兵放在了我的桌上。

0?wx_fmt=jpeg

圖5 可人臉識別的泰迪熊Freya。圖片由Lukas Biewald提供


人臉識別攝像頭跟Amazon Echo搭配使用


Amazon的Echo使得高品質的語音命令變得非常簡單,並且對這種項目來說有著完美的接口。不幸的是,使用Echo的最好方式是讓它跟一個穩定的Web服務進行直接通信,但是我們想把樹莓派攝像頭放在路由器防火牆後麵的本地網絡——這使得配置有點棘手。

我們將Echo連接到一個AWS Lambda服務上,它會通過SSH通道跟我們的樹莓派係統通信。這可能有點複雜,但這是最簡單的方法。

0?wx_fmt=jpeg

圖6 架構圖。圖片由Lukas Biewald提供


通過SSH 通道暴露HTTP 人臉識別API接口


到目前為止我們已經構建了一個用於人臉識別的小網絡應用,我們還需要讓外部世界可以訪問它。隻要我們在某個地方有一個Web服務器,我們就可以配置一個SSH通道。不過有一個叫做localtunnel的甜美小應用程序為我們做了這一切,你可以輕鬆地安裝它:

npm install -g localtunnel

我喜歡用一個小腳本來包裝一下它,使其處於活動狀態防止它掛掉。請把MYDOMAIN改為對你有意義的內容:

until lt –port 5000 -s MYDOMAIN; do

echo ‘lt crashed… respawning…’

sleep 1

done

現在你可以通過訪問https://MYDOMAIN.localtunnel.me 來ping一下你的服務器。


創建一個Alexa Skill


要使用我們的Echo,我們需要創建一個新的Alexa Skill。Amazon有一個很好的入門指南,或者你可以直接訪問Alexa開發者門戶網站。

首先我們需要設定一個intent:

{

“intents”: [

{

“intent”: “PersonCameraIntent”,

“slots”: [

{

“name”: “camera”,

“type”: “LIST_OF_CAMERAS”

}

]

}]}

然後我們給Alexa一些樣例Utterance:

PersonCameraIntent tell me who {camera} is seeing

PersonCameraIntent who is {camera} seeing

PersonCameraIntent who is {camera} looking at

PersonCameraIntent who does {camera} see

接下我們需要給Alexa一個結束點,為此我們將使用一個Lambda函數。


配置一個Lambda函數


如果你從未使用過Lambda的函數,那本文讓你賺到了!Lambda函數是一種在Amazon服務器上為一個簡單函數定義一個統一API的簡單方法,並隻有在調用時才會付費。

Alexa Skill 是Lambda函數的完美用例,所以Amazon已經配置了一個可用的用於Alexa Skill的模板。當Alexa與我們列出的PersonCameraIntents的其中一項匹配時,它將會調用我們的Lambda函數。將MYDOMAIN改為你的本地通道腳本中使用的域名,這樣一切就會運行的很好。

你還可以使用Amazon Rekognition發送的元數據中的其它有趣之處。例如,它可以猜測麵部表情,所以我通過它去判斷在我門口的是一位開心的訪客還是一個生氣的訪客。你還可以讓Echo告訴你訪客是否有胡子、戴太陽眼鏡和其它一些特征:

def face_camera(intent, session):

card_title = “Face Camera”

if ‘camera’ in intent[‘slots’]:

robot = intent[‘slots’][‘camera’][‘value’]

try:

response = urlopen(‘https://MYDOMAIN.localtunnel.me/faces/%s’ % robot)

data = response.read()

if (data== “Not Found”):

speech_output = “%s didn’t see a face” % robot

else:

person, gender, emotion = data.split(“,”)

if person == “” or person is None:

speech_output = “%s didn’t recognize the person, but ” % robot

else:

speech_output = “%s recognized %s and ” % (robot, person)

if gender == “Male”:

speech_output += “he ”

else:

speech_output += “she ”

speech_output += “seems %s” % emotion.lower()

except URLError as e:

speech_output = “Strange, I couldn’t wake up %s” % robot

except socket.timeout, e:

speech_output = “The Optics Lab Timed out”

else:

speech_output = “I don’t know what robot you’re talking about”

should_end_session = False

return build_response({}, build_speechlet_response(

card_title, speech_output, None, should_end_session))

原文發布時間為:2017-04-20

本文來自雲棲社區合作夥伴“大數據文摘”,了解相關信息可以關注“BigDataDigest”微信公眾號

最後更新:2017-05-17 13:33:08

  上一篇:go  基於數據,牛逼的產品經理是如何為試驗想法排列優先級的?
  下一篇:go  機器學習中的線性代數:關於常用操作的新手指南