什么';我的透视变换系数函数(Python)有什么问题?

什么';我的透视变换系数函数(Python)有什么问题?,python,numpy,matrix-inverse,perspectivecamera,Python,Numpy,Matrix Inverse,Perspectivecamera,原始问题 所以我已经读了很多关于如何在纯Python中对图像进行透视变换的书,但是我无法让它工作 变换本身非常简单,它只是一个小的方程,但是我在使用函数从图像中的某些锚定点创建系数时遇到了问题。在基于numpy的优秀答案的帮助下,我得到了一个可以正常工作的代码,它可以毫无错误地完成,但我的问题是,我正试图用纯Python实现这一点。系数变得非常低,结果图像上什么也没有弹出 一个问题可能是我在纯Python函数中尝试移植的numpy函数,如dotmatrix、乘法和逆矩阵。(当我手动输入每个系数时

原始问题

所以我已经读了很多关于如何在纯Python中对图像进行透视变换的书,但是我无法让它工作

变换本身非常简单,它只是一个小的方程,但是我在使用函数从图像中的某些锚定点创建系数时遇到了问题。在基于numpy的优秀答案的帮助下,我得到了一个可以正常工作的代码,它可以毫无错误地完成,但我的问题是,我正试图用纯Python实现这一点。系数变得非常低,结果图像上什么也没有弹出

一个问题可能是我在纯Python函数中尝试移植的numpy函数,如dotmatrix、乘法和逆矩阵。(当我手动输入每个系数时,我会得到一个透视变换的图像,所以我知道渲染部分的系数应该工作)。因此,如果有人能帮我找出我计算系数时可能出现的问题,我将不胜感激:)

更新

好的,快速更新,事实证明numpy代码现在突然起作用,生成了一个透视图像(最初来自我之前链接的帖子),所以这至少是一个好迹象。下面是我使用的确切numpy代码,因此是在纯Python中复制的步骤模板

import numpy
matrix = []
print pa,pb
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)
print "ab",A,B
res = numpy.dot(numpy.linalg.inv(A.T * A) * A.T, B)
print "res",numpy.array(res).reshape(8)
下面是纯Python版本,该版本目前试图重现这些步骤,但失败了:

def tilt(self, oldplane, newplane):
    """
    perspective transform.
    oldplane is a list of four old xy coordinate pairs
    that will move to the four points in the newplane
    """
    #first find the transform coefficients, thanks to https://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]])
    def transpose(listoflists):
        return [list(each) for each in zip(*listoflists)]
    def flatten(listoflists):
        return [xory for xy in listoflists for xory in xy]
    def sumproduct(listA,multis):
        "aka, dot multiplication"
        outgrid = []
        for y,(row,multi) in enumerate(zip(listA,multis)):
            rowsum = 0
            for x,nr in enumerate(row):
                rowsum += nr*multi
            outgrid.append(rowsum)
        return outgrid
    def gridmultiply(grid1,grid2):
        "aka, matrix*matrix"
        outgrid = []
        for y in xrange(len(grid1)):
            newrow = []
            for x in xrange(len(grid2)):
                value = grid1[y][x] * grid2[y][x]
                newrow.append(value)
            outgrid.append(newrow)
        return outgrid
    def gridinverse(grid):
        outgrid = []
        pos_deriv = 1
        neg_deriv = 1
        for y in xrange(len(grid)):
            horizline = []
            for x in xrange(len(grid[0])):
                invx=len(grid[0])-1-x
                invy=len(grid)-1-y
                nr = grid[y][x]
                pos_deriv += pos_deriv*nr
                invnr = grid[invy][invx]*-1
                horizline.append(invnr)
                neg_deriv += neg_deriv*invnr
            outgrid.append(horizline)
        derivative = 1/float(pos_deriv-neg_deriv)
        print "deriv",derivative
        outgrid = gridmultiply(outgrid,[[derivative for _ in xrange(len(outgrid[0]))] for _ in xrange(len(outgrid))])
        return outgrid

    A = grid
    B = flatten(pb)
    res = sumproduct(gridinverse(gridmultiply(gridmultiply(transpose(A),A),transpose(A))), B)
    transcoeff = res
    print transcoeff
    #then calculate new coords, thanks to http://math.stackexchange.com/questions/413860/is-perspective-transform-affine-if-it-is-why-its-impossible-to-perspective-a"
    k = 1
    a,b,c,d,e,f,g,h = transcoeff
    outimg = Image().new(self.width,self.height)
    for y in xrange(len(self.imagegrid)):
        for x in xrange(len(self.imagegrid[0])):
            color = self.get(x,y)
            newx = int(round((a*x+b*y+c)/float(g*x+h*y+k)))
            newy = int(round((d*x+e*y+f)/float(g*x+h*y+k)))
            try:
                outimg.put(newx,newy,color)
                #print x,y,newx,newy
            except IndexError:
                #out of bounds
                pass
    return outimg

1) 没有numpy你为什么要这么做?2) 你有这个代码的正常版本吗?3) 如果是这样的话,您是否尝试过为您的函数编写一些测试
sumproduct
flatte
,等等?1)我知道这是一个巨大的迂回,但这是为了我正在编写的纯Python实验,我可能会将其添加到纯Python映像库“Pymaging”中,而且很有趣!2) 我有一个Numpy版本的代码,我从我链接到的论坛帖子中修改了它,但即使这样也会导致linalg.inv函数中出现错误(因为它收到的是一个数组而不是一个矩阵),但不确定我可以更改哪个部分来修复它。3) 我已经做了一些零星的打印来比较输入/输出,但我想在我进入未知领域之前,我会先问这里:P1)足够公平2)你应该先让这部分工作3)然后让你的纯Python函数工作。事实上,在添加新的未经测试的代码时,您正在移植损坏的代码,因此很难隔离问题。我建议您先发布您试图调用另一个问题中定义的
find_coefs
,人们可以帮助解决该问题。@MrE,我对系数进行了numpy计算,请参阅更新的问题。所以现在只剩下在Python中重新创建各种numpy矩阵操作了,这要提前感谢所有知道的人。