200美元“造”出一臺可由語音控制外加能進行人臉識別的自主飛行無人機
繼“如何用100美元和TensorFlow來造一個能‘看’東西的機器人” 之後,Lukas又一最新力作。
結合深度學習和便宜硬體的更多探奇。
在“造”出能進行物體識別的機器人後,下一步就很清晰了,我要“造”一個能飛的東西!我決定搞一個能自主飛行的無人機,並要它能識別人臉和響應語音指令。
選擇一臺成品無人機
開始“黑入”一臺無人機的最難的部分就是如何開始。我最初的選擇是用零件組裝一臺無人機。但和我完成的大部分的DIY專案一樣,從零開始一般都耗費了太多的時間,還不如直接買一個成品。實話實說,我自己組裝的無人機從來沒有正常的飛行過。而買一臺成品機就既省事又省錢。
絕大部分無人機廠商都宣稱提供API介面,但對於業餘玩家來說就沒有一個明確的最佳選擇。大部分能提供貌似可用的API介面的無人機都要超過1000美元。這對於入門級的玩家來說就太貴了。
但經過搜尋,我發現Parrot AR 無人機2.0版(見圖1)是一個低端可“黑”入無人機的極佳選擇。新的售價是200美元,不過很多人在買了以後就不怎麼再玩了,所以在eBay上花130美元或更少就能買到一個不錯的二手貨。
圖1:我車庫裡的無人機收藏。最左邊的就是Parrot AR無人機。圖片由Lukas Biewald授權使用
論飛行穩定性,Parrot AR型不如更貴的Parrot Bebop 2型(550美元)。但是Parrot AR型所帶的叫node-ar-drone的node.js客戶端庫是非常好用的。
Parrot AR型的另外一個優點是它非常皮實、耐摔。在測試自主飛行程式碼的時候,我的無人機頻繁地撞到牆、傢俱、植物甚至是我們家的客人,並墜落。但它還是依舊能正常飛行。
比起“造”能在地上跑的機器人,“造”無人機最不爽的一點就是它的電池可用時間太短了。基本上是充電幾小時,飛行十幾分鍾。所以我建議多買兩塊電池,迴圈充電使用。
給我的無人機開發程式
我經過實踐發現,Javascript內在的事件驅動的特性使得它成為一種非常好的控制無人機的語言。請相信我,無人機飛行的時候,是有非常多的非同步事件發生。我寫Node.JS的時間並不長,但在這個專案過程中,我對它的印象非常深刻。上一次我正兒八經地為機器人寫程式用的是C語言。處理C語言的執行緒和異常是一件非常讓人頭疼的事,所以我儘量避免再使用它。我希望有人能為其他的機器人平臺開發出JavaScript的介面,因為這會讓為機器人開發程式(完全無法預知會發生什麼事)變得更簡單更有趣。
架構設計
我決定在我的筆記本上執行控制邏輯,同時在雲端執行機器學習的部分。這種架構設計比在樹莓派板上直接執行神經網路的延遲要低。我認為這種架構對於業餘無人機專案而言是合適的。
微軟、谷歌、IBM和亞馬遜都提供快速且便宜的機器學習API。最終我選擇了微軟的認知服務API來完成這個專案,因為它是唯一提供定製化的人臉識別功能的API。
圖2裡展示了整個無人機專案的系統架構。
圖2:智慧無人機的系統架構。圖片由Lukas Biewald授權使用
開始動手
預設地,Parrot AR無人機2.0版自己可以提供一個無線網路,供客戶端接入,但是這個功能卻極度煩人。每次你要實驗點東西,你都需要從本地網路斷開,再連到無人機的無線網裡。好訊息是,有一個叫ardrone-wpa2的專案,非常有用,用它你可以“黑”進無人機,並讓無人機連到你自己的無線網路裡。
Telnet到無人機作業系統上並遊蕩一番是挺有趣的。Parrot無人機使用的是一個簡化版的Linux作業系統。你上次Telnet到某個系統上是什麼時間哪?下面的命令例子就演示瞭如何開啟一個終端並直接登入到無人機的作業系統上。
% script/connect “The Optics Lab” -p “particleorwave” -a 192.168.0.1 -d 192.168.7.43
% telnet 192.168.7.43
通過命令列來控制飛行
在安裝了node庫之後,下一步就是生成一個node.js的命令列執行環境,然後就可以開始控制你的無人機了:
var arDrone = require(‘ar-drone’);
var client = arDrone.createClient({ip: ‘192.168.7.43’});
client.createRepl();
drone> takeoff()
true
drone> client.animate(‘yawDance, 1.0)
如果你按照我上面所說的一步一步地實驗到這裡,你的無人機肯定已經墜落過了——至少好幾次。我已經無數次地把我的無人機的保護外殼給它粘回機身上,直到它徹底解體,隨後我只好再買了一個新的。我不得不說,其實Parrot AR型在沒有保護外殼的時候飛行得更好。但這種方式會使無人機變得很危險。因為沒有保護外殼的話,一旦無人機撞到東西,它的螺旋槳就會直接打到物體上,並留下刮痕。
從網頁上控制無人機飛行
為無人機開發一個基於網頁的控制頁面挺簡單且效果不錯。用如下所示的express.js框架就可以搭建一個很小巧的網頁伺服器。
var express = require(‘express’);
app.get(‘/’, function (req, res) {
res.sendFile(path.join(__dirname + ‘/index.html’));
});
app.get(‘/land’, function(req, res) {
client.land();
});
app.get(‘/takeoff’, function(req, res) {
client.takeoff();
});
app.listen(3000, function () {
});
我用下面的程式碼來通過一個按鈕傳送AJAX請求。
<html>
<script language=’javascript’>
function call(name) {
var xhr = new XMLHttpRequest();
xhr.open(‘GET’, name, true);
xhr.send();
}
</script>
<body>
<a onclick=”call(‘takeoff’);”>Takeoff</a>
<a onclick=”call(‘land’);”>Land</a>
</body>
</html>
從無人機上匯出視訊流
我發現把無人機上的攝像頭拍攝的視訊匯出的最佳方法就是:建立一個持續的連線,並把攝像頭拍攝的PNG圖片傳送到我的網站的網頁上。通過使用AR無人機的庫(見下面的程式碼),網頁伺服器不斷地把無人機攝像頭拍攝的PNG畫面拉取出來。
var pngStream = client.getPngStream();
pngStream
.on(‘error’, console.log)
.on(‘data’, function(pngBuffer) {
sendPng(pngBuffer);
}
function sendPng(buffer) {
res.write(‘–daboundary\nContent-Type: image/png\nContent-length: ‘ + buff
er.length + ‘\n\n’);
res.write(buffer);
});
對從無人機獲取的影象進行人臉識別
微軟的Azure Face API系統很容易上手,且功能強大。你上傳你朋友的照片給它,這個系統就能識別出他們是誰。它也能猜測人物的年齡和性別。我發現這兩個功能的識別準確率是驚人的高。整個識別的延遲大概是200毫秒。識別1000次請求花費1.5美元。對我而言,這個價格對於這種應用是相當合理的。下面是我的程式碼,它實現了傳送圖片給API來做人臉識別的功能。
var oxford = require(‘project-oxford’),
oxc = new oxford.Client(CLIENT_KEY);
loadFaces = function() {
chris_url = “https://media.licdn.com/mpr/mpr/shrinknp_400_400/AAEAAQAAAAAAAALyAAAAJGMyNmIzNWM0LTA5MTYtNDU4Mi05YjExLTgyMzVlMTZjYjEwYw.jpg”;
lukas_url = “https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/3/000/058/147/34969d0.jpg”;
oxc.face.faceList.create(‘myFaces’);
oxc.face.faceList.addFace(‘myFaces’, {url => chris_url, name=> ‘Chris’});
oxc.face.faceList.addFace(‘myFaces’, {url => lukas_url, name=> ‘Lukas’});
}
oxc.face.detect({
path: ‘camera.png’,
analyzesAge: true,
analyzesGender: true
}).then(function (response) {
if (response.length > 0) {
drawFaces(response, filename)
}
});
我用了ImageMagick庫來對我收集的PNG圖片做打標籤,效果相當好。對於這個部分其實可以有很多的擴充套件可能。比如用一個情感API來識別人臉所表現出來的情感。
運用語音來控制無人機
進行語音識別部分開發的難點並不是識別本身,而是如何把語音流從執行在我本地伺服器上的網頁裡轉換成微軟Speech API可以使用格式。下面的程式碼就是實現這個功能的。一旦你能把語音儲存成單聲道和以正確的取樣頻率取樣後,這個語音識別API就能很方便地識別語音內容。這個API的花費是1000次請求4美元。對於業餘應用來說,基本相當於是免費了。
RecordRTC是一個很好的庫,可以用來作為以網頁為客戶端的語音採集的新手入門的工具。在客戶端,我就加入了儲存語音檔案的程式碼。
app.post(‘/audio’, function(req, res) {
var form = new formidable.IncomingForm();
// 設定允許客戶在一個請求裡上傳多個檔案
form.multiples = true;
form.uploadDir = path.join(__dirname, ‘/uploads’);
form.on(‘file’, function(field, file) {
filename = “audio.wav”
fs.rename(file.path, path.join(form.uploadDir, filename));
});
// 記錄發生的錯誤日誌
form.on(‘error’, function(err) {
console.log(‘An error has occured: \n’ + err);
});
// 一旦所有檔案上傳完成,才給客戶端發相應
form.on(‘end’, function() {
res.end(‘success’);
});
// 解析出請求裡包含的表單資料
form.parse(req)
speech.parseWav(‘uploads/audio.wav’, function(text) {
console.log(text);
controlDrone(text);
});
});
我使用FFmpeg工具來降低音訊的取樣率,並把多聲道合併成單聲道,以供微軟API使用。
exports.parseWav = function(wavPath, callback) {
var cmd = ‘ffmpeg -i ‘ + wavPath + ‘ -ar 8000 -ac 1 -y tmp.wav’;
exec(cmd, function(error, stdout, stderr) {
console.log(stderr); // command output is in stdout
});
postToOxford(callback);
});
儘管我開發的功能就是這些,但是還是可以繼續擴充套件。比如用微軟的文字變語音的API來讓無人機說話!
開發自主搜尋路徑
我使用ardrone-autonomy庫來為無人機開發自主搜尋路徑。在此過程中,我無數次地把無人機弄得撞到了客廳的傢俱和植物上。最後,我妻子很“客氣”地建議我去車庫裡繼續我的專案,因為那裡沒多少可以撞的東西。但是車庫的地方有點小,使得操控空間有限。
圖3:在我的“實驗室”裡試飛無人機。圖片由Lukas Biewald授權使用
在我能有一個更大的實驗空間後,我會嘗試更智慧的搜尋演算法。不過,現在我還是隻會讓無人機做起飛和旋轉的動作,以此來搜尋發現人,並識別是敵還是友。
var autonomy = require(‘ardrone-autonomy’);
var mission = autonomy.createMission({ip: ‘10.0.1.3’, frameRate: 1, imageSize: ‘640:320’});
console.log(“Here we go!”)
mission.takeoff()
.zero() // 把當前狀態作為參考基準
.altitude(1)
.taskSync(console.log(“Checkpoint 1”))
.go({x: 0, y: 0, z: 1, yaw: 90})
.taskSync(console.log(“Checkpoint 2”))
.hover(1000)
.go({x: 0, y: 0, z: 1, yaw: 180})
.taskSync(console.log(“Checkpoint 3”))
.hover(1000)
.go({x: 0, y: 0, z: 1, yaw: 270})
.taskSync(console.log(“Checkpoint 4”));
.hover(1000)
.go({x: 0, y: 0, z: 1, yaw: 0
.land()
全都搞定後的效果
看下面的視訊。我讓無人機起飛並去找我的朋友Chris:
結論
在一切都配置妥當之後,就可以通過API來控制無人機,獲得拍攝到的視訊圖片,這一切都爽爆了!隨著新的影象識別技術可供使用,可能的應用必將越來越多。比如,讓無人機根據房屋平面圖來刷牆。雖然Parrot無人機並不是設計來為在狹小空間(比如我的房子)裡安全飛行的,但隨著無人機越來越皮實,價格變得更低,我相信真正有用的應用將會進入爆發期。
微軟的認知服務雲API是相當得好用且便宜。最初我比較擔心無人機所用的廣角攝像頭所拍攝的圖片會影響人臉識別的準確度,另外螺旋槳的噪聲可能會對語音識別產生干擾。但整體而言,這兩個API的表現遠超我的期望。同時處理延遲也低於我的預期。從架構設計角度來看,在雲端執行機器學習實時影象處理似乎是一個奇怪的選擇,但它可能會成為未來很多應用的架構選擇。
Lukas Biewald
Lukas Biewald是CrowdFlower的創始人兼CEO。CrowdFlower始於2009年,是一個資料增強的平臺,可以幫助企業獲得隨需的人力來收集、產生訓練資料,以及參與人-機器學習迴圈的工作。 在從史丹佛大學拿到數學學士和電腦科學碩士學位後,Lukas領導了雅虎日本的搜尋相關團隊。隨後他去了Powerset,作為一個資深資料科學家進行工作。2008年Powerset被微軟收購。Lukas還被《公司》雜誌評選為30位30歲以下的著名人士。 Lukas還是一位專家級的圍棋選手。
相關文章
- 人臉識別之Python DLib庫進行人臉關鍵點識別Python
- [譯] 使用 WFST 進行語音識別
- face-api.js:一個在瀏覽器中進行人臉識別的 JavaScript 介面APIJS瀏覽器JavaScript
- 新一代 Kaldi: 支援 JavaScript 進行本地語音識別和語音合成啦!JavaScript
- face-api.js:在瀏覽器中進行人臉識別的JS介面APIJS瀏覽器
- 科大訊飛,不只是智慧語音識別
- 訊飛 離線語音識別+替換自己的id
- 口袋無人機DOBBY:我的“人臉識別”已上線無人機
- 谷歌開放語音識別API 釋出機器學習雲平臺谷歌API機器學習
- 聲音識別技術真的能識別出蒙面聖戰士嗎?
- 美國出臺商用無人機新規,寶寶表示我也要去考無人機飛行員駕照無人機
- JavaScript的語音識別JavaScript
- 語音識別進入IVR系統 (轉)VR
- C#實現控制檯傳參呼叫YoloV5進行人體識別C#YOLO
- 一、Windows10平臺下Unity3d的語音識別——關鍵字識別WindowsUnity3D
- 用語言控制Linux:Linux的語音識別軟體(轉)Linux
- 蘋果推類似亞馬遜Echo智慧音響:攝像頭能識別人臉蘋果亞馬遜
- 語音識別技術
- 語音識別----音高的處理
- 語音識別方向的資料
- 在Python中使用OpenCV進行人臉檢測PythonOpenCV
- 海南話語音識別模型——模型訓練(一)模型
- 終結“黑飛”時代,無人機交通法規或年底出臺無人機
- 使用科大訊飛語音轉文字的服務進行電話錄音分析
- 人臉識別技術突飛猛進 為應用領域擴充奠定基礎
- 樹莓派語音互動--語音輸入識別樹莓派
- 谷歌再獲語音識別新進展:利用序列轉導來實現多人語音識別和說話人分類谷歌
- 好玩的github專案-科大訊飛語音linux線上語音合成後臺服務GithubLinux
- 人工智慧 (08) 語音識別人工智慧
- Swift-語音識別、翻譯Swift
- 語音識別開源專案
- ASR-使用whisper語音識別
- Linux的語音識別軟體(轉)Linux
- 科普丨一文看懂語音識別的技術原理
- 行人闖紅燈識別預警系統
- 鷹抓無人機一擊致命 制服無人機後飛走無人機
- 機器學習-無監督學習(人臉識別,使用NMF進行特徵提取)機器學習特徵
- 怎麼關閉win10語音識別 win10如何關閉電腦的語音識別Win10