以前在论坛、微博经常看到一张脸,五官长得像A,脸型似乎又是B,觉得很有意思。

比如像这张图片。这张图片应该是网友用Photoshop完成的,他们取了郭大爷的五官,放在金元帅的脸上,在把边缘处理平滑。

而上面这张图片是另外一种效果,它不仅改变了五官,连脸型轮廓也一起改变了。这种技术称为face morphing,这篇随笔就聊一聊它吧。

Morphing是指把一张照片变换成另一张照片,中间的变换过程如行云流水一般自然。

Cross-Disolve

最方便的方法是像素值叠加,第一幅照片的像素值乘以系数k,加上第二幅照片的对应像素值乘以系数(1-k)。这个方法尽管操作方便,但是效果并不好。首先,要把两幅照片的尺寸调整到一样大小,然后图像中主要内容的位置也应该保持一致,否则直接叠加会形成虚影。

Feature-based Morphing

Beier和Neely对这个方法做了改进,他们提出了一种基于特征的图像变换新方法。

假设目标图像里有一条直线PQ表示施瓦辛格的鼻梁,在源图像里小布什的鼻梁是P'Q'。那么我们就可以得到一个函数对应关系P'(x,y) = f(P(x,y)), Q'(x,y) = f(Q(x,y)). 而图像里的其它任意点X则可以根据PQ和P'Q'的关系来推算。

如果只用这一对特征线段来计算,那么在线段附近的区域可以很好的预测,稍远的区域就难以估计了。于是,可以选择多条特征线段,比如眼眶、发际线、下巴、领口等区域。多对线段和一对线段的方法类似,根据前面一对特征线段的方法,点X对每一对线段PiQi都计算得到一个点Xi,同时按照点X和线段PQ距离的远近得到一个权重值wi,距离越远权重越小。最后,X= Σwi*Xi。对于照片上的每一个像素X(x,y)都做这个运算,就得到了合成图像。

Mesh-based Morphing

另一种方法是基于网格的变换,它的思路就是在源图像和目标图像上标注若干对应的特征点,按照特征点把整张图像分割成若干块三角形区域。为保证五官在变换中的完整,五官和脸的轮廓应该多放置特征点,但是过多的特征点又会使运算速度降低。图像A的特征点数目和图像B特征点的数目是一致的,所以可以按照PC = α*PA + (1-α)*PB 的公式融合生成特征点在新图像中的位置。α∈[0,1]表示图像A对新图像的贡献率,α=1时新图像就是图像A。

下一步,用inverse warping的方法,找出图像C的点在图像A和图像B的对应位置。用插值的方法求出在图像A和图像B的像素值。同样按照PC = α*PA + (1-α)*PB 的公式将两者混合。

上面三张照片是α=0.25, 0.56, 0.75时的效果。

比较

Cross-Disolve方法最简单,但是效果不好。Feature-based Morphing方法直观,容易理解,实现也比较方便,但是如果取得特征线段不好,会有“意外效果”出现。Mesh-based Morphing方法人工选择特征点的过程略微复杂,但是效果比较好。

附Matlab代码:

A = imread('imA.jpg');
height = size(A,1);
width = size(A,2);

imshow(A);
[xA,yA] = ginput(64);
xA = [xA;1;width;width;1];
yA = [yA;1;1;height;height];

B = imread('C:\ZHYH\code\pic\wb.jpg');
imshow(B);
[xB,yB] = ginput(64);
xB = [xB;1;width;width;1];
yB = [yB;1;1;height;height];

alpha = 0.75;

C = zeros(height,width,3);
xC = alpha*xA + (1-alpha)*xB;
yC = alpha*yA + (1-alpha)*yB;
triC = delaunay(xC,yC);
ntri = size(triC,1);

xCA = zeros(height,width);
yCA = zeros(height,width);
xCB = zeros(height,width);
yCB = zeros(height,width);

[X,Y] = meshgrid(1:width,1:height);

