shikailun的日志

人脸变形算法的实现(改进)

上次在缺陷中有提到,在对Baby上的三角形ABC和对应的Parent上的DEF进行仿射变换后,总是不可避免的会空隙使得生成的图片带有“划痕”。经过几天的不眠日,今天总算解决了这个问题!吼吼~~

如上图,这是因为三角形ABC和DEF所包含像素点的数目一般是不回相同的,甚至相差很大,造成目标图片中的像素点或者未被赋值,形成令人讨厌的空洞,或者被多次赋值,造成像素重叠,总的效果不是很理想。

这几天我一直在想怎么解决这个问题,考虑过把这些空洞点的像素点的像素根据周围点取加权平均,但实际操作起来难度非常大。

今天看到了一篇关于二维图像变形的论文时才发现它们在做转换时把顺序给反过来了,将三角形DEF内的每一像素点反变换至ABC内的对应点,确定其像素值(这里对于怎么确定像素值,有很多种方法,包括最邻近插值、双线性插值等);
这样,结果图像中的每一像素点均被赋值唯一的一次,既提高了精度,又可以避免重复的赋值。

//遍历DEF图
for (int n = 0; n < H; n++)
{
    for (int m = 0; m < W; m++)
    {
        p = new Point(m, n);
        if (CommonUtil.ContainsPoint(Point[] DEF, p)) //DEF三个点 参见http://yilee.info/determining-if-a-point-lies-on-the-interior-of-a-polygon.html
        {
            q = CommonUtil.getAffineTransformationQ(p, D, E, F, A, B, C); //从DEF至ABC进行仿射变换
            targetBmp.SetPixel(m, n, sourceBmp.GetPixel(q.X, q.Y));
        }
    }
}

看看现在我们模特的几个转换结果图,比原来好多了不是?

Posted on
This entry was posted in technology  and tagged BabyMaker  图像处理  算法