Math 什么';这是一种用给定的一组点扭曲图像的简单方法吗?

Math 什么';这是一种用给定的一组点扭曲图像的简单方法吗?,math,graphics,morphing,Math,Graphics,Morphing,我想实现图像变形,为此我需要能够使用给定的点集和它们的目标位置(它们将被“拖动”)使图像变形。我正在寻找一个简单易行的解决方案来完成这项工作,它不需要看起来很好或非常快 这是我需要的一个示例: 假设我有一个图像和一组只有一个变形点[0.5,0.5],它的目标点在[0.6,0.5](或者说它的运动向量是[0.1,0.0])。这意味着我要将图像的中心像素向右移动0.1。某些给定半径r中的相邻像素当然需要用该像素“拖动”一点 我的想法是这样做: p2 = p1 + ( 1 / ( (distance(

我想实现图像变形,为此我需要能够使用给定的点集和它们的目标位置(它们将被“拖动”)使图像变形。我正在寻找一个简单易行的解决方案来完成这项工作,它不需要看起来很好或非常快

这是我需要的一个示例:

假设我有一个图像和一组只有一个变形点[0.5,0.5],它的目标点在[0.6,0.5](或者说它的运动向量是[0.1,0.0])。这意味着我要将图像的中心像素向右移动0.1。某些给定半径r中的相邻像素当然需要用该像素“拖动”一点

我的想法是这样做:

p2 = p1 + ( 1 / ( (distance(p1,p0) / r)^2 + 1 ) ) * s
  • 我将创建一个函数,根据提供的变形点集,将源图像位置映射到目标位置
  • 然后我必须找到这个函数的反函数,因为我必须通过目标像素来执行转换,并看到“点必须从哪里来才能到达这个位置”
  • 步骤1中的函数如下所示:

    p2 = p1 + ( 1 / ( (distance(p1,p0) / r)^2 + 1 ) ) * s
    
    在哪里

    • p0([x,y]向量)是变形点的位置
    • p1([x,y]向量)是源图像中的任意给定点
    • p2([x,y]向量)是p1将移动到的位置
    • s([x,y]矢量)是变形点的运动矢量,表示p0将被拖动的方向和距离
    • r(标量)是半径,只是一些数字
    我对第二步有问题。反函数的计算对我来说似乎有点太复杂了,所以我想知道:

    • 如果存在求逆函数的简单方法,或
    • 如果有更好的函数,求逆函数很简单,或者
    • 如果有一个完全不同的方式来做这一切,这是简单的

      • 不需要构造直接函数并将其反转。通过交换源点和目标点的角色,直接计算逆函数

        你需要一些形式的二元插值,看看径向基函数插值。它需要解一个线性方程组

        反向距离加权(类似于您的建议)是最容易实现的,但我担心它会给出令人失望的结果


        这是Python的解决方案-我按照建议做了,只是尝试使用forward函数作为反向函数(切换源和目标)。我还稍微改变了函数,改变指数和其他值会产生不同的结果。代码如下:

        from PIL import Image
        import math
        
        def vector_length(vector):
          return math.sqrt(vector[0] ** 2 + vector[1] ** 2)
        
        def points_distance(point1, point2):
          return vector_length((point1[0] - point2[0],point1[1] - point2[1]))
        
        def clamp(value, minimum, maximum):
          return max(min(value,maximum),minimum)
        
        ## Warps an image accoording to given points and shift vectors.
        #  
        #  @param image input image
        #  @param points list of (x, y, dx, dy) tuples
        #  @return warped image
        
        def warp(image, points):
          result = img = Image.new("RGB",image.size,"black")
        
          image_pixels = image.load()
          result_pixels = result.load()
        
          for y in range(image.size[1]):
            for x in range(image.size[0]):
        
              offset = [0,0]
        
              for point in points:
                point_position = (point[0] + point[2],point[1] + point[3])
                shift_vector = (point[2],point[3])
        
                helper = 1.0 / (3 * (points_distance((x,y),point_position) / vector_length(shift_vector)) ** 4 + 1)
        
                offset[0] -= helper * shift_vector[0]
                offset[1] -= helper * shift_vector[1]
        
              coords = (clamp(x + int(offset[0]),0,image.size[0] - 1),clamp(y + int(offset[1]),0,image.size[1] - 1))
        
              result_pixels[x,y] = image_pixels[coords[0],coords[1]]
        
          return result
        
        image = Image.open("test.png")
        image = warp(image,[(210,296,100,0), (101,97,-30,-10), (77,473,50,-100)])
        image.save("output.png","PNG")