透视转换在PIL中如何工作? [英] How does perspective transformation work in PIL?
问题描述
PIL的 Image.transform
具有透视模式需要8个元组的数据,但我不知道如何将其转换为该元组的30度右倾角.
PIL's Image.transform
has a perspective-mode which requires an 8-tuple of data but I can't figure out how to convert let's say a right tilt of 30 degrees to that tuple.
有人可以解释吗?
推荐答案
要应用透视变换,您首先必须知道平面A中的四个点,这些点将映射到平面B中的四个点.使用这些点,您可以可以得出单应变换.通过这样做,您可以获得8个系数,并且可以进行转换.
To apply a perspective transformation you first have to know four points in a plane A that will be mapped to four points in a plane B. With those points, you can derive the homographic transform. By doing this, you obtain your 8 coefficients and the transformation can take place.
网站 http://xenia.media.mit.edu/~cwren/interpolator /(镜像: WebArchive )以及许多其他文章,介绍了如何确定这些系数.为了使事情变得容易,这里是根据上述链接的直接实现:
The site http://xenia.media.mit.edu/~cwren/interpolator/ (mirror: WebArchive), as well as many other texts, describes how those coefficients can be determined. To make things easy, here is a direct implementation according from the mentioned link:
import numpy
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)
其中pb
是当前平面中的四个顶点,pa
包含结果平面中的四个顶点.
where pb
is the four vertices in the current plane, and pa
contains four vertices in the resulting plane.
因此,假设我们将图像转换为:
So, suppose we transform an image as in:
import sys
from PIL import Image
img = Image.open(sys.argv[1])
width, height = img.size
m = -0.5
xshift = abs(m) * width
new_width = width + int(round(xshift))
img = img.transform((new_width, height), Image.AFFINE,
(1, m, -xshift if m > 0 else 0, 0, 1, 0), Image.BICUBIC)
img.save(sys.argv[2])
这是上面的代码的示例输入和输出:
Here is a sample input and output with the code above:
我们可以继续执行最后一个代码,并执行透视转换以还原剪切力:
We can continue on the last code and perform a perspective transformation to revert the shear:
coeffs = find_coeffs(
[(0, 0), (256, 0), (256, 256), (0, 256)],
[(0, 0), (256, 0), (new_width, height), (xshift, height)])
img.transform((width, height), Image.PERSPECTIVE, coeffs,
Image.BICUBIC).save(sys.argv[3])
结果:
您还可以在目的地上玩一些有趣的事情:
You can also have some fun with the destination points:
这篇关于透视转换在PIL中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!