文章目录

  • 前端机器学习--识别人脸在脸颊上画草莓
    • 一、最终结果
    • 二、原理
      • 1. 前端的机器学习
      • 2. 基本原理
    • 三、基于`vue-cli`搞一个
      • 1. 使用`vue-cli`脚手架搭建项目
      • 2. 使用`face-api.js`检测人脸图片,获取检测结果
        • (1)安装`face-api.js`
        • (2)加载模型数据
        • (3)使用`face-api.js`检测人脸图片,获取检测结果
      • 3. 计算(草莓位置、大小、倾斜弧度等)
        • (1)获取脸上元素的特征点数组
        • (2)获取草莓位置
        • (3)获取草莓大小
        • (4)获取草莓倾斜弧度
      • 4. 画草莓

前端机器学习–识别人脸在脸颊上画草莓

一、最终结果



在线体验
急性子想直接食用的点这个:源码地址

二、原理

要在用户上传的人脸上画草莓,会面临几个问题:

  1. 在哪儿画?
  2. 画多大?
  3. 草莓的角度和脸的角度是否一致?

基于这些问题,就不得不使用机器学习来解决了!

1. 前端的机器学习

提起前端的机器学习,首先想到的就是Google的TensorFlow:

TensorFlow 是一个端到端开源机器学习平台。它拥有一个包含各种工具、库和社区资源的全面灵活生态系统,可以让研究人员推动机器学习领域的先进技术的发展,并让开发者轻松地构建和部署由机器学习提供支持的应用。

有兴趣的可以去TensorFlow官网看看,有很多好玩的东西。

当然,我们仅仅是使用人脸识别,那有人已经在TensorFlow的基础上封装了专门针对人脸识别的库 face-api.js

2. 基本原理

我只是大体说一下,我只是一个感兴趣的可以去看看具体的内容。

  1. 第一步:找出所有的面孔

解决方案HOG(Histogram of Oriented Gradients)方向梯度直方图,一种能够检测物体轮廓的算法。

  1. 第二步:脸部的不同姿势

使用由瓦希德·卡奇米(Vahid Kazemi)和约瑟菲娜·沙利文(Josephine Sullivan)在 2014 年发明的一种面部特征点估计(face landmark estimation)算法。

这一算法的基本思路是找到68个人脸上普遍存在的点(称为特征点, landmark):

其中:

下巴轮廓17个点 [0-16]
左眉毛5个点 [17-21]
右眉毛5个点 [22-26]
鼻梁4个点 [27-30]
鼻尖5个点 [31-35]
左眼6个点 [36-41]
右眼6个点 [42-47]
外嘴唇12个点 [48-59]
内嘴唇8个点 [60-67]

有了这68个点,我们就可以轻松的知道眉毛、眼睛、鼻子和嘴巴的位置信息了,根据这些位置信息,我们经过一些简单的计算就可以得出开始提到的这几个问题的答案:

  1. 在哪儿画?
  2. 画多大?
  3. 草莓的角度和脸的角度是否一致?

三、基于vue-cli搞一个

有了face-api.js我们就可以动手开始搞了。大体上分为4步:

  1. 使用vue-cli脚手架搭建项目
  2. 使用face-api.js检测人脸图片,获取检测结果
  3. 计算(草莓大小、位置、旋转角度等)
  4. 画草莓

1. 使用vue-cli脚手架搭建项目

使用vue-cli快速创建一个项目

2. 使用face-api.js检测人脸图片,获取检测结果

(1)安装face-api.js

npm i face-api.js

(2)加载模型数据

使用face-api.js是不需要我们自己慢慢训练的,可以直接使用models
你可以根据应用程序的要求加载你需要的特定模型。但是如果要运行一个完整的端到端的示例,我们还需要加载人脸检测、人脸特征点检测和人脸识别模型。相关的模型文件可以在代码仓库中找到。我们将它们放在public/models文件夹下并导入:

const MODEL_URL = "/models";
await faceapi.loadSsdMobilenetv1Model(MODEL_URL);
await faceapi.loadFaceLandmarkModel(MODEL_URL);
await faceapi.loadFaceRecognitionModel(MODEL_URL);

face-api.js导入我们的组件:

import * as faceapi from "face-api.js";

