欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本篇是《Java版人脸跟踪三部曲》系列的第二篇,前文体验了人脸跟踪的效果,想要编码实现这样的效果,咱们需要做好设计工作,也就是本篇的任务
  • 本篇主要包含以下内容:
  1. 核心逻辑
  2. 重要知识点:HSV、HUE
  3. 重要知识点:反向投影
  4. 重要知识点:CamShift
  5. 重要知识点:JavaCV的API支持
  6. 如何开局?
  7. 前文的完整功能分析
  8. 异常处理
  9. 期待下一篇的实战(虎年贺岁作品)

核心逻辑

  • 本篇没有编码和操作实战,会略显枯燥,所以提前小结人脸跟踪核心逻辑,如此就算您受不了欣宸的啰嗦提前关闭网页,好歹也能带走些干货:
  • 如下图所示,人脸跟踪的核心逻辑,其实就是先拿人脸直方图hist,然后将每一帧都转为hist的概率分布图(也叫反向投影),再用MeanShift算法在图上做迭代计算,结果就是人脸位置:
  • 拿到每一帧的人脸位置后,在人脸上添加一个矩形框,此时,在预览窗口看到的效果就是视频中人脸上始终有矩形框,实现了跟踪的效果
  • 虽然尽可能简短的讲完了核心逻辑,但此时的您可能有一些疑问,例如:
  1. Hue分量是啥?
  2. 反向投影是啥?
  3. MeanShift又是啥?
  4. 前文提到过CamShift,这会儿咋又不提了?
  • 没错,上面几个疑问就是人脸跟踪功能依赖的关键技术,接下来咱们都简单了解一下吧

重要知识点:HSV、HUE

  • HSV:如下图,HSV是一种直观的颜色空间,把色调分布到一个圆盘上,Hue表示角度,所以Hue的值就代表一个具体的色调,然后,Saturation看做饱和度(我的感觉是添加黑色),把Value看做亮度(我的感觉是添加白色),刚才提到的Hue分量,其实就是指Hue的值,(Saturation和Value的值在后面的算法中不会用到)
  • 再来仔细看看圆盘中Hue的值对应的色调:

重要知识点:反向投影

  • 在使用JavaCV的CamShift算法API时,最重要的入参就是反向投影,每一帧最终都会被转成反向投影,也就是前面提到的用人脸Hue分量的直方图将第X帧转化成色彩概率分布图
  • 反向投影图是用输入图像的某一位置上像素值(多维或灰度)对应在直方图的一个bin上的值来代替该像素值
  • 反向投影在OpenCV中会经常见到,一般使用场景是在一个图像中查找特定图像的最匹配点或区域,或者说定位目标图像出现在指定图像的位置
  • 来看看用一张图片制作反向投影的过程,如下所示,先根据人脸得到直方图,然后对每一张图片都用这个直方图去计算出反向投影图(也就是拿着人脸直方图,去每一帧图片中计算人脸在此图片中的色彩概率分布),JavaCV为我们准备好了API(Imgproc.calcBackProject),我们只需准备好API所需参数即可:
  • 有了上面的流程,就能对每帧图片做反向投影,得到人脸在这张图片上的概率分布图,然后用MeanShitf算法对这个概率分布图做迭代计算,直到其收敛或者到达最大迭代次数,确定人脸在图片上的位置

重要知识点:CamShift算法

  • 实现人脸跟踪的关键是CamShift,全称ContinuouslyAdaptive Mean Shift,即连续自适应的MeanShift算法
  • Mean Shift算法是一种无参密度估计算法,不需要任何先验知识而完全依靠特征空间中样本点的计算其密度函数值,在很多领域都有成功应用,例如图像平滑、图像分割、物体跟踪等,本篇不会展开细说Mean Shift算法,就用下面这幅图简单说说,
  1. 上图每个圆心是一个质心,
  2. 以质心为原点画一个圆圈,圆圈内有很多红点
  3. 圆圈内每个点与圆心构成一个向量,把圆圈内向量相加,得到新的向量就是meanshift向量,即黄色箭头
  4. 以meanshift向量的重点为圆心,再画一个圆圈,在此圆圈内执行步骤3
  5. 不断重复上述过程,着该向量移动便能找到密度最大处,就是最终结果
  • 向量-> 移动 -> 向量 -> 移动,这和梯度下降有些相似之处啊
  • 以上就是meanshif算法,而将meanshift算法扩展到连续图像序列,就是camshift,它将视频的连续帧做meanshift
    计算,用上一帧结果作为下一帧meanshift算法搜索窗的初始值,来调整下一帧的中心位置和窗体大小,如此迭代下去,就可以实现对目标的跟踪。
  • 对应到OpenCV的实现中,就是输入一个图像(probImage),再输入一个开始迭代的窗口(window),以及迭代条件(criteria),而输出,就是迭代完成的位置(RotatedRect);

