numpy MapDelaunay三角形之间的对应点

lxkprmvk  于 2022-12-18  发布在  其他
关注(0)|答案(1)|浏览(108)

我尝试使用反向扭曲变形两张人脸图像。我有两张图像的Delaunay三角形以及所有对应三角形对的所有变换矩阵。x1c 0d1x
我已经将矩阵应用于三角形内的每个像素,但我得到的图像都很混乱,有些像素也没有填充。

我怀疑顶点列表没有按顺序排列,这意味着三角形没有对应。或者可能只是我搞乱了行,列的顺序。
下面是我的代码:

from scipy.spatial import Delaunay
from skimage.draw import polygon
import numpy as np

def drawDelaunay(img, landmarks, color):
    tri = Delaunay(landmarks)
    vertices = []

    for t in landmarks[tri.simplices]:
        # t = [int(i) for i in t]
        pt1 = [t[0][0], t[0][1]]
        pt2 = [t[1][0], t[1][1]]
        pt3 = [t[2][0], t[2][1]]

        cv2.line(img, pt1, pt2, color, 1, cv2.LINE_AA, 0)
        cv2.line(img, pt2, pt3, color, 1, cv2.LINE_AA, 0)
        cv2.line(img, pt3, pt1, color, 1, cv2.LINE_AA, 0)    

        vertices.append([pt1, pt2, pt3])
    return img, vertices

def getAffineMat(triangle1, triangle2):
    x = np.transpose(np.matrix([*triangle1]))
    y = np.transpose(np.matrix([*triangle2]))

    # Add ones to bottom of x and y
    x = np.vstack((x, [1,1,1]))
    y = np.vstack((y, [1,1,1]))

    xInv = np.linalg.pinv(x)
    return np.dot(y, xInv)

srcImg = face2
srcRows, srcCols, srcDepth = face2.shape
destImg = np.zeros(face1.shape, dtype=np.uint8)

for triangle1, triangle2 in zip(vertices1, vertices2):
    transMat = getAffineMat(triangle1, triangle2)
    r, c = list(map(list, zip(*triangle2)))
    rr, cc = polygon(r, c)

    for row, col in zip(rr, cc):
        transformed = np.dot(transMat, [col, row, 1])
        srcX, srcY, *_ = np.array(transformed.T)

        # Check if pixel is within image boundaries   
        if isWithinBounds(srcCols, srcRows, col, row):
            # Interpolate the color of the pixel from the four nearest pixels
            color = bilinearInterpolation(srcImg, srcX, srcY)
            
            # Set the color of the current pixel in the destination image
            destImg[row, col] = color

我希望实现这没有getAffineTransform或warpAffine。任何帮助将不胜感激!
资料来源:

  1. Transfer coordinates from one triangle to another triangle
  2. https://devendrapratapyadav.github.io/FaceMorphing/
ymdaylpp

ymdaylpp1#

但是你没有对应的三角形!这看起来像是2个单独的Delaunay三角剖分。也许是在匹配点上做的,但是仍然没有匹配的三角形。你不能做两个Delaunay三角剖分,每个图像一个,然后期望它们匹配。你需要一个Delaunay三角剖分,然后在两边使用相同的边(所以,至少对于一边,三角剖分不会完全是Delaunay)。
例如,看看图像的右上角,一边有4条边缘(计算那些我们看不到的边缘,因为它们与图像边界混淆,但它们必须在那里),另一边有6条边缘。
假设连接到两个匹配顶点的边的数量为常数(否则,如何扭曲任何东西?)
所以很明显我认为(但是你没有提供任何代码,因为你假设三角剖分是正确的,而我很确定三角剖分是不正确的,所以我只能猜测),你得到了两组匹配的,然后对这两组点进行2次Delaunay三角剖分,期望能够匹配三角形,即使它们不是完全相同的三角形。

编辑:如何转换

(in在评论中回复您的问题)
这是同样的三角剖分,在第一幅图中有一个点p,p,p,...,p的列表,在第二幅图中有一个点q,q,q,...,q的匹配列表,在第一幅图中执行三角剖分,其输出应该是一个索引三元组的列表,例如(1,3,4),(1,2,3),...表示第一幅图像中的最佳三角剖分是由三角形(p,p,p),(p,p,p),...组成的三角剖分。
在第二幅图中,你使用三角剖分(q,q,q),(q,q,q),...
即使它不是q,q,...,q的最优三角剖分(最大化最小角的三角剖分),如果q,q,...,q与p,p,...,p没有那么大的不同(如果你试图一致地匹配两个图像,它们不应该是这样的),它也不应该那么远。
因此,变换矩阵是每个匹配三角形中变换坐标的矩阵(每对匹配三角形有一个变换)。
要确定第二个图像的哪个点(x ',y')与第一个图像的点(x,y)匹配,需要
1.为了识别(x,y)在哪个三角形(i,j,k)(即(p,p,p))中,
1.求(x,y)在这个三角形内的重心坐标:(x,y)=αp +βp +γp
1.假设(x ′,y ′)在匹配三角形内具有相同的重心坐标,即(x ′,y ′)=αq +βq +γq
变换矩阵(对于三角形(i,j,k))是从(x,y)到(x ',y')的变换矩阵

相关问题