(3)使用face-api.js检测人脸图片,获取检测结果

let input = this.$refs.inputImg; // 待检测的图片
let canvas = this.$refs.overlay; // 等下画检测结果的画布
const minConfidence = 0.8;
let fullFaceDescriptions = await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceDescriptors(); // 检测图片
faceapi.matchDimensions(canvas, input); // 让画布和图片一样大
const displaySize = { width: input.width, height: input.height };
const resizedDetections = faceapi.resizeResults(fullFaceDescriptions,displaySize
); // 调整检测结果和输入图片像素

3. 计算(草莓位置、大小、倾斜弧度等)

(1)获取脸上元素的特征点数组

// 脸颊是从左往右 17个点
const jawOutline = resizedDetections[0].landmarks.getJawOutline();
// 鼻子是从上往下画的 9个点
const nose = resizedDetections[0].landmarks.getNose();
//嘴巴分 20个点
const mouth = resizedDetections[0].landmarks.getMouth();
//左眼 6个点 从左往右
const leftEye = resizedDetections[0].landmarks.getLeftEye();
//右眼 6个点 从左往右
const rightEye = resizedDetections[0].landmarks.getRightEye();
//左眉毛 5个点 从左往右
const leftEyeBbrow = resizedDetections[0].landmarks.getLeftEyeBrow();
//右眉毛 5个点 从左往右
const rightEyeBrow = resizedDetections[0].landmarks.getRightEyeBrow();
faceapi.draw.drawDetections(canvas, resizedDetections); // 画框
faceapi.draw.drawFaceLandmarks(canvas, resizedDetections); // 画点

画出来的结果如图:

(2)获取草莓位置

草莓的位置获取,先看下面这张图:

先比较左右黄色和绿色两条线的长度,哪边长就画在哪边(考虑可能照片是侧着脸的),具体的位置左右不一样,右边绿色的线直接从线的中点开始画,而左边黄色的线则是在线的中点再往左边偏移草莓宽度的一半开始画。
大概如图:

所以是先获取点32和点16的距离,再获取中点:

//  获取两点之间距离
const getDistance = (a, b) => {return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2))
}
//  获取两点之间的中点
const getMidPoint = (pa, pb) => ({x: (pa.x + pb.x) / 2,y: (pa.y + pb.y) / 2
})

(3)获取草莓大小

草莓的大小可以估计一下,大概是整个脸宽的1/6

const size = { width: faceWidth / 6, height: faceWidth / 6 }

(4)获取草莓倾斜弧度

我们可以根据眉毛的中点和下颚的最低点两个点计算出脸的弧度,即草莓的弧度:

// 获取脸的倾斜弧度
const getFaceRadian = (jawPos, midPointOfEyebrows) =>Math.PI -Math.atan2(jawPos.x - midPointOfEyebrows.x, jawPos.y - midPointOfEyebrows.y)

4. 画草莓

有了前面的内容,画草莓就简单了。先将原图画上去,再在原图的基础上画上草莓:

