在matplotlib中剪切转换的图像

时间:2017-05-01 21:40:36

标签: python python-3.x numpy matplotlib

我正在尝试在由3x3矩阵(使用齐次坐标)转换的matplotlib中显示图像。我有以下内容:

import numpy as np
import matplotlib as mp
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

class GenericTransform(mp.transforms.Transform):
    input_dims = 2
    output_dims = 2
    is_separable = False

    # expects a 3x3 matrix as a numpy array
    def __init__(self, matrix):
        super().__init__()
        self.matrix = matrix
        self.has_inverse = (np.linalg.det(matrix) != 0)

    def transform(self, values):
        # append 1 to each coordinate in `values`
        hvals = np.insert(values, 2, 1, axis=1)

        # do the transformations
        thvals = np.matmul(self.matrix, hvals.transpose()).transpose()

        # TODO: perspective divison?

        # get rid of extra dimension and return
        return thvals[:, 0:2]

    def transform_non_affine(self, values):
        return self.transform(values)

    def inverted(self):
        return GenericTransform(np.linalg.inv(self.matrix))



# add an image to the plot with a transformation
def addImage(filename, matrix):
    transform = GenericTransform(matrix)
    img = mpimg.imread(filename)
    imgShow = plt.imshow(img, alpha=1)
    imgShow.set_transform(transform + imgShow.get_transform())

我用图像文件名和矩阵调用addImage,然后调用plt.show(),转换似乎正确应用。但是,绘制的图像看起来会超出其边界范围,就像填充图像角落定义的轴对齐框一样: transformed image goes beyond expected bounds 看似“反射”的线是我想要简单地切断图像的地方。我对matplotlib不太熟悉,所以我很困惑为什么会这样。我松散地追随this。我还尝试使用路径手动剪辑图像:

# add an image to the plot with a transformation
def addImage(filename, matrix):
    transform = GenericTransform(matrix)
    img = mpimg.imread(filename)
    x = img.shape[1]
    y = img.shape[0]
    path = transform.transform_path(mp.path.Path([[0,0], [x,0], [x,y], [0,y], [0,0]]))
    patch = mp.patches.PathPatch(path, facecolor="none")
    imgShow = plt.imshow(img, alpha=1, clip_on=True, clip_path=patch)
    imgShow.set_transform(transform + imgShow.get_transform())

但这并不是我想要的。具体来说,每当我调整窗口大小或移动绘图时,剪切区域都会保持静止,因为背景中的图像会移动。如何才能正确剪辑图像?

另外,我知道我进行转换的方式对于透视转换可能是错误的,但我想自己解决这个问题。

1 个答案:

答案 0 :(得分:1)

几个小时后,我终于明白了。我不太明白如何将变换应用于剪辑路径。最终,这有效:

def addImage(filename, matrix):
    transform = GenericTransform(matrix)
    img = mpimg.imread(filename)
    imgShow = plt.imshow(img, alpha=1, clip_on=True, interpolation="bilinear")
    oldTransform = imgShow.get_transform()
    imgShow.set_transform(transform + oldTransform)

    w = img.shape[1]
    h = img.shape[0]
    path = transform.transform_path(mp.path.Path([[0,0], [w,0], [w,h], [0,h], [0,0]]))
    patch = mp.patches.PathPatch(path, facecolor="none")
    patch.set_transform(oldTransform)
    imgShow.set_clip_path(patch)