图像美容之眼睛放大算法。

   目前,手机上各种图像特效的软件应用App越来越盛行,比较有名如美图秀秀,camare360,美颜相机等,还有一些在某些特定的方向做的比较的优秀的如魔漫相机等。这些软件几乎无一例外的都提供了相当数量的针对人脸进行美化的功能,正是这些最基础的功能吸热了很多热血美女丑女中女的兴趣。以至于几乎我所认识的每个25-35之间的女性朋友都知道美图秀秀,而了解Photoshop的则微乎其微。不过最近听一些朋友谈到,认为手机上的图像软件已经过了开发的鼎盛期,也不晓得到底是不是这样。

    作为人脸中最有神的部位眼睛,自然是各软件开发商不会错过的美化对象,拿运行速度极差的可牛影像为例,他至少提供了眼睛放大、去红眼、祛黑眼圈、眼睛变色、加眼影等众多和眼睛有关的美容刀。其实这些,在程序开发者开来不过一些美妙的代码发言后绽放多多鲜花,可确是众多人为之用之美容的神器。

    但是,这些简单的功能,送之于百度或这个google搜索相关算法,能找到想匹配的信息量真的不多,最起码我没找到可以直接用之于实践的东西。

    本文就共享一些我关于眼睛缩放这个问题的一些研究成果,这些研究是3年前进行的。

    正规的来说,眼睛缩放属于图像的一种局部扭曲,关于扭曲,Photoshop中的液化滤镜最能体现这类算法的灵魂。眼睛缩放完全可以用其中的一种方式来实现,如下图所示:

    (为节省篇幅,旋转了下)

    使用该膨胀工具,选择合适的参数能得到非常理想的效果,但是如果仅仅为了这个功能区研究庞大的液化滤镜的算法,是极其需要勇气的精力的。虽然目前在开源内的软件中可以从GIMP的Iwarp代码或者paint.net的一个smudgle插件通过反编译的方式得到代码参考学习,但是这个过程是比较痛苦的,因为我因为痛苦过一次了,这里分享一个简单的方式去实现他,就减轻大家的痛苦了吧。

    在手动的眼睛缩放过程中,一般有三个参数:中心点、画笔大小、力度,我们分别用(PointX,PointY),Radius,Strength表示。比如美图提供了如下的用户界面:

  中心点是用户通过鼠标单击获得的,画笔的大小决定了算法所影响到的范围。力度影响眼睛放大的程度。

  我的算法是通过如下图所示的简单过程实现的。

  对于画笔半径以内的任一位置像素(X,Y),按照其所在的位置和半径之间的比值,根据强度的设定值按照某个线性的公式,从经过点(PointX,PointY)和(X,Y)的直线中选择一个位置像素作为新的像素值,如果这个新的位置位于两点之间(图中X1,Y1),则出现眼睛缩小的效果,而位于直线的延长线上(图中的X2,Y2),则会有眼睛放大的效果,用一段简单的代码表示就是:

    Left = IIf(PointX - Radius < 0, 0, PointX - Radius)                     '  计算边界值
    Top = IIf(PointY - Radius < 0, 0, PointY - Radius)
    Right = IIf(PointX + Radius >= m_Width, m_Width - 1, PointX + Radius)
    Bottom = IIf(PointY + Radius >= m_Height, m_Height - 1, PointY + Radius)
    PowRadius = Radius * Radius

    For Y = Top To Bottom
        OffSetY = Y - PointY
        For X = Left To Right
            OffsetX = X - PointX
            XY = OffsetX * OffsetX + OffSetY * OffSetY                      '   距离的平方
            If XY <= PowRadius Then                                         '   在指定的半径内
                ScaleFactor = 1 - XY / PowRadius
                ScaleFactor = 1 - Strength / 100 * ScaleFactor              '   按照这种关系计算取样点的位置
                PosX = OffsetX * ScaleFactor + PointX
                PosY = OffSetY * ScaleFactor + PointY
                If PosX < 0 Then                                            '   放置越界
                    PosX = 0
                ElseIf PosX >= m_Width Then
                    PosX = m_Width - 1
                End If
                If PosY < 0 Then
                    PosY = 0
                ElseIf PosY >= m_Height Then
                    PosY = m_Height - 1
                End If
                Speed = Y * m_Stride + X * 3
                Index = PosY * m_Stride + PosX * 3
                ImageData(Speed) = ImageDataB(Index)                        '将当前点的值赋值为取样点的值
                ImageData(Speed + 1) = ImageDataB(Index + 1)
                ImageData(Speed + 2) = ImageDataB(Index + 2)
            End If
        Next
    Next

  我没有提供的完整的代码,是因为真正懂的人只要从只言片语就能搞清楚,而那些伸手党在我这里是不收欢迎的。

  上述代码有很多可以改进的地方,第一,上述出现的结果会有些不清晰,只是 由于计算的取样的坐标实际上是浮点数,因此直接取整会带来较大的误差,较为合理的做法是利用双线性插值之类的插值算法进行计算优化。第二:线性映射的计算公式也可以做调整,比如调整成那种离眼珠越进的那些像素的变化越小,而越远的变换越大等。

       效果如下图:

      按照上述细路写了个测试程序:http://files.cnblogs.com/Imageshop/ZoomEyes.rar