// 画草莓
function drawBerry(ctx, config, berryUrl) {const { angle, faceWidth, facePos } = configgetImg(berryUrl, (img) => {ctx.save()// 移动画布原点到画草莓的位置ctx.translate(facePos.point.x, facePos.point.y)// 旋转草莓的角度和脸的角度一致ctx.rotate(angle)// 调整草莓的位置const { x, y, width, height } = transBerry(faceWidth, 0, 0, facePos.dir)ctx.drawImage(img, x, y, width, height)ctx.restore()})
}
// 获取图片
function getImg(src, cb) {const img = new Image()img.setAttribute('crossOrigin', 'anonymous')img.src = srcimg.onload = () => cb(img)
}

限于篇幅,文中只提及了部分重点代码,需要看完整代码的可以点这里。

前端机器学习--识别人脸在脸颊上画草莓相关推荐

  1. 前端机器学习:识别人脸,并在脸颊上画草莓

    2020-04-05 17:56:15 作者 | 前端开发劝退师 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 最终结果 在线体验:http://www.caomage.com/ind ...

  2. 机器学习原来这么有趣!第四章:用深度学习识别人脸

    第一章:全世界最简单的机器学习入门指南 https://blog.csdn.net/wskzgz/article/details/89917343 第二章:用机器学习制作超级马里奥的关卡 https: ...

  3. 机器学习之人脸识别face_recognition使用

    机器学习之人脸识别face_recognition使用 简介 一 二 主要方法介绍 1. load_image_file 加载图像 2. face_locations 定位图中所有人脸 3. face ...

  4. 机器学习原来如此有趣:用深度学习识别人脸

    本系列文章目前已经更新两期,分别是: 机器学习原来如此有趣!全世界最简单的机器学习入门指南. 机器学习原来如此有趣:如何故意欺骗神经网络 你是否有注意到Facebook最近开发了一个非同寻常的功能:将 ...

  5. 机器学习之人脸识别(Face Recognition)

    机器学习之机器是如何识别人脸(Face Recognition)的? 目前,一些机器学习技术已经被广泛应用于人脸识别.人脸支付以及身份认证领域,例如支付宝的FACEID,阿里的Alipay,ETC等等 ...

  6. 机器学习与人脸识别3:人脸检测算法综述

    以下内容转自网络,主要介绍人脸算法的历史: 导言 人脸检测是目前所有目标检测子方向中被研究的最充分的问题之一,它在安防监控,人证比对,人机交互,社交和娱乐等方面有很强的应用价值,也是整个人脸识别算法的 ...

  7. 人脸识别数据集精粹(上)

    人脸识别数据集精粹(上) 人脸识别 人脸检测和关键点检测都是比较底层的任务,而人脸识别是更高层的任务,它就是要识别出检测出来的人脸是谁,完成身份比对等任务,也是人脸领域里被研究最多的任务. 1.1 人 ...

  8. 重要提醒!人脸识别一定要穿上衣服!

    ????关注 中生代技术,接力技术,链接价值???? " 说到人脸识别,大家应该都不陌生了.如今,人脸识别作为新兴的生活方式,已经在乘车.打卡.支付.办证.公安司法等环境中快速普及. 图片来 ...

  9. 2D与3D人脸识别有什么本质上的区别?

    https://www.zhihu.com/question/324123433/answer/681365180 https://www.zhihu.com/question/324123433/a ...

最新文章

  1. rsync 同步数据
  2. IP分类以及特殊IP
  3. 11个鲜为人知的实用Linux命令 - Part 2
  4. SQL常用日期处理函数(转)
  5. java通过桥访问excel_通过jdbc-odbc桥来访问excel文件
  6. iOS 自定义layer的两种方式
  7. python字典浅复制_元组,字典,浅复制,集合
  8. Atitit 分布式文件系统 hdfs nfs fastfs 目录 1. 分布式文件系统 1 2. 什么是FastDFS 1 2.1. FastDFS特性: 1 2.1.1. fastdfs是否可在
  9. 大数据科学相关岗位,我们需要具备哪些数学基础?
  10. 2018华为网络技术大赛失败纪念
  11. 【Proteus仿真】CD4026秒脉冲0-9循环计数
  12. JAVA将多个PDF文件合并成一个PDF
  13. matlab视频行人检测,利用MATLAB实现了视频图像行人识别与检测
  14. js、html实现断点播放视频,视频资源在localStorage中
  15. 反射 Reflect Modifier 修饰符工具类
  16. map、set、multimap和multiset的使用【STL】
  17. Qt使用vlc多窗口播放同一个视频
  18. 2021-2027全球与中国人体解剖学模型市场现状及未来发展趋势
  19. 最长情的告白就是陪伴【Python七夕祝福】——那些浪漫的开始
  20. 怎么快速的在WORD中勾选空白的小方格,看这里就够了,WORD中如何快速的勾选空白小方格

热门文章

  1. rasp完整搭建方案
  2. 【和63】王甲佳:实体“微地址”的遐想(微地址系列9-3)
  3. SFP端口与GE口的作用
  4. jqgrid 单元格自动换行且垂直居中
  5. selenium关闭浏览器当前页面后,切换到最后一个页面继续操作
  6. 【开发教程1】开源蓝牙智能健康手表-整机功能演示
  7. 华为手表,还能评价动脉弹性:北大人民医院孙宁玲等研究
  8. 释放重引用(Use After Free,UAF)漏洞原理
  9. hdu 5465(二维树状数组)
  10. admin Tips