for k = 1:ntri
[w1,w2,w3,r] = inTri(X, Y, xC(triC(k,1)), yC(triC(k,1)), xC(triC(k,2)), yC(triC(k,2)), xC(triC(k,3)), yC(triC(k,3)));
w1(~r)=0;
w2(~r)=0;
w3(~r)=0;
xCA = xCA + w1.*xA(triC(k,1)) + w2.*xA(triC(k,2)) + w3.*xA(triC(k,3));
yCA = yCA + w1.*yA(triC(k,1)) + w2.*yA(triC(k,2)) + w3.*yA(triC(k,3));
xCB = xCB + w1.*xB(triC(k,1)) + w2.*xB(triC(k,2)) + w3.*xB(triC(k,3));
yCB = yCB + w1.*yB(triC(k,1)) + w2.*yB(triC(k,2)) + w3.*yB(triC(k,3));
end

VCA(:,:,1) = interp2(X,Y,double(A(:,:,1)),xCA,yCA);
VCA(:,:,2) = interp2(X,Y,double(A(:,:,2)),xCA,yCA);
VCA(:,:,3) = interp2(X,Y,double(A(:,:,3)),xCA,yCA);

VCB(:,:,1) = interp2(X,Y,double(B(:,:,1)),xCB,yCB);
VCB(:,:,2) = interp2(X,Y,double(B(:,:,2)),xCB,yCB);
VCB(:,:,3) = interp2(X,Y,double(B(:,:,3)),xCB,yCB);

C = alpha*VCA + (1-alpha)*VCB;
imshow(uint8(C));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% inTri checks whether input points (vx, vy) are in a triangle whose
% vertices are (v0x, v0y), (v1x, v1y) and (v2x, v2y) and returns the linear
% combination weight, i.e., vx = w1*v0x + w2*v1x + w3*v2x and
% vy = w1*v0y + w2*v1y + w3*v2y. If a point is in the triangle, the
% corresponding r will be 1 and otherwise 0.
%
% This function accepts multiple point inputs, e.g., for two points (1,2),
% (20,30), vx = (1, 20) and vy = (2, 30). In this case, w1, w2, w3 and r will
% be vectors. The function only accepts the vertices of one triangle.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [w1,w2,w3,r] = inTri(vx, vy, v0x, v0y, v1x, v1y, v2x, v2y)
v0x = repmat(v0x, size(vx,1), size(vx,2));
v0y = repmat(v0y, size(vx,1), size(vx,2));
v1x = repmat(v1x, size(vx,1), size(vx,2));
v1y = repmat(v1y, size(vx,1), size(vx,2));
v2x = repmat(v2x, size(vx,1), size(vx,2));
v2y = repmat(v2y, size(vx,1), size(vx,2));
w1 = ((vx-v2x).*(v1y-v2y) - (vy-v2y).*(v1x-v2x))./...
((v0x-v2x).*(v1y-v2y) - (v0y-v2y).*(v1x-v2x)+eps);
w2 = ((vx-v2x).*(v0y-v2y) - (vy-v2y).*(v0x-v2x))./...
((v1x-v2x).*(v0y-v2y) - (v1y-v2y).*(v0x-v2x)+eps);
w3 = 1 - w1 - w2;
r = (w1>=0) & (w2>=0) & (w3>=0) & (w1<=1) & (w2<=1) & (w3<=1);
end

