python中图像的几何扭曲

python中图像的几何扭曲,python,image-processing,numpy,scikit-image,Python,Image Processing,Numpy,Scikit Image,我想使用python对图像执行几何变换,沿着给定曲线“拉直”或校正图像。scikit imageprojectveTransform()和warp()在这方面似乎非常好,但文档很少。我遵循了文档,但无法使其在示例案例中正常工作 这里有一个例子:我将创建一个具有两个同心圆的图像,目标是校正这些圆的四分之一,以便生成的图像是两条平行线。以下是示例数据: import numpy as np a = np.zeros((500, 500)) # create two concentric circl

我想使用python对图像执行几何变换,沿着给定曲线“拉直”或校正图像。scikit image
projectveTransform()
warp()
在这方面似乎非常好,但文档很少。我遵循了文档,但无法使其在示例案例中正常工作

这里有一个例子:我将创建一个具有两个同心圆的图像,目标是校正这些圆的四分之一,以便生成的图像是两条平行线。以下是示例数据:

import numpy as np
a = np.zeros((500, 500))

# create two concentric circles with a thickness of a few pixels:
for i in range(500):
    for j in range(500):
        r = np.sqrt((i - 250)**2 + (j - 250)**2) 
        if r > 50 and r < 52:
            a[i, j] = 10
        if r > 100 and r < 102:
            a[i, j] = 10
# now create the coordinates of the control points in the original image:
(x0, y0) = (250, 250)
r = 30   # inner circle
x = np.linspace(250 - r, 250, 50)
y = np.sqrt(r ** 2 - (x - x0) ** 2) + x0
r2 = 120   # outer circle
x2 = np.linspace(250 - r2, 250, 50)
y2 = np.sqrt(r2 ** 2 - (x2 - x0) ** 2) + x0
dst = np.concatenate((np.array([x, y]).T, np.array([x2, y2]).T))

因此,我的目标是校正红色控制点给出的象限中的图像。(在本例中,这与笛卡尔到极坐标变换相同。)使用文档示例中的scikit图像,我完成了:

# create corresponding coordinates for control points in final image:
xi = np.linspace(0, 100, 50)
yi = np.zeros(50)
xi2 = xi
yi2 = yi + (r2 - r)
src = np.concatenate((np.array([xi, yi]).T, np.array([xi2, yi2]).T))

# transform image
from skimage import transform, data
tform3 = transform.ProjectiveTransform()
tform3.estimate(src, dst)
warped = transform.warp(a, tform3)
我原以为这张扭曲的图像会显示两条平行线,但结果是:

我做错了什么


请注意,虽然在本例中是笛卡尔到极坐标的变换,但在最一般的情况下,我正在寻找来自任意曲线的变换。如果有人知道使用其他软件包的更好方法,请告诉我。我可以通过对一组径向线使用
ndimage.map\u坐标来解决这个问题,但我一直在寻找更优雅的方法。

a
ProjectiveTransform
是一种线性变换,无法匹配您的变形方案。可能有更好的选择,但对于任意曲线,您可以使用
分段仿射变换
,它将通过细分线性变换匹配您抛出的任何内容。如果您只需在代码中更改转换的名称,我将得到以下输出:


所以你可能需要稍微调整一下才能得到你想要的东西,但至少它在变换定义良好的区域产生了两条平行线。

我不认为这就是它不起作用的确切原因:单应在齐次坐标系中是线性的,但相应的二维投影变换不是线性的。好的一点,也许我概括得太多了。我仍然不认为它可以模拟从笛卡尔坐标到极坐标的转换,而这正是eOP所追求的。谢谢,这确实解决了它。可以在warp中使用参数
output\u shape
,这样输出将具有定义转换的维度。例如,在这种情况下:
output\u shape=(90100)
。我现在看到还有一个
多项式变换
,我想这里也可以使用它(遗憾的是,例子又少了)。@tiago我试着用
多项式变换
来设置它,但除了一张空白图像之外,什么都没有得到。。。您可能想ping,我很确定他们会非常乐意帮助您对任何转换进行排序。我现在只遇到了这个问题,但是如果您仍然有问题,请告诉我们。我们非常乐意为图库添加更多示例。
# create corresponding coordinates for control points in final image:
xi = np.linspace(0, 100, 50)
yi = np.zeros(50)
xi2 = xi
yi2 = yi + (r2 - r)
src = np.concatenate((np.array([xi, yi]).T, np.array([xi2, yi2]).T))

# transform image
from skimage import transform, data
tform3 = transform.ProjectiveTransform()
tform3.estimate(src, dst)
warped = transform.warp(a, tform3)