****************************作者: laviewpbt   时间: 2014.7.15    联系QQ:  33184777 转载请保留本行信息**********************

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户2442861的专栏

Caffe学习系列(23):如何将别人训练好的model用到自己的数据上

http://www.cnblogs.com/denny402/p/5137534.html

401
来自专栏上善若水

L003Linux和androidNDK之linux好玩的命令

你可能了解 ‘ls’ 命令,并经常使用它来查看文件夹的内容。但是,有些时候你可能会拼写成 ‘sl’ ,这时我们应该如何获得一些乐趣而不是看见“command n...

863
来自专栏帮你学MatLab

《Experiment with MATLAB》读书笔记(六)

读书笔记(六) 这是第六部分绘图 主要通过绘制分形图案展示绘图命令 function fern shg %显示画图界面 clf reset %清...

2626
来自专栏人工智能头条

EC2上的深度学习:CUDA 7/cuDNN/caffe/DIGITS实战教程

1484
来自专栏ATYUN订阅号

OpenAI-人工反馈的深度学习

rl-teacher是“Deep Reinforcement Learning from Human Preferences”的实现。 这个系统允许你教一个强化...

3546
来自专栏生信技能树

如何选择聚类模块数目

一般来说,类似K-means聚类算法需要我们提取指定聚类得到的cluster数目。 那么问题来了,如何为聚类选择一个适合的cluster数目呢 ? 很遗憾,上面...

56810
来自专栏尾尾部落

mac OS 安装XGBoost

XGBoost是一种基于决策树(CART)的分布式的高效的梯度提升算法,它可被应用到分类、回归、排序等任务中,与一般的GBDT算法相比,XGBoost主要有以下...

784
来自专栏YoungGy

MMD_6b_DecisionTree

overview ? construct 构建决策树的时候需要考虑以下问题: 什么时候停止 如果不停止,那么以什么变量的什么特征构建二叉树 如果停止,那么预测的...

1777
来自专栏AI研习社

一个应用于物体识别的迁移学习工具链

迁移学习指的是,通过对预训练模型的参数进行微调,将训练好的模型应用到相似或者只有细微差异的不同任务中。通过这个方法,我们可以基于一些性能顶尖的深度学习模型得到别...

812
来自专栏ATYUN订阅号

Machine Box创始人教你快速建立一个ML图像分类器

AiTechYun 编辑:Yining Machine Box的创始人Mat Ryer在medium上分享了一篇博文,意在教你在硬盘上快速的建立一个机器学习图像...

3306

扫码关注云+社区