重要知识点:JavaCV对CamShift的支持

  • 关于核心功能的理论已经聊得七七八八了,再来看看JavaCV对核心知识点提供了哪些具体的API支持,如下表所示,前面涉及到的关键技术都覆盖到了:
序号 API 作用
1 Imgproc.cvtColor 从摄像头拿到的帧,其颜色空间是RGB格式的,需要转为HSV格式
2 Core.mixChannels 将HSV图片的Hue分量提取到另一个Mat中
3 Imgproc.calcHists 生成直方图
4 Imgproc.calcBackProject 生成反向投影
5 Video.CamShift 在反向投影图上执行CamShift计算
  • 至此,核心技术算是分析完了,但仅有核心技术是不够的,需要有主程序、分支逻辑、异常处理等诸多努力,才能实现完整的功能,接下来就以开发者的视角,开始咱们的开发设计
  • 首先要搞清楚的是:如何确定最初的那个人脸?

如何开局?

  • 在设计过程中,咱们要面临的第一个问题就是如何开局?换句话说:从哪里拿到人脸,用于生成直方图,并找好位置作为下一帧做CamShift计算的起始位置
  • 如果您之前在网上搜索过CamShift的文章,会发现大多都是用户用鼠标在预览窗口选定一个区域,然后程序取这个区域作为跟踪对象
  • 但是,欣宸这里不会沿用上述手动选择的方式,如果您之前看过《JavaCV的摄像头实战》系列,会发现该系列经常用到JavaCV提供的人脸检测功能,因此,咱们继续使用这个人脸检测功能来开局
  • 简单来说,当程序运行后,如果摄像头中出现了人脸,那么该人脸就被自动作为跟踪对象,会被计算Hue直方图,并且人脸位置也是下一帧做CamShift计算的起始位置
  • 为了简单起见,假设摄像头中只会出现一个人脸,代码处理也只针对一个人脸的场景
  • 如果您想了解人脸检测的更多细节,请参考《JavaCV的摄像头实战之八:人脸检测》

前文的完整功能分析(重要)

异常处理

  • 在实际运行过程中,可能会遇到以下六个问题:
  1. 提前准备必要文件之一,opencv在windows环境的动态链接库,下载地址(不用积分):https://download.csdn.net/download/boling_cavalry/75121158
  2. 提前准备必要文件之二,人脸检测的模型文件,下载地址:https://raw.github.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml
  3. native方法异常:BGR实例转为javacv的RGBA时,opencv_imgproc.cvtColor可能抛出异常,所以要注意捕获,避免程序退出
  4. JavaCV中,最常用的类来自org.bytedeco.opencv.opencv_core这个包,然而,在计算直方图、反向投影、CamShift的时候,大部分参数又来自org.opencv.core这个包,因此从摄像头取得的帧相关的数据对象,都要转换成另一个包下面的同名对象,才能顺利的执行人脸跟踪操作
  5. 人脸跟踪的时候,如何判断跟丢了?正常情况下,CamShift返回的是一个有效的矩形,人不再出现的帧,CamShift计算其反向投影的时候,返回的矩形的长和宽都小于等于零,但实际测试的时候,发现人脸消失后,CamShift还可能返回一个很小的矩形,这显然是必须要丢弃的,因此,判断是否跟丢的逻辑,我这里就改成:长或者宽比上一次的变化率是否超过百分八十,实测效果尚可,您也可以自行调整这个参数
  6. 假设人脸检测的结果是50*60的矩形,能将整个人脸包括在此矩形中,但CamShift计算得到的矩形就未必是50*60了,一般高度会更大,导致将人脸之下的脖子也包括进来,而且头发上面会包括进来,此刻,您可以按照自己的业务需求来调整这个矩形,我这里是将位置向下移动(不把头发包括进来),再把宽度的值设置成高度,这样看起来与人脸检测的结果比较接近,调整前后的效果如下图所示:
  • 以上就是之前的开发过程中遇到的典型问题,可见如果没有事先准备,怕是每个问题都能将爱学习的您折磨得痛苦不堪…

