注:今天 HTML5 小組沙龍《論道 HTML5 》分享時有朋友問到一個問題, getUserMedia 是否會支持人臉識別,我當時的答案是這應該是應用來實現的功能,而不是規范要完成的工作。而我之前在網上看到過一篇關于 getUserMedia 和人臉識別的相關文章,覺得很有趣,正好趁這個機會分享給大家。
轉載請注明出處: 蔣宇捷的博客
“ 現代 Web” 不斷發展出不少有趣的 API ,但你并不會在大多數項目中使用到所有的內容。例如我一直特別關注 Canvas 特性。它對游戲和繪圖意義重大 – 但是僅此而已。它并不是一個不好的特性,我只是不會經常用到它。每當看到一些開發中酷炫的新功能,我的大腦里都會思考它們可以產生哪些 實際 用途。顯然對你有價值的內容可能對我來說并不一定,但搞清楚我如何實際使用一個功能是我學習它的一部分。
其中的一個特性是 getUserMedia ( )。它是一個 JavaScript API ,可以讓你訪問(需要權限)用戶的網絡攝像頭和麥克風。 目前 Opera 和 Chrome (我相信現在的版本 18 可以支持,但是你可能需要使用 Canary 。你還需要啟用它。這兒有一個 。)一旦你啟用了 getUserMedia ,它使用起來相當簡單。這里有一個快速的訪問請求:
//a video tagvar video = document.getElementById('monitor');//request itnavigator.webkitGetUserMedia('video', gotStream, noStream);function gotStream(stream) {video.src = webkitURL.createObjectURL(stream);video.onerror = function () {stream.stop();streamError();};}function noStream() {document.getElementById('errorMessage').textContent = 'No camera available.';}function streamError() {document.getElementById('errorMessage').textContent = 'Camera error.';}
getUserMedia 的第一個參數是類型。 根據規范,這應該是一個對象,你可以啟用音頻、視頻,或兩者兼而有之,像這樣: {audio:true, video:true} 。 然而在我的測試中,傳遞一個字符串 “video” 也可以正常工作。 你將看到的演示基于另一個演示,所以代碼來自于一個較早的 Chrome 下的版本。 第二個和第三個參數是操作成功和失敗的回調函數。
你可以看到操作成功的事件處理函數將視頻流分配給HTML5 Video 標簽。最酷的是,一旦運行起來,你就可以使用 Canvas API 來拍照。 對于這個演示,可以看看 Greg Miernicki 的 Demo :
如果這個Demo 無法工作,可以按照下面的說明來開啟getUserMedia支持后再次進行嘗試。(雖然我打算分享一些屏幕截圖,所以如果你只是想繼續閱讀,那也沒關系。)
基于Greg 的Demo,我突然想到可以用網絡攝像頭的照片做一些很酷的東西。我記得 有一個 非常 酷的 API 來解析臉部的圖片。 (我 11 月曾經在博客里寫了一個 ColdFusion 的 。)然后我在想,是否我們能把 Greg 的 Demo 與 Face.com 的 API 結合起來做一些基本面部識別的 Demo 。
這有這幾個重大問題。 第一 – Face.com 有一個很好的 REST API ,我們將如何從 JavaScript 應用程序里面來調用它? 其次 – Face.com 需要你可以上傳圖片,或給它一個網址。 我知道可以把一個 Canvas 圖片發送給服務器,并通過我的后臺上傳到 Face.com ,但有沒有辦法繞過服務器來把圖片發送給這個 API ?
第一個實際上并不是問題。 Face.com 實現了 (跨域資源共享)。 CORS 系統基本上可以讓服務器暴露給其它域上文件的 Ajax 調用。 這是一個偉大的功能,我希望更多的服務能夠使用它。
更復雜的問題則是如何把畫布上的數據發送到Face.com (宇捷注:還可以參考我的這篇文章《 如何使用 HTML5 實現拍照上傳應用 》)。我如何模擬文件上傳?這里有另一個很酷的新技巧 – Formdata 。 ColdFusion 的研究員 Sagar Ganatra 關于這個話題有一篇很棒的 。 下面展示了我如何使用它:
function snapshot() {$("#result").html("
Working hard for the money...
");canvas.width = video.videoWidth;canvas.height = video.videoHeight;canvas.getContext('2d').drawImage(video, 0, 0);var data = canvas.toDataURL('image/jpeg', 1.0);newblob = dataURItoBlob(data);var formdata = new FormData();formdata.append("api_key", faceKey);formdata.append("api_secret", faceSecret);formdata.append("filename","temp.jpg"); formdata.append("file",newblob); $.ajax({ url: 'http://api.face.com/faces/detect.json?attributes=age_est,gender,mood,smiling,glasses', data: formdata, cache: false, contentType: false, processData: false, dataType:"json", type: 'POST', success: function (data) { handleResult(data.photos[0]); }}); }讓我們一行行來看這段代碼。 首先 – 我需要從畫布對象獲取二進制數據。 有幾種方法可以實現,但是我尤其想要一個二進制的 Blob 。 請注意 dataURIToBlob 方法。 這是幾周前我從 上發現的。
我創建了一個新的formdata 對象,然后簡單地設置了自己所需的值。你可以看到我發起了幾個 API 請求,但關鍵在于文件名和文件對象本身。
接下來你可以看到簡單的jQuery Ajax 調用。 Face.com 有多種選擇,但我基本只要求它返回預測年齡、性別、情緒,是否面帶微笑以及戴著眼鏡。 就是這些。我得到了一個很棒的 JSON 包,并且對它進行了格式化。
現在顯然API 并不完美。我獲得了使用 API 一些不同程度的結果。 有時相當準確,有時相反。但是總體來說,這相當酷。這里有一些實際測試的圖片,看起來有點“可怕”。
識別結果:neutral(無表情)
識別結果: happy(開心)
識別結果:surprised(驚訝)
識別結果:sad(悲傷)
好了,準備自己親自來試試? 只需點擊下面的演示按鈕。如果需要源代碼,可以直接在頁面上查看! 這是100 %的純客戶端代碼。
如果想從另外一方面了解 getUserMedia ,可以看看這些例子:
感謝 getUserMedia ( HTML5Doctor 的這篇文章不錯,可以了解到 getUserMedia 的前世今生,以及和 HTML Media Capture API 的區別。)
本文轉載自:蔣宇捷的專欄
歡迎加入我愛機器學習QQ14群:336582044
微信掃一掃,關注我愛機器學習公眾號