python - 使用 src/target 坐标使用 Python PIL 进行透视变换

标签 python image-processing python-imaging-library coordinate-transformation

我偶然发现了 this question并尝试使用 Python Pillow 执行透视转换。

这就是我正在尝试做的事情以及结果的样子:

enter image description here

这是我用来尝试的代码:

from PIL import Image
import numpy

# function copy-pasted from https://stackoverflow.com/a/14178717/744230
def find_coeffs(pa, pb):
    matrix = []
    for p1, p2 in zip(pa, pb):
        matrix.append([p1[0], p1[1], 1, 0, 0, 0, -p2[0]*p1[0], -p2[0]*p1[1]])
        matrix.append([0, 0, 0, p1[0], p1[1], 1, -p2[1]*p1[0], -p2[1]*p1[1]])

    A = numpy.matrix(matrix, dtype=numpy.float)
    B = numpy.array(pb).reshape(8)

    res = numpy.dot(numpy.linalg.inv(A.T * A) * A.T, B)
    return numpy.array(res).reshape(8)

# test.png is a 256x256 white square
img = Image.open("./images/test.png")

coeffs = find_coeffs(
    [(0, 0), (256, 0), (256, 256), (0, 256)],
    [(15, 115), (140, 20), (140, 340), (15, 250)])

img.transform((300, 400), Image.PERSPECTIVE, coeffs,
              Image.BICUBIC).show()

我不确定转换是如何工作的,但似乎这些点向相反的方向移动(例如,我需要执行 (-15, 115) 以使点 A 向右移动。但是,它也赢了' 移动 15 个像素但 5)。

如何确定目标点的确切坐标以正确倾斜图像?

最佳答案

答案很简单:只需交换源坐标和目标坐标。但这不是你的错:链接答案的作者特别容易混淆,因为 target, source (在这种情况下)是函数参数的困惑顺序,因为函数参数没有帮助名称,并且因为该示例对剪刀进行了反向转换。

除了交换源坐标和目标坐标,您还可以交换 find_coeffs 函数的参数。更好的是,也重命名它们,比如

def find_coeffs(source_coords, target_coords):
    matrix = []
    for s, t in zip(source_coords, target_coords):
        matrix.append([t[0], t[1], 1, 0, 0, 0, -s[0]*t[0], -s[0]*t[1]])
        matrix.append([0, 0, 0, t[0], t[1], 1, -s[1]*t[0], -s[1]*t[1]])
    A = numpy.matrix(matrix, dtype=numpy.float)
    B = numpy.array(source_coords).reshape(8)
    res = numpy.dot(numpy.linalg.inv(A.T * A) * A.T, B)
    return numpy.array(res).reshape(8)

保持其余代码不变,只使用不同的图像,我得到了这个转换:

Walter with red cornersWalter with red corners in perspective

关于python - 使用 src/target 坐标使用 Python PIL 进行透视变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53032270/

相关文章:

python - 性能 SQLAlchemy 和或

android - 如何在 android(2.1 或更高版本)上获取设备(特别是 sdcard)上的所有图像

c++ - 在 C++ 中从 YBR_FULL 转换为 RGB?

c# - 垂直翻转字节数组中位图的算法

python - 如何将 PIL(或任何模块)安装到树莓派上?

python - 如何合并两个具有不同时间戳的 Pandas

python - Keras:使用灰度蒙版和 ImageDataGenerator 类进行图像分割

python - 以数组形式打开图像

python - virtualenv 中的日志记录模块

python - 使用 Python 和 pillow (PIL) 填充空心形状