前言

在很多美颜相机啊,抖音啊,都会有一些放大眼睛的效果,今天就来实现如何放大眼睛。

思路

1、首先使用OpenCV定位到人脸
2、根据定位到的人脸去检测人脸关键点,进而获取到人眼睛的位置。
3、根据眼睛位置,对眼睛进行放大。

实现

定位人脸

人脸的定位追踪,在之前文章中已经写过OpenCv实现人脸追踪 当时是在xCode上写的,把里面的代码移植到Android中就可以了,这个是C写的,所以需要移植到JNI中。这里的人脸模型,我采用的是OpenCV中提供的,当然也可以自己去训练模型。

检测人脸关键点

人脸关键点的检测,有很多三方的sdk,比如说face++等等,都是要收费的,face++是检测了68个关键点,这68个关键点都不是随意分布的,都是有规律的。如下图:

但是像face++这种,都是需要收费的,我从GitHub上找了一个免费的叫SeetaFaceEngine它这个里面有三个模块:人脸检测模块(SeetaFace Detection)、面部特征点定位模块(SeetaFace Alignment)以及人脸特征提取与比对模块(SeetaFace Identification)。这里我用到的是SeetaFace Alignment,用来检测人脸的关键点。

它这里面并不是定位了68个关键点,而是定位了5个关键点,即左眼(0)、右眼(1)、鼻子(2)、嘴巴左边(3)、嘴巴右边(4),这个分布也是有规律的,并不是随便的点。代码如下:将定位到的人脸,送去进行关键点的检测

  if (faces.size()){Rect face = faces[0];rects.push_back(Rect2f(face.x,face.y,face.width,face.height));//关键点定位//保存5个关键点//0:左眼 1:右眼 2:鼻头 3:嘴巴左边,4 :嘴巴右边seeta::FacialLandmark points[5];//图像数据seeta::ImageData image_data(src.cols,src.rows);image_data.data = src.data;//指定人脸部位 去定位眼睛seeta::FaceInfo faceInfo;seeta::Rect bbox; //是一个矩形边框,用来微调定位到的人脸的窗口,有时候可能会定位的不准确bbox.x = face.x;bbox.y = face.y;bbox.width = face.width;bbox.height = face.height;faceInfo.bbox = bbox;// 定位人脸关键点方法,第一个参数是你需要检测的灰度图,// 第二个参数是The face bounding box,脸部边框// 第三个参数是检测到的关键点集合faceAlignment->PointDetectLandmarks(image_data,faceInfo,points);for (int i = 0; i < 5; ++i) {//把点放入集合中 ,点是没有宽和高的rects.push_back(Rect2f(points[i].x,points[i].y,0,0));}}
放大眼睛

这里是根据网上论文中的一个公式实现的,http://www.gson.org/thesis/warping-thesis.pdf, 大概在45页左右有个这样的描述,以及公式,就是根据这个来实现的。

4.4.2. Local scaling warps
The mapping used for a local scaling warp maps each point within the area
of influence onto a point in the source image whose distance vector from
the center of the area has the same orientation as that in the destination
image but whose length is a function fs® of the length r of the vector
The function chosen for fs®
where the parameter a is controlled by the current horizontal position of
the mouse ranging from when the mouse is at the left edge of the
area of interest to when the mouse is at the right edge of the area of
interest Note that the function reduces to the identity function fs® = r
when a =0.In Figure the function f(s)r for rmax has been plotted for a number of values of a in the range

这个公式是什么意思呢?这个公式求出的值是采集的改变后的点距离眼睛中心点的位置,rmax表示的是最大放大的区域,r表示原来的点距离眼睛中心点的位置,a表示的是放大系数,所以当a=0的时候,公式的结果就是r,也就是没有变化,不放大。
原理是什么呢,就是在片元着色器,把眼睛周边的需要放大的点取值成对应的眼睛内部的点的值,然后把这个值的坐标赋值给gl_FragColor,这样就完成了眼睛的放大;
片元着色器:

// r:原来的点距离眼睛中心点的位置
//rmax: 放大区域
float fs(float r,float rmax){//放大系数float a = 0.4;return (1.0 - pow((r/rmax -1.0),2.0) *a);
}//根据需要采集的点 aCoord 计算新的点(可能是需要改变为眼睛内部的点,完成放大的效果)
vec2 newCoordDistance(vec2 coord,vec2 eye,float rmax){vec2 newCoord = coord;//获得当前需要采集的点与眼睛的距离//distance是glsl中的内置函数float r = distance(coord,eye);//在范围内 才放大if(r < rmax){//想要方法需要采集的点 与 眼睛中心点的距离float fsr = fs(r,rmax);// 新点-眼睛 / 老点-眼睛 = 新距离/老距离//(newCoord  - eye) / (coord-eye) = fsr/r;//(newCoord  - eye) = fsr/r * (coord-eye)newCoord = fsr * (coord - eye) +eye;}return newCoord;
}
void main(){//最大作用半径 rmax//计算两个点的距离float rmax = distance(left_eye,right_eye)/2.0;// 如果属于 左眼 放大区域的点 得到的就是 左眼里面的某一个点(完成放大效果)// 如果属于 右眼放大区域的点 或者都不属于 ,那么 newCoord还是 aCoordvec2 newCoord= newCoordDistance(aCoord,left_eye,rmax);newCoord = newCoordDistance(newCoord,right_eye,rmax);//  采集到 RGBA 值gl_FragColor = texture2D(vTexture,newCoord);
}

效果图

用最爱的明星做个效果图,可以看出来眼睛部位是有明显的放大的

Android OpenGLES滤镜开发之大眼效果相关推荐

  1. Android OpenGLES滤镜开发之贴纸效果

    前言 上一篇中写到了如何实现放大眼睛的效果,这一篇实现贴纸效果,就像那个faceu相机,b612相机,还有抖音都会有的这种贴纸效果. 思路 1.贴纸肯定也是需要定位到人脸的 2.找到贴纸需要放置的位置 ...

  2. android贴纸效果,Android OpenGLES滤镜开发之贴纸效果

    思路 1.贴纸肯定也是需要定位到人脸的 2.找到贴纸需要放置的位置 3.将贴纸纹理和人本身纹理进行融合 实现 人脸定位啥的,我就不说了,不清楚的可以去前面的文章看看,主要来看看贴纸是如何贴上去的 2. ...

  3. Android OpenGLES滤镜开发之仿抖音灵魂出窍

    前言 前几篇写的滤镜效果比如美颜.大眼.贴纸效果都是在录制视频之前,这个灵魂出窍的效果是在录制视频之后,可以对视频添加效果. 思路 可以观察到灵魂出窍的效果,其实其主图像本没有什么变化,只是新增了一张 ...

  4. Android音视频开发从入门到精通,我这一路走来的经验分享

    前不久,在国家统计局针对北京市进行的农民工市民化状况进行的调研中,从事信息技术,软件技术等IT服务业的人员也被当做农民工. 编程的门槛不高,薪资水平也还可观.这一直是"三百六十行,行行转IT ...

  5. 《Android 美颜类相机开发汇总》第五章 Android OpenGLES 美颜定制实现

    在介绍美颜定制之前,我们先来复习一下OpenGL中图像绘制原理.OpenGL的图像绘制,是由许许多多三角形构成的.OpenGL的绘制离不开三角形的绘制.通常对于不需要对图像细节进行处理的时候,我们一般 ...

  6. Android开发_android界面效果全汇总

    (一)Activity页面切换的效果 先介绍下左右滑动切换Activity,对于复杂的手势原理一样,具体后述. 主要原理为监控触屏事件和手势事件,在触屏事件处理函数中调用手势事件处理函数,表示用户触屏 ...

  7. android 内置滤镜,Android滤镜开发(一) 开篇:关于滤镜

    滤镜 一般是由玻璃,树脂和聚碳酸酯等制成的物体,用来处理相机等传感器受到外界环境的影响,或者达到某种视觉效果.对于现在数字时代的图像,我们可以通过算法处理来达到以前镜片的效果 Android平台上的滤 ...

  8. Android折叠屏开发学习(三)---使用MotionLayout实现折叠屏分屏效果

    学更好的别人, 做更好的自己. --<微卡智享> 本文长度为6259字,预计阅读11分钟 前言 今天是折叠屏开发的第三篇,前面已经介绍了铰链的角度监听和Jetpack Window实现监听 ...

  9. Android动画开发——Animation动画效果

    动画类型 Android的animation由四种类型组成 XML中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画效果 translate 画面转换位置移动动画效果 rotate 画面 ...

最新文章

  1. 将深度学习低延迟推理性能提高一倍
  2. CSS3文本居中显示、圆形圆角绘制、立体阴影效果设置实例演示
  3. 太原理工软件学院c语言2020,太原理工软件工程C语言实验报告 数组.doc
  4. MSTP协议介绍和堆叠技术介绍
  5. 如何使用 Visual Studio Code 调试 Angular Schematics 实现
  6. php之isset() 、empty()、is_null()的区别
  7. 题解 AT934 【完全数】
  8. Java多线程第三节-线程的正确停止
  9. 深度学习 | MATLAB卷积神经网络原理描述
  10. zbbz插件使用教程_CAD坐标自动标注zbbz插件非常实用(附压缩包及安装步骤)
  11. 手机html己停用怎么办,iphone手机出现已停用请五分钟再试怎么办
  12. android 控制手机,如何用Android手机控制另一部手机[详细说明]
  13. 使用SQL管理数据库
  14. gensim中word2vec API参数说明
  15. Possible solution: - Disable offline mode and rerun the build
  16. 机房收费系统的退卡和结账
  17. MT2502 datasheet,MT2502硬件设计,MT2502芯片资料
  18. 优思学院|“共同原因“和“特殊原因“是什么?
  19. sumproduct 公式
  20. matlab starcat_维纳滤波和编码曝光PSF去除运动模糊【matlab】

热门文章

  1. doraemon的python(大更新) 实例讲解 图书管理系统的配置和应用
  2. chromium 编译
  3. ios pushViewController 页面不跳转问题解决
  4. 安卓 7.0 无法获取外置SD卡问题解决方案 | Failed to find configured root that contains
  5. 全球最大的3D数据集公开了!标记好的10800张全景图 | 附论文
  6. 某银行计算机系统要实现一个电子,电子商务师练习题与答案
  7. 互联网公司的期权激励和期权估值问题
  8. Python 中堪称神仙的6个内置函数
  9. 由神秘到简单 教你在网页中添加微软地图
  10. 数组排列组合问题——BACKTRACKING