图像处理之face morphing的更多相关文章

  1. Atitit 图像处理和计算机视觉的分类 三部分 图像处理 图像分析 计算机视觉

    Atitit 图像处理和计算机视觉的分类 三部分 图像处理 图像分析 计算机视觉 1.1. 按照当前流行的分类方法,可以分为以下三部分:三部分 图像处理 图像分析 计算机视觉1 1.2. 图像处理需要 ...

  2. Atitit 图像处理的摩西五经attilax总结

    Atitit 图像处理的摩西五经attilax总结 1. 数字图像处理(第三版)1 2. 图像处理基础(第2版)(世界著名计算机教材精选)1 3. 计算机视觉特征提取与图像处理(第三版)2 4. Op ...

  3. Atitit 图像处理的心得与疑惑 attilax总结

    Atitit 图像处理的心得与疑惑 attilax总结 1.1. 使用类库好不好??还是自己实现算法1 1.2. 但是,如果遇到类库体积太大,后者没有合适的算法,那就只能自己开发算法了1 1.3. 如 ...

  4. Atitit 图像处理 调用opencv 通过java  api   attilax总结

    Atitit 图像处理 调用opencv 通过java  api   attilax总结 1.1. Opencv java api的支持 opencv2.4.2 就有了对java api的支持1 1. ...

  5. Atitit MATLAB 图像处理 经典书籍attilax总结

    Atitit MATLAB 图像处理 经典书籍attilax总结 1.1. MATLAB数字图像处理1 1.2. <MATLAB实用教程(第二版)>((美)穆尔 著)[简介_书评_在线阅读 ...

  6. Atitit 图像处理类库大总结attilax qc20

    Atitit 图像处理类库大总结attilax qc20 1.1. 选择与组合不同的图像处理类库1 1.2. Halcon 貌似商业工具,功能强大.1 1.3. Openvc  Openvc功能也是比 ...

  7. Atitit MATLAB 图像处理attilax总结

    Atitit MATLAB 图像处理attilax总结 1.1. 下载 Matlab7.0官方下载_Matlab2012 v7.0 官方简体中文版-办公软件-系统大全.html1 1.2. Matla ...

  8. 使用MATLAB对图像处理的几种方法(下)

     试验报告 一.试验原理: 图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境.灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对 ...

  9. 使用MATLAB对图像处理的几种方法(上)

    实验一图像的滤波处理 一.实验目的 使用MATLAB处理图像,掌握均值滤波器和加权均值滤波器的使用,对比两种滤波器对图像处理结果及系统自带函数和自定义函数性能的比较,体会不同大小的掩模对图像细节的影响 ...

随机推荐

  1. Sticks(poj1011/uva307)

    题目大意: 乔治有一些碎木棒,是通过将一些相等长度的原始木棒折断得到的,给出碎木棒的总数和各自的长度,求最小的可能的原始木棒的长度:(就是将一些正整数分组,每组加起来和相等,使和尽可能小) 一开始做p ...

  2. [开发笔记]-“在引用COM组件时,出现了无法嵌入互操作类型。。。”的错误

    这两天在做一个需要将wps文档转换成word文档的程序,在调用wps的com组件时项目编译是没有问题的,但当运行的时候却弹出了下面的错误提示: 从网上百度一番后,找到了正确的解决方法. 先从Com组件 ...

  3. jquery easyui DataGrid 动态的改变列显示的顺序

    $.extend($.fn.datagrid.methods,{ columnMoving: function(jq){ return jq.each(function(){ var target = ...

  4. HDU 2586 LCA

    题目大意: 多点形成一棵树,树上边有权值,给出一堆询问,求出每个询问中两个点的距离 这里求两个点的距离可以直接理解为求出两个点到根节点的权值之和,再减去2倍的最近公共祖先到根节点的距离 这是自己第一道 ...

  5. Linux摄像头驱动学习之:(二)通过虚拟驱动vivi分析摄像头驱动

    一.通过指令 "strace -o xawtv.log xawtv" 得到以下调用信息:// 1~7都是在v4l2_open里调用1. open2. ioctl(4, VIDIOC ...

  6. mybatis ForEach Collection集合等规范解析(转)

    转自:http://blog.csdn.net/wj3319/article/details/9025349 在SQL开发过程中,动态构建In集合条件查询是比较常见的用法,在Mybatis中提供了fo ...

  7. Oracle GoldenGate 12c中的协同交付(Coordinated Delivery)

    OGG 12c中,并行交付有2种模式:集成交付.协同交付.不过集成交付只能针对目标端是oracle数据库(有版本要求)使用,而协同交付则可以在非oracle数据库上使用. 先来看2个问题, l 为什么 ...

  8. Canopy测试IPython控制台输出

    Canopy测试IPython控制台输出

  9. 进行以上Java编译的时候,出现unmappable character for encoding GBK。

    public class Exerc02{ public static void main(String args []){ char c = '中国人'; System.out.pingtln(c) ...

  10. Effective C++ ----以对象管理资源

    以对象管理资源 通过对象的析构函数的自动调用来自动释放资源 第一部分:几种典型的以对象管理资源的例子 1. STL::auto_ptr 获取资源后立刻放入资源管理对象 std::auto_ptr< ...