期待下一篇的实战(虎年贺岁作品)

  • 至此,图文并茂的设计篇已全部完成,和愉快的编码相比,这种设计和准备工作既枯燥且辛苦,但却是一个功能健全的应用不可或缺的一部分,只希望本篇能为您提供足够的理论知识信息,让咱们在下一篇的编码实战中做到胸有成竹,下笔如有神助
  • 新年即将到来,欣宸原创虎年贺岁作品:《Java版人脸跟踪三部曲之三:编码实战》,敬请期待~

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

Java版人脸跟踪三部曲之二:开发设计相关推荐

  1. Java版人脸跟踪三部曲之三:编码实战

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <Java版人脸跟踪三部曲>全文链接 &l ...

  2. Java版人脸检测详解下篇:开发java应用并做成docker镜像

    本篇概览 如果您看过<Java版人脸检测上篇>一文,甚至动手实际操作过,那么你应该会对背后的技术细节感兴趣,开发这样一个应用,咱们总共要做以下三件事: 1.准备好docker基础镜像 2. ...

  3. Java版人脸检测详解上篇:运行环境的Docker镜像(CentOS+JDK+OpenCV)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 如果您看过<三分钟极速体验:Java版 ...

  4. Java版人脸检测详解下篇:编码

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 如果您看过<三分钟极速体验:Java版 ...

  5. 三分钟极速体验:Java版人脸检测

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 检测照片中的人脸,用Java可以实现吗? 当 ...

  6. 视频教程-企业微信支付JAVA版_向员工收款-微信开发

    企业微信支付JAVA版_向员工收款 微信企业号星级会员.10多年软件从业经历,国家级软件项目负责人,主要从事软件研发.软件企业员工技能培训.已经取得计算机技术与软件资格考试(软考)--"信息 ...

  7. Java版 人脸识别SDK demo

    2019独角兽企业重金招聘Python工程师标准>>> 虹软人脸识别SDK之Java版,支持SDK 1.1+,以及2.0版本,滴滴,抓紧上车! 前言 由于业务需求,最近跟人脸识别杠上 ...

  8. java 员工轮询值班排班 开发设计(mysql+redis)

    JAVA 员工轮询 值班 排班 1.设计一个值班历史纪录表 duty_employee_history(area_id,dept_id) 联合主键,存放已值班过的数据 area_id int(11) ...

  9. 数据结构Java版之排序算法(二)

    排序按时间复杂度和空间复杂度可分为 低级排序 和 高级排序 算法两种.下面将对排序算法进行讲解,以及样例的展示. 低级排序:冒泡排序.选择排序.插入排序. 冒泡排序: 核心思想,小的数往前移.假设最小 ...

最新文章

  1. C和指针之字符串编程练习8实现char *my_strnchr(char const *str, int ch, int which)
  2. 优秀程序员的两大要素:懒 + 笨
  3. 【英语学习】【WOTD】teem 释义/词源/示例
  4. Linux查ip出来的pp0,linux下使用shell查看apache IP访问量
  5. Spring整合ActiveMQ之嵌入(二)
  6. IBM Rational DOORS通过DXL进行二次开发
  7. 加工中心宏程序c语言,加工中心最实用的宏程序
  8. 联想昭阳K22-80机器关闭或开启触摸板方法
  9. 商业网站建设和运营的四度:Approachability、Usability、 Accessibility 和 Profitability...
  10. 3d Max人物动画学习笔记(一) 骨骼创建
  11. 【蓝桥杯刷题冲刺辅导】掌握递归·DFS解题套路,这一文足以?
  12. 【算法设计与分析】-- 分治法
  13. cron crontab anacron anacrontab Linux下的计划任务
  14. (三)基于Multisim的电台发射系统:高频功率放大器的设计
  15. opencv读取图像的灰度值并显示出来
  16. 基于Python疫苗预约系统设计与实现 开题报告
  17. linux源文件配置及操作
  18. vdisk 的缓存系统设计
  19. html中列表菜单加文字请选择,html中下拉菜单
  20. 海量遥感数据处理与GEE云计算技术应用

热门文章

  1. 科研(research)与研发(RD)思维有什么区别?
  2. 一级建造师(石油化工)考试系统_金桥考试虫 v2.0 官方
  3. 聊聊HashMap红黑扩容和树化的时机
  4. struct ethhdr、ether_header、iphdr、tcphdr、udphdr
  5. 【计算机】可信平台模块Trusted Platform Module - TPM
  6. 被逼急的小红书在拿品牌开刀
  7. 前端使用百度地图搜索
  8. 前任3:由圣经故事通天塔想到公司部门间沟通协作
  9. MacDown如何设置代码高亮
  10. MacDown 编辑器 使用