tia*_*ago 10 python numpy image-processing scikit-image
我想使用python对图像执行几何变换,以"拉直"或纠正沿给定曲线的图像.看来,scikit形象ProjectiveTransform()
和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))
Run Code Online (Sandbox Code Playgroud)
这可以绘制,例如:
imshow(a, cmap='gist_gray_r')
plot(x, y, 'r.')
plot(x2, y2, 'r.')
Run Code Online (Sandbox Code Playgroud)
所以我的目标是纠正红色控制点给出的象限中的图像.(在这种情况下,这与笛卡尔到极坐标变换相同.)使用文档示例中的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)
Run Code Online (Sandbox Code Playgroud)
我期待这个warped
图像显示两条平行线,但我得到:
我在这做错了什么?
请注意,虽然在这种情况下它是笛卡尔到极坐标变换,但在最一般的情况下,我正在寻找从某个任意曲线的变换.如果有人知道使用其他包装的更好方法,请告诉我.我可以通过使用ndimage.map_coordinates
一堆径向线来解决这个问题,但是正在寻找更优雅的东西.
A ProjectiveTransform
是线性变换,不能与您的变形方案匹配.可能有更好的选项,但对于任意曲线,您可以使用a PiecewiseAffineTransform
,它将匹配您通过细分线性变换抛出的任何内容.如果您只是在代码中更改转换的名称,这是我得到的输出:
因此,您可能需要稍微调整它以获得您所追求的内容,但至少它会产生您期望在转换定义良好的区域中的两条平行线.