二维图像的三角形变换算法解释
对于二维图像的变形,最简单直接的方式就是将需要变形的不规则区域进行三角形划分,使复杂多边形由1到N个三角形组成,那么最终的变形动作也就转化为这些三角形变形。
三角形变形,就是将一个三角形通过某种变换变成另一个三角形,同时也要保证在源三角形中的点能够正确映射到目标三角形中合适的位置。如下图所示:
![](http://blog.csdn.net/images/blog_csdn_net/aqua_aqua/131802/o_Snap1.jpg)
图中△ABC是源三角形,Z点是源三角形中的任意一点。△abc为目标三角形,而z点就是源三角形中Z点的变换后点。很自然这中间就存在一个变换关系f的存在,根据这个变换关系,可以可△ABC中的每个点都在△abc找到合适的位置。这种从源三角形中的点出发,根据变换关系,算目标三角形的点的方式,称之为正向变换。此种变换的适合于在目标三角形中找出源三角形的某一点,但是对于二维图像变形,是需要将源三角形区域内的所有像素都映射到目标三角形中,而两个三角形的形态、大小不可能一样,所以最终所造成的结果可能是目标三角形中有的像素未接受到映射,形成空洞。
还有一种变换方式是从目标三角形中的点去找其在源三角形中的位置,这称为逆向变换。对于需要将整个源三角形都映射到目标三角形的情况,这种方式要更适合。因为这样可以使目标三角形完全被填充,不至于出现空洞。所以本文中采用了这种逆向变换方式。
而上述两种变换方式也有所通常所采用的方法也是以二维矩形来表示一个坐标点(源坐标或目的坐标),然后经过一系列平移、缩放、错切变换等矩阵运算,来算出另一映射坐标点(目的坐标或源坐标),虽然其结果比较精确,但是这样一个过程是相当复杂,且运算量大。另一种近似算法:利用源三角形和目标三角形各个顶点的对应,通过线性插值,算出源和目的每条边的映射关系,再将相邻边上的点进行连接,再次运用线性插值,最后得到了两三角形内任意点之间的映射对。相对而言,第二种算法运算量要小很多,且容易理解,
以下图中源三角形△ABC和目标三角形△abc为例,A点的对应点为a,B点对应点为b,C点对应点为c。现在要找出目标三角形△abc中z点在源三角形△ABC的对应的Z点坐标。具体算法:
1. 过d点做水平线,找到其与△abc的两个交点。设与ab边交点为e,与ac边交点f。
2. 根据△ABC与△abc三个顶点的对应关系,算出e、f两点在△ABC的AB边和AC边上的对应点E、F。
3. 最后由z点在ef点连线的位置,可以得到EF点连线上Z点的位置。
在这个算法中只用到了最简单的线性插值技术和基本的直线到表达式,避免了繁琐的矩阵运算。在具体的实现过程中,因为是对目标三角形中每点进行填充,所以还运用到了扫描线技术。
![](http://blog.csdn.net/images/blog_csdn_net/aqua_aqua/131802/o_Snap2.jpg)
在具体实现,由代码表示,此处只是给出了其流程。
a. 对目标三角形abc中的三个点进行某种序列的排序,使其便于以后运算。此处设最高点为a点,依次为b、c点。如出现水平线,则左点在前。
b. 如果目标三角形中存在水平线,则先找到水平线在源三角形的对应线。因为此次变换主要运用提直线的两点表达式,这个表达式中对于水平的表示需要特殊处理。
c. 从高点a点后下进行水平扫描,每条水平线都会与△abc存在两个交点,找到这个两个交点e、f点,
d. 根据两点所在边与其在△ABC中对应边的关系,找到源三角形中的E、F点。
e. 对e、f点之间的连线进行遍历,找到其线上各点在△ABC中EF点连线的位置,
f. 找到相应位置也就找到了相应的原始像素,因为在一般情况下找到的原始点坐标都是一个实数,不是整数,所以取原始点的颜色还需要对此位置四周的颜色进行双线性插值,才能找到最终所需要的颜色。
注意,在对颜色进行线性插值时,要对三原色分别进行插值。
另外,对于大区域的变换时,可以多线程技术,对三角形的区域进行多点同时进行转换。