You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python沿任意直线拉伸图像或绕任意点缩放?

图像沿指定方向相对于不变直线的仿射拉伸实现

问题背景

现有一张128x128的2D numpy.ndarray热力图,已知:

  • 图像上一点 P = (x0, y0)
  • 方向向量 v = [v0, v1]
  • 直线 L:过点P且与v垂直
  • 缩放因子s(百分比形式)

需求是沿v方向、以比例s将图像远离直线L拉伸,直线L上的点变换后位置不变:

  • s为正时,所有点远离L
  • s为负时,所有点向L靠近

同时要求:

  • 仅修改图像内容,保持128x128尺寸不变
  • 变换前后直线L在图像中的位置不变(视野不变)

当L过原点时,这是简单的线性变换,但L不一定过原点,因此需要用仿射变换实现。

已尝试的方法及问题

  1. cv2.resize:仅支持过原点的线性变换,且必须调整图像实际尺寸,不符合需求。

  2. cv2.getAffineTransform + cv2.warpAffine:
    尝试通过选取共线点生成变换矩阵,代码如下:

    def get_transformation_matrix(pt1 : tuple[float, float], pt2 : tuple[float, float], scale_factor : float) -> np.ndarray:
        """Returns the transformation matrix to scale an image along the line containing `pt1` and `pt2`,
        centered at their midpoint, by `scale_factor` (a percentage increase/decrease)."""
        # 从pt1到pt2的向量,除以2(即pt1到中点/中点到pt2的向量)
        slope_vector = np.array([pt2[0] - pt1[0], pt2[1] - pt1[1]]) / 2
    
        # 两点的中点
        center = np.array([(pt2[0] - pt1[0]) / 2 + pt1[0],
                           (pt2[1] - pt1[1]) / 2 + pt1[1]])
        
        # 变换后的新点:中点±缩放后的slope_vector
        new_pt1 = center - slope_vector * (1 + scale_factor / 100)
        new_pt2 = center + slope_vector * (1 + scale_factor / 100)
    
        initial_points = np.float32([pt1, center, pt2])
        final_points = np.float32([new_pt1, center, new_pt2])
        
        return cv2.getAffineTransform(initial_points, final_points)
    
    M = get_transformation_matrix([100, 100], [200, 100], 10)
    print(M)
    dst = cv2.warpAffine(data, M, data.shape)
    

    但得到的变换矩阵M是全零矩阵[[0. 0. 0.] [0. 0. 0.]],输出图像dst全黑。推测是因为cv2.getAffineTransform需要三组不共线的点(构成三角形)来计算仿射矩阵,而选取的三个点共线导致无法生成有效矩阵。

  3. scipy.ndimage.affine_transform:看起来可行,但不清楚如何推导对应的变换矩阵和偏移量。

相关子问题

如果需求改为绕点P进行均匀缩放,是否和上述直线拉伸的逻辑类似,只是不需要区分L方向的单位向量?特此确认。


内容的提问来源于stack exchange,提问作者Nik3141

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:52:47