import matfunc as mt
def perspective_coefficients(self, oldplane, newplane):
"""
Calculates and returns the transform coefficients needed for a perspective
transform, ie tilting an image in 3D.
Note: it is not very obvious how to set the oldplane and newplane arguments
in order to tilt an image the way one wants. Need to make the arguments more
user-friendly and handle the oldplane/newplane behind the scenes.
Some hints on how to do that at http://www.cs.utexas.edu/~fussell/courses/cs384g/lectures/lecture20-Z_buffer_pipeline.pdf
| **option** | **description**
| --- | ---
| oldplane | a list of four old xy coordinate pairs
| newplane | four points in the new plane corresponding to the old points
"""
# first find the transform coefficients, thanks to http://stackoverflow.com/questions/14177744/how-does-perspective-transformation-work-in-pil
pb,pa = oldplane,newplane
grid = []
for p1,p2 in zip(pa, pb):
grid.append([p1[0], p1[1], 1, 0, 0, 0, -p2[0]*p1[0], -p2[0]*p1[1]])
grid.append([0, 0, 0, p1[0], p1[1], 1, -p2[1]*p1[0], -p2[1]*p1[1]])
# then do some matrix magic
A = mt.Matrix(grid)
B = mt.Vec([xory for xy in pb for xory in xy])
AT = A.tr()
ATA = AT.mmul(A)
gridinv = ATA.inverse()
invAT = gridinv.mmul(AT)
res = invAT.mmul(B)
a,b,c,d,e,f,g,h = res.flatten()
# finito
return a,b,c,d,e,f,g,h
要应用透视变换,首先必须知道平面a中的四个点,这些点将映射到平面B中的四个点。使用这些点,可以导出同形变换。通过这样做,你得到你的8个系数和转换可以发生。
网站http://xenia.media.mit.edu/~cwren/interpolator/(镜像:WebArchive)以及许多其他文本描述了如何确定这些系数。为了简化操作,下面是根据上述链接直接实现的:
其中,
pb
是当前平面中的四个顶点,pa
包含结果平面中的四个顶点。因此,假设我们变换图像,如:
下面是上面代码的输入和输出示例:
我们可以继续执行最后一个代码并执行透视转换以还原剪切:
导致:
您还可以在目的地享受一些乐趣:
我将截取这个问题,因为它是Google上唯一一个与Python中的透视转换相关的问题。下面是一些更通用的代码,基于上面的代码创建透视变换矩阵并生成一个函数,该函数将在任意点上运行该变换:
这里有一个纯Python版本的来生成转换系数(正如我已经看到几个请求的那样)。我制作并使用它来制作PyDraw纯Python图像绘制包。
如果将其用于您自己的项目,请注意,计算需要几个高级矩阵操作,这意味着此函数需要另一个纯Python矩阵库,名为
matfunc
,最初由Raymond Hettinger编写,您可以download here或here。相关问题 更多 >
编程相关推荐