我偶然发现了this question,并试图用Python Pillow进行透视转换。
这是我正在尝试做的以及结果如下:
这是我以前尝试过的代码:
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)
让剩下的代码保持不变,只使用不同的图像,我得到了这个转换: