卡通图像变形算法(Moving Least Squares)附源码
本文介绍一种利用移动最小二乘法来实现图像变形的方法,该方法由用户指定图像中的控制点,并通过拖拽控制点来驱动图像变形。假设p为原图像中控制点的位置,q为拖拽后控制点的位置,我们利用移动最小二乘法来为原图像上的每个像素点v构建相应的仿射变换lv(x),并通过该变换来计算得到图像变形后的位置:
其中权重wi的表达式为wi = 1/|pi - v|2α。
仿射变换lv(x)由两部分组成lv(x) = xM + T,其中M为线性转换矩阵,T为平移量。事实上将最小化表达式对变量T求偏导后可以得到T的表达式T = q* - p*M,其中p* = ∑wipi/∑wi,q* = ∑wiqi/∑wi。
于是仿射变换可以化简为lv(x) = (x - p*)M + q*,而最小化表达式可以变化为:
其中,
。
注意移动最小二乘法并未对转换矩阵M进行条件限制,如果添加其他限制条件后,能得到不同形式的转换矩阵M,文章根据不同的转换矩阵M提出了三种变形方法:仿射变形(Affine Deformation)、相似变形(Similarity Deformation)和刚性变形(Rigid Deformation),下面分别介绍这三种方法。
- 仿射变形(Affine Deformation)
仿射变形是利用经典正规方程对最小化表达式直接求解得到的结果:
有了旋转矩阵M的表达式后,我们得到变形的表达式:
由于用户是通过控制q的位置来实现图像变形,而p的位置是固定不变的,因此上式中大部分内容可以预先计算并保存,从而提高运算速度,重写变形表达式如下:
其中。
% Precomputing the affine deformation:
function data = Precompute_Affine(p,v,w)
% Computing pstar:
pstar = Precompute_pstar(p,w); % Precomputing the first matrix:
M1 = v - pstar; np = size(p,);
nv = size(v,);
% Iterating on points:
phat = cell(,np);
M2 = zeros(,,nv);
for i = :np
% Computing the hat points:
phat{i} = bsxfun(@minus, p(i,:), pstar); % Computing the matrix elements:
M2(,,:) = M2(,,:) + permute(w(:,i).*phat{i}(:,).^, [,,]);
M2(,,:) = M2(,,:) + permute(w(:,i).*phat{i}(:,).*phat{i}(:,), [,,]);
M2(,,:) = M2(,,:);
M2(,,:) = M2(,,:) + permute(w(:,i).*phat{i}(:,).^, [,,]);
end % Computing the inverse:
nv = size(v,);
IM2 = mmx('backslash', M2, repmat(eye(), [,,nv])); % Computing the first product elements:
F1 = [sum(M1.*squeeze(IM2(:,,:))',2), sum(M1.*squeeze(IM2(:,2,:))',)]; % Computing the A values:
A = zeros(nv,np);
for i = :np
A(:,i) = sum(F1.*phat{i},).*w(:,i);
end % The data structure:
data.A = A;
end
- 相似变形(Similarity Deformation)
由于仿射变形包含非均匀缩放,因此其变形效果不是很好。相似变形是仿射变形的一个特殊子集,它的变形效果只包含平移、旋转和均匀缩放,我们限制转换矩阵M使其满足MTM = λ2I,根据该条件得到相似变形的转换矩阵M如下:
其中。
与仿射变形一样,我们提取出可以预先计算的部分后得到变形表达式:
其中。
% Precomputing the similar deformation:
function data = Precompute_Similar(p,v,w)
% Computing pstar:
pstar = Precompute_pstar(p,w); np = size(p,);
nv = size(v,);
% Iterating on points:
phat = cell(,np);
mu = zeros(nv,);
for i = :np
% Computing the hat points:
phat{i} = bsxfun(@minus, p(i,:), pstar); % Updating the values of mu:
mu = mu + w(:,i).*sum(phat{i}.^,);
end % Computing the matrix A:
A = cell(,np); R1 = v - pstar;
R2 = [R1(:,),-R1(:,)];
for i = :np
L1 = phat{i};
L2 = [L1(:,),-L1(:,)]; % [col1 col2]
% [col3 col4]
A{i} = [w(:,i).*sum(L1.*R1,), ...
w(:,i).*sum(L1.*R2,), ...
w(:,i).*sum(L2.*R1,), ...
w(:,i).*sum(L2.*R2,)];
end % Premultiplying A/mu:
for i = :np
A{i} = bsxfun(@rdivide, A{i}, mu);
end % The data structure:
data.A = A;
end
- 刚性变形(Rigid Deformation)
最近许多研究都是关于刚性变形,也就是说变形不含任何缩放效果,我们进一步限制转换矩阵M使其满足MTM = I,这样可以得到刚性变形,刚性变形的表达式如下:
其中,式中Ai表达式与相似变形中的Ai表达式相同。
% Precomputing the rigid deformation:
function data = Precompute_Rigid(p,v,w)
% Computing pstar:
pstar = Precompute_pstar(p,w); np = size(p,);
% Iterating on points:
phat = cell(,np);
for i = :np
% Computing the hat points:
phat{i} = bsxfun(@minus, p(i,:), pstar);
end % Computing the matrix A:
A = cell(,np); R1 = v - pstar;
R2 = [R1(:,),-R1(:,)];
for i = :np
L1 = phat{i};
L2 = [L1(:,),-L1(:,)]; % [col1 col2]
% [col3 col4]
A{i} = [w(:,i).*sum(L1.*R1,), ...
w(:,i).*sum(L1.*R2,), ...
w(:,i).*sum(L2.*R1,), ...
w(:,i).*sum(L2.*R2,)];
end % The norm of v-pstar:
norm_v_pstar = sqrt(sum((v - pstar).^, )); % The data structure:
data.A = A;
data.norm_v_pstar = norm_v_pstar;
end
本文为原创,转载请注明出处:http://www.cnblogs.com/shushen
参考文献:
[1] Scott Schaefer, Travis McPhail, and Joe Warren. 2006. Image deformation using moving least squares. ACM Trans. Graph. 25, 3 (July 2006), 533-540.
卡通图像变形算法(Moving Least Squares)附源码的更多相关文章
- Python的开源人脸识别库:离线识别率高达99.38%(附源码)
Python的开源人脸识别库:离线识别率高达99.38%(附源码) 转https://cloud.tencent.com/developer/article/1359073 11.11 智慧上云 ...
- 8个前沿的 HTML5 & CSS3 效果【附源码下载】
作为一个前沿的 Web 开发者,对于 HTML5 和 CSS3 技术或多或少都有掌握.前几年这些新技术刚萌芽的时候,开发者们已经使用它们来小试牛刀了,如今这些先进技术已经遍地开发,特别是在移动端大显身 ...
- Android中Canvas绘图基础详解(附源码下载) (转)
Android中Canvas绘图基础详解(附源码下载) 原文链接 http://blog.csdn.net/iispring/article/details/49770651 AndroidCa ...
- 13行代码实现:Python实时视频采集(附源码)
一.前言 本文是<人脸识别完整项目实战>系列博文第3部分:程序设计篇(Python版),第1节<Python实时视频采集程序设计>,本章内容系统介绍:基于Python+open ...
- Web 开发中很实用的10个效果【附源码下载】
在工作中,我们可能会用到各种交互效果.而这些效果在平常翻看文章的时候碰到很多,但是一时半会又想不起来在哪,所以养成知识整理的习惯是很有必要的.这篇文章给大家推荐10个在 Web 开发中很有用的效果,记 ...
- 精选9个值得学习的 HTML5 效果【附源码】
这里精选了一组很酷的 HTML5 效果.HTML5 是现 Web 开发领域的热点, 拥有很多让人期待已久的新特性,特别是在移动端,Web 开发人员可以借助 HTML5 强大功能轻松制作各种交互性强.效 ...
- 使用 CSS3 实现 3D 图片滑块效果【附源码下载】
使用 CSS3 的3D变换特性,我们可以通过让元素在三维空间中变换来实现一些新奇的效果. 这篇文章分享的这款 jQuery 立体图片滑块插件,利用了 3D transforms(变换)属性来实现多种不 ...
- C#编程总结(七)数据加密——附源码
C#编程总结(七)数据加密——附源码 概述 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,使其只能在输入相应的密钥之后才能显示出本来内容 ...
- swfupload多文件上传[附源码]
swfupload多文件上传[附源码] 文件上传这东西说到底有时候很痛,原来的asp.net服务器控件提供了很简单的上传,但是有回传,还没有进度条提示.这次我们演示利用swfupload多文件上传,项 ...
随机推荐
- Java并发编程:Thread类的使用
Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...
- [moka同学收藏]Vim升华之树形目录插件NERDTree安装图解
无意中看到实验室的朋友使用的vim竟然能在左边显示树形目录,感觉很方便,这样子文件夹有什么文件一目了然.她说是一个插件叫NERDTree,安装执行后的效果如下,不是你想要的效果就别安了.我的系统是Ub ...
- Atitit利用反射获取子类 集合 以及继承树
Atitit利用反射获取子类 集合 以及继承树 想从父类往下找子类的确是不可能的,要知道只要类不是final的话谁都有继承它的自由不需要事前通知父类. Eclipse实现不是重父类开始找而是重子类往回 ...
- Https网站搭建——通过https://localhost:8443访问tomcat首页
图片大致介绍了Https浏览器与服务器握手的过程,涉及到的名词:证书.Hash算法.随机数密码.公钥加密.私钥解密.握手消息.hash验证.摘要 tomcat服务器配置可以实现https双向认证,简单 ...
- 轻松掌握:JavaScript策略模式
策略模式 定义:定义一系列的算法,把它们一个个封装成函数,也可把它们作为属性统一封装进一个对象,然后再定义一个方法,该方法可根据参数自动选择执行对应的算法. 一般用于在实现一个功能时,有很多个方案可选 ...
- 函数模块:CTVB_COMPARE_TABLES--两个表中删除/变更/粘贴分解
这个函数模块比较两个内表,将被删除.增加和修改的内表行分别分组输出. 输入参数:TABLE_OLD:旧表TABLE_NEW:新表KEY_LENGTH:键长度,指定内表中的前若干个字节(在 Unicod ...
- 在SharePoint中创建可自定义属性的文件夹
概况 阅读时间:约5分钟 适用版本:SharePoint Server 2010及以上 面向用户:普通用户.管理员.开发人员 难度指数:★★★☆☆ SharePoint中的文件夹分为2种,一种是文档库 ...
- [转]Android应用程序框架思路整理
一.一般Android应用程序架构(Book,购彩,Market). 普通的应用程序由于只需要用到Android的联网与显示的功能,所以应用程序大体上是呈现为UI(Activities)与网络(Net ...
- python之import子目录文件
问题: 在pre_tab.py文件下: print("AA") from test.te import login1 login1() from test.te import ...
- SqlServer--查询案例
use MyDataBase1 -- * 表示显示所有列 -- 查询语句没有加where条件表示查询所有行 select *from TblStudent ---只查询表中的部分列 select t ...