用Javascript实现人脸美容
本文可视为《用HTML5实现人脸识别》的进阶,在人脸识别的基础上,我们将使用纯Javascript来实现如下的功能:
- 识别和标注人脸以及五官
![](http://namepk.sinaapp.com/blog/jsface/1.jpg)
- 对人脸进行美容
![](http://namepk.sinaapp.com/blog/jsface/2.jpg)
从本文的内容中,你将意识到,Javascript能做的,能实现的,远远比你想象的多。
演示
一、实现
1、人脸识别
Face.com有包括检测、识别在内的多个API接口,根据《用HTML5实现人脸识别》一文,我们已经可以实现图片上传,并得到检测的结果,结果如下:
返回的参数
返回参数的详细解释参见http://developers.face.com/docs/api/return-values/,其中tags为多张照片的识别结果,每一个结果包括了耳朵、眼睛、嘴、鼻的中心位置,以及年龄、性别、是否佩戴眼镜、情绪、是否在笑等多种信息。
上传图片并请求接口的代码如下。
function buildRequest(imgSrc) {document.getElementById("detect").disabled = true;document.getElementById("beauty").disabled = true;var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var imgObj = new Image(); imgObj.src = imgSrc; canvas.width = imgObj.width; canvas.height = imgObj.height; ctx.drawImage(imgObj, 0, 0); var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height); document.getElementById("bigImg").style.width = imgObj.width;var data = canvas.toDataURL('image/jpeg', 1.0); newblob = dataURItoBlob(data); var formdata = new FormData(); formdata.append("api_key", "your key"); formdata.append("api_secret", "your secret"); formdata.append("filename","avatar.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]); }});
}
人脸标注
我们将根据人脸识别的结果对五官和面部进行标注。标注的方式有两种,一种是基于Canvas的绘图,一种是传统DIV方式标注。下面我们采用第二种方式,原理是在各个点上画一个3*3的DIV,DIV的背景色为红色,采用绝对定位。接口返回的五官数值为宽高所在点的百分比值,所以需要先进行换算。
标注五官的方法如下:
function drawFacial(data) {var width = data.width;var height = data.height;var points = ["eye_left", "eye_right", "mouth_left", "mouth_center", "mouth_right", "nose", "ear_left", "ear_right"];for(var i = 0; i < points.length; i++) {var div = document.createElement('div');div.style.width = "3px";div.style.height = "3px";div.style.backgroundColor = "red";div.style.position = "absolute";div.className = "facePoint";var values = data.tags[0][points[i]];if(values != null) {var left_x = values.x;div.style.left = left_x * width / 100 - 1 + "px";var left_y = values.y;div.style.top = left_y * height / 100 - 1 + "px";document.body.appendChild(div);}}
}
标注人脸区域的方法如下:
function drawFace(data) {var width = data.width;var height = data.height;var faceWidth = data.tags[0].width * width / 100;var faceHeight = data.tags[0].height * height / 100;var faceCenter = data.tags[0].center;var div = document.createElement('div');div.style.width = faceWidth + "px";div.style.height = faceHeight + "px";div.style.borderColor = "red";div.style.borderWidth = "1px";div.style.borderStyle = "dotted";div.style.position = "absolute";div.className = "faceBox";div.style.left = faceCenter.x * width / 100 - faceWidth / 2 - 1 + "px";div.style.top = faceCenter.y * height / 100 - faceHeight / 2 - 1 + "px";document.body.appendChild(div);
}
从结果来看,Face.com的检测结果非常精准。
人脸美容
对人脸我们采用两种效果叠加进行美容,分别是增加亮度和模糊度,这样可以让人脸看起来更白,皮肤更好。
1、 增加亮度
增加亮度其实非常简单,只需要在像素点的RGB通道上增加一个固定的值。代码如下:
var imgPixels = ctx.getImageData(faceLeft, faceTop, faceWidth, faceHeight); var data = imgPixels.data;
adjustment = 5;for (var i = 0; i < data.length; i += 4) {data[i] += adjustment;data[i+1] += adjustment;data[i+2] += adjustment;
}
2、 添加模糊效果
模糊效果较为复杂,平常我们常用到的包括均值模糊和高斯模糊。在HTML5Rocks上有一篇很棒的文章《IMAGE FILTERSWITH CANVAS》,里面有各种图像处理效果,我们可以直接应用里面的模糊效果(也即3*3的均值模糊)。
原图
锐化
索贝尔滤镜
代码如下:
var Filters = {};Filters.convolute = function(pixels, weights, opaque) {var side = Math.round(Math.sqrt(weights.length));var halfSide = Math.floor(side/2);var src = pixels.data;var sw = pixels.width;var sh = pixels.height;// pad output by the convolution matrixvar w = sw;var h = sh;var output = Filters.createImageData(w, h);var dst = output.data;// go through the destination image pixelsvar alphaFac = opaque ? 1 : 0;for (var y=0; y<h; y++) {for (var x=0; x<w; x++) {var sy = y;var sx = x;var dstOff = (y*w+x)*4;// calculate the weighed sum of the source image pixels that// fall under the convolution matrixvar r=0, g=0, b=0, a=0;for (var cy=0; cy<side; cy++) {for (var cx=0; cx<side; cx++) {var scy = sy + cy - halfSide;var scx = sx + cx - halfSide;if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) {var srcOff = (scy*sw+scx)*4;var wt = weights[cy*side+cx];r += src[srcOff] * wt;g += src[srcOff+1] * wt;b += src[srcOff+2] * wt;a += src[srcOff+3] * wt;}}}dst[dstOff] = r;dst[dstOff+1] = g;dst[dstOff+2] = b;dst[dstOff+3] = a + alphaFac*(255-a);}}return output;
};Filters.tmpCanvas = document.createElement('canvas');
Filters.tmpCtx = Filters.tmpCanvas.getContext('2d');Filters.createImageData = function(w,h) {return this.tmpCtx.createImageData(w,h);
};
最后对Canvas里的图像叠加两种效果的代码如下:
var width = data.width;
var height = data.height;var faceWidth = data.tags[0].width * width / 100;
var faceHeight = data.tags[0].height * height / 100;
var faceCenter = data.tags[0].center;var faceLeft = faceCenter.x * width / 100 - faceWidth / 2;
var faceTop = faceCenter.y * height / 100 - faceHeight / 2;var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var imgPixels = ctx.getImageData(faceLeft, faceTop, faceWidth, faceHeight); var data = imgPixels.data;
adjustment = 5;for (var i = 0; i < data.length; i += 4) {data[i] += adjustment;data[i+1] += adjustment;data[i+2] += adjustment;
}
imgPixels = Filters.convolute(imgPixels, [ 1/9, 1/9, 1/9,1/9, 1/9, 1/9,1/9, 1/9, 1/9 ], 1);ctx.putImageData(imgPixels, faceLeft, faceTop, 1, 1, faceWidth - 3, faceHeight - 3);
这样,我们完成了所有的代码。是不是相当的有成就感?看起来我们完成了相当新颖而酷炫的工作。
二、思考
1、 美容滤镜是否有其他实现的方式?
之前我介绍过CSS3滤镜,它有虚化和亮度调节两个方法可以方便直接的为图片添加滤镜效果,可以在《遇见CSS3滤镜》这篇文章里了解到。
2、我们还可以实现哪些美容效果?
1)去红眼
检测到眼睛位置后,我们可以采用一定范围内的滤镜,把这个范围内的红色转换为黑色,从而实现去红眼效果。
2)眼睛放大
检测到眼睛位置后,我们还可以采用一定的算法,实现眼睛放大的效果。要体验这个效果,可以下载百度魔图客户端体验。
百度魔图-强大的图片处理客户端
3)背景虚化
背景虚化效果基本和我们文中提到的效果是相反的方式。
3、 文中的效果是否还可以优化?
例如是否可以把文中美容的区域将正方形变为椭圆形,更为贴近人脸的形状?其实并不难,读者有兴趣可深入思考和实现。
4、 除了美容,我们还能完成什么样的功能?
Face.com提供了三个功能演示:人脸Tag、情景照片、人脸查找。对于应用开发者来说,从来不缺乏创意,例如Face.com图片检测返回的参数里包括图片旋转角度,我们可以利用这个参数实现图片批量自动旋转的功能(我最近在整理旅游的照片时就深深的理解了这个功能的便利性和必要性)。或者基于微博的图片爱情速配App?我期待更有创意和使用价值idea的出现。
扩展阅读
- 《遇见CSS3滤镜》
- 《如何使用HTML5实现拍照上传应用》
- 《用HTML5创建超酷图像灰度渐变效果》
本文来自蒋宇捷的博客,转载请注明。
用Javascript实现人脸美容相关推荐
- 用HTML5实现人脸识别-用Javascript实现人脸美容
在人脸识别的基础上,我们将使用纯Javascript来实现如下的功能: 识别和标注人脸以及五官 对人脸进行美容 从本文的内容中,你将意识到,Javascript能做的,能实现的,远远比你想象的多. 演 ...
- OpenCV:19.人脸美容效果2-边缘处理
人脸美容效果2-边缘处理 1.快速边缘保留算法 1.快速边缘保留算法 先看两张图: 具体代码 // 1. 快速边缘保留#include<opencv2/opencv.hpp> #inclu ...
- javaScript实现人脸探测与捕获
javaScript实现人脸探测与捕获 思路 tracking.js库可以实现捕捉或实时跟踪相机返回的颜色或面部图像信息.基于对特定颜色的检测或人脸面部的出现和移动来触发相对应的检测事件,比如调用该库 ...
- 我爱机器学习网机器学习类别文章汇总
机器学习领域的几种主要学习方式 From Stumps to Trees to Forests KDD-2014 – The Biggest, Best, and Booming Data Scien ...
- 我爱机器学习--机器学习方向资料汇总
转载:http://blog.csdn.net/shuimanting520/article/details/45748505 机器学习爱好者资料 机器学习领域的几种主要学习方式 From Stump ...
- 【项目实战课】基于Pytorch的PFLD人脸关键点检测实战
欢迎大家来到我们的项目实战课,本期内容是<基于Pytorch的PFLD人脸关键点检测实战>.所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战讲 ...
- 【资源总结】“十大深度学习方向” 专栏
文章首发于微信公众号<与有三学AI> [资源总结]"十大深度学习方向" 专栏上线 今天给大家介绍一下我们拥有的知乎十大深度学习专栏,涵盖了深度学习的各个主流的方向 01 ...
- 使用face-api和Tensorflow.js进行预训练的AI情绪检测
目录 设置服务器 设置HTML 获取实时视频源 使用face-api.js进行预测 将代码放在一起 测试结果 下一步是什么? 下载源-10.6 MB 面部表情识别是图像识别中关注的关键领域之一,一直都 ...
- Web前端技术 Web学习资料 Web学习路线 Web入门宝典
学习路线 第一章 核心 1.Node Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.Node.js是一个 ...
最新文章
- Linux设备驱动模型三 kset
- MP3 Encoder for mac(MP3编码器)修复版
- 《Tableau数据可视化实战》——1.3节连接Excel文件
- 佳能g2810打印机扫描怎么用_佳能g2810打印机说明书
- 华为网络技术大赛2017 考后感
- C陷阱与缺陷(二)语义“陷阱”、连接
- python音乐库_目前在python3下有哪些音乐处理库?
- 大一计算机时间差怎么求,总结:如何使用Excel计算时差和日期差,只需阅读本文!...
- SpringBoot+SpringSecurity+Thymeleaf 演示CSRF攻击
- PromptBERT: Improving BERT Sentence Embeddings with Prompts
- 数字角频率和模拟角频率和物理频率和归一化角频率的关系,及FFT频率和实际物理频率的关系分析
- 情境领导者-第二章、领导风格
- css兼容浏览器火狐,常见IE和火狐的CSS兼容性问题
- C++坑人游戏(加更)
- 容器化技术与微服务结合---结合springcloud微服务框架进行部署(含切换成阿里云docker仓库)(五)
- GitHub 上最酷的 8 个简历模板
- FPGA入门(FPGA结构、Verilog编程基础)
- 09 年,台式机显卡功耗表
- ESXI VCenter 安装过程及常规使用方法(图文解析每一步)
- 对话CTO的精彩语句