注:今天HTML5小组沙龙《论道HTML5》分享时有朋友问到一个问题,getUserMedia是否会支持人脸识别,我当时的答案是这应该是应用来实现的功能,而不是规范要完成的工作。而我之前在网上看到过一篇关于getUserMedia和人脸识别的相关文章,觉得很有趣,正好趁这个机会分享给大家。
译自:[http://www.raymondcamden.com/index.cfm/2012/4/6/Face-detection-with-getUserMedia](http://www.raymondcamden.com/index.cfm/2012/4/6/Face-detection-with-getUserMedia)
转载请注明出处:[蒋宇捷的博客](http://blog.csdn.net/hfahe)
“现代Web”不断发展出不少有趣的API,但你并不会在大多数项目中使用到所有的内容。例如我一直特别关注Canvas特性。它对游戏和绘图意义重大 - 但是仅此而已。它并不是一个不好的特性,我只是不会经常用到它。每当看到一些开发中酷炫的新功能,我的大脑里都会思考它们可以产生哪些*实际*用途。显然对你有价值的内容可能对我来说并不一定,但搞清楚我如何实际使用一个功能是我学习它的一部分。
其中的一个特性是getUserMedia( **[W3C规范](http://dev.w3.org/2011/webrtc/editor/getusermedia.html)** )。它是一个JavaScript API,可以让你访问(需要权限)用户的网络摄像头和麦克风。 目前Opera和Chrome(我相信现在的版本18可以支持,但是你可能需要使用Canary。你还需要启用它。这儿有一个[说明](https://sites.google.com/site/webrtc/running-the-demos)。)一旦你启用了getUserMedia,它使用起来相当简单。这里有一个快速的访问请求:
~~~
//a video tag
var video = document.getElementById('monitor');
//request it
navigator.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:
[**http://miernicki.com/cam.html**](http://miernicki.com/cam.html)
如果这个Demo无法工作,可以按照下面的说明来开启getUserMedia支持后再次进行尝试。(虽然我打算分享一些屏幕截图,所以如果你只是想继续阅读,那也没关系。)
基于Greg的Demo,我突然想到可以用网络摄像头的照片做一些很酷的东西。我记得[**Face.com**](http://www.face.com/)有一个*非常*酷的API来解析脸部的图片。(我11月曾经在博客里写了一个ColdFusion的[例子](http://www.raymondcamden.com/index.cfm/2011/11/7/Facecom-API-released)。)然后我在想,是否我们能把Greg的Demo与Face.com的API结合起来做一些基本面部识别的Demo。
![](https://box.kancloud.cn/2016-08-09_57a9a2e546cb4.gif)
这有这几个重大问题。 第一 - Face.com有一个很好的REST API,我们将如何从JavaScript应用程序里面来调用它?其次 - Face.com需要你可以上传图片,或给它一个网址。 我知道可以把一个Canvas图片发送给服务器,并通过我的后台上传到Face.com,但有没有办法绕过服务器来把图片发送给这个API?
第一个实际上并不是问题。Face.com实现了[**CORS**](http://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html)(跨域资源共享)。CORS系统基本上可以让服务器暴露给其它域上文件的Ajax调用。这是一个伟大的功能,我希望更多的服务能够使用它。
更复杂的问题则是如何把画布上的数据发送到Face.com(宇捷注:还可以参考我的这篇文章《[如何使用HTML5实现拍照上传应用](http://blog.csdn.net/hfahe/article/details/7354912)》)。我如何模拟文件上传?这里有另一个很酷的新技巧 - Formdata。ColdFusion的研究员Sagar Ganatra关于这个话题有一篇很棒的**[博客](http://www.sagarganatra.com/2011/07/submitting-form-using-formdata-object.html)**。下面展示了我如何使用它:
~~~
function snapshot() {
$("#result").html("<p><i>Working hard for the money...</i></p>");
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方法。这是几周前我从[StockOverflow](http://stackoverflow.com/a/8782422/52160)上发现的。
我创建了一个新的formdata对象,然后简单地设置了自己所需的值。你可以看到我为发起的API请求添加了几个参数,但关键在于文件名和文件对象本身。
接下来你可以看到简单的jQuery Ajax调用。Face.com有多种选择,但我基本只要求它返回预测年龄、性别、情绪,是否面带微笑以及戴着眼镜。就是这些。我得到了一个很棒的JSON包,并且对它进行了格式化。
现在显然API并不完美。我获得了使用API一些不同程度的结果。有时相当准确,有时相反。但是总体来说,这相当酷。这里有一些实际测试的图片,看起来有点“可怕”。
![](https://box.kancloud.cn/2016-08-09_57a9a2e55aae0.jpg)
识别结果:neutral(无表情)
![](https://box.kancloud.cn/2016-08-09_57a9a2e572c03.jpg)
识别结果:happy(开心)
![](https://box.kancloud.cn/2016-08-09_57a9a2e58aa5b.jpg)
识别结果:surprised(惊讶)
![](https://box.kancloud.cn/2016-08-09_57a9a2e5a43dc.jpg)
识别结果:sad(悲伤)
好了,准备自己亲自来试试? 只需点击下面的演示按钮。如果需要源代码,可以直接在页面上查看! 这是100%的纯客户端代码。
[![](https://box.kancloud.cn/2016-08-09_57a9a2e5bfb2a.jpg)](http://www.raymondcamden.com/demos/2012/mar/29/test1.html)
如果想从另外一方面了解getUserMedia,可以看看这些例子:
- [感谢getUserMedia](http://html5doctor.com/getusermedia/)(HTML5Doctor的这篇文章不错,可以了解到getUserMedia的前世今生,以及和HTML Media Capture API的区别。)
- [在Chrome上测试WebRTC](https://sites.google.com/site/webrtc/running-the-demos)
- [HTML5新特性:WebRTC和设备访问](http://www.tricedesigns.com/2012/02/02/bleeding-edge-html5-webrtc-device-access/)
- [用HTML5捕获音频和视频](http://www.html5rocks.com/en/tutorials/getusermedia/intro/)
- 前言
- AutoPager的简单实现
- 利用CSS3特性巧妙实现漂亮的DIV箭头
- IE9在Win7下任务栏新特性简介
- 浏览器九宫格的简单实现
- Raphael js库简介
- 使用CSS3构建Ajax加载动画
- 用CSS3创建动画价格表
- 用CSS3实现浏览器的缩放功能
- 用纯CSS3实现QQ LOGO
- 用CSS3创建旋转载入器
- 使用Javascript开发移动应用程序
- 用HTML5创建超酷图像灰度渐变效果
- 使用CSS3创建文字颜色渐变(CSS3 Text Gradient)
- 仅用CSS创建立体旋转幻灯片
- 如何创建跨浏览器的HTML5表单
- 用CSS3实现动画进度条
- HTML5 Guitar Tab Player
- 奇妙的HTML5 Canvas动画实例
- 谈HTML5和CSS3的国际化支持
- 实现跨浏览器的HTML5占位符
- 前端开发必备工具:WhatFont Bookmarklet-方便的查询网页上的字体
- 使用HTML5和CSS3来创建幻灯片
- HTML5之美
- 如何使用HTML5创建在线精美简历
- 以小见大、由浅入深-谈如何面试Javascript工程师
- 快速入门:HTML5强大的Details元素
- 用CSS3实现图像风格
- HTML5视频字幕与WebVTT
- 用纯CSS3实现Path华丽动画
- 用3个步骤实现响应式网页设计
- 遇见CSS3滤镜
- 关于CSS3滤镜的碎念
- 用纯CSS3绘制萌系漫画人物动态头像
- CSS3新的鼠标样式介绍
- 用HTML5献上爱的3D玫瑰
- 对HTML5 Device API相关规范的解惑
- 如何使用HTML5实现拍照上传应用
- 2012第一季度国外HTML5移动开发趋势
- HTML5新特性:范围样式
- 百度开发者大会-《用HTML5新特性开发移动App》PPT分享
- Chrome 19对于HTML5最新支持的动态:电池状态API,全屏API,震动API,语音API
- 遇见Javascript类型数组(Typed Array)
- 用HTML5 Audio API开发游戏音乐
- 用HTML5实现人脸识别
- 用Javascript实现人脸美容
- Chrome 20对于HTML5最新支持的动态:颜色输入,网络信息API,CSS着色器
- 用HTML5实现手机摇一摇的功能
- 用HTML5实现iPad应用无限平滑滚动
- 用非响应式设计构建跨端Web App
- 了解SVG
- HTML5图像适配介绍
- HTML5安全:内容安全策略(CSP)简介
- HTML5安全:CORS(跨域资源共享)简介
- 用CSS3 Region和3D变换实现书籍翻页效果
- 谈谈移动App的思维误区
- Chrome新特性:文件夹拖拽支持
- 《关注HTML5安全》
- HTML5安全风险详析之一:CORS攻击
- HTML5安全风险详析之二:Web Storage攻击
- HTML5图像适配最新进展:响应式图片规范草案
- HTML5移动Web App相关标准状态及路线图
- HTML5安全风险详析之三:WebSQL攻击
- Chrome引入WebRTC支持视频聊天App
- HTML5安全风险详析之四:Web Worker攻击
- HTML5安全风险详析之五:劫持攻击
- HTML5安全风险详析之六:API攻击
- HTML5安全攻防详析之七:新标签攻击
- 在iOS Safari中播放离线音频
- 使用WebRTC实现远程屏幕共享
- Firefox、Android、iOS遇见WebRTC
- HTML5光线传感器简介
- HTML5安全攻防详析之八:Web Socket攻击
- HTML5安全攻防详析之完结篇:HTML5对安全的改进
- 激动人心!在网页上通过语音输入文字 - HTML5 Web Speech API介绍
- Web滚动性能优化实战
- 用CSS3设计响应式导航菜单
- 用HTML5构建高性能视差网站
- 漫谈@supports与CSS3条件规则
- HTML5下载属性简介
- 如何开发优秀的HTML5游戏?-迪斯尼《寻找奥兹之路》游戏技术详解(一)
- 如何开发优秀的HTML5游戏?-迪斯尼《寻找奥兹之路》游戏技术详解(二)
- 趋势:Chrome为打包应用提供强大新特性
- 从HTML5移动应用现状谈发展趋势
- 基于HTML5的Web跨设备超声波通信方案