简体   繁体   English

图像中的几何扭曲

[英]Geometric warp of image in python

I would like to use python to perform a geometric transform over an image, to 'straighten' or rectify an image along a given curve. 我想使用python对图像执行几何变换,以沿给定曲线“拉直”或校正图像。 It seems that scikit-image ProjectiveTransform() and warp() are very good for this, but the documentation is sparse. 看起来scikit-image ProjectiveTransform()warp()对此非常有用,但是文档很少。 I followed the documentation here , but I couldn't get it to work properly for a sample case. 我在这里遵循了文档,但是在一个示例案例中却无法正常工作。

Here's an example: I'll create an image with two concentric circles, and the goal is to rectify one quarter of these circles, so that the resulting image are two parallel lines. 这是一个示例:我将创建一个具有两个同心圆的图像,目标是纠正这些圆的四分之一,以使生成的图像为两条平行线。 Here is the sample data: 这是示例数据:

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))

And this can be plotted, eg: 这可以画出来,例如:

imshow(a, cmap='gist_gray_r')
plot(x, y, 'r.')
plot(x2, y2, 'r.')

在此处输入图片说明

So my goal is to rectify the image in the quadrant given by the red control points. 因此,我的目标是在红色控制点给出的象限中校正图像。 (In this case, this is the same as a Cartesian to polar transformation.) Using scikit image from the documentation example, I've done: (在这种情况下,这与笛卡尔到极坐标的转换相同。)使用文档示例中的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)

I was expecting this warped image to show two parallel lines, but instead I get: 我原以为这张warped图像会显示两条平行线,但是我却得到了: 在此处输入图片说明

What am I doing wrong here? 我在这里做错了什么?

Note that while in this case it is a Cartesian to polar transform, in the most general case I'm looking for a transformation from some arbitrary curve. 请注意,虽然在这种情况下这是笛卡尔到极坐标的变换,但在最一般的情况下,我正在寻找任意曲线的变换。 If someone knows of a better way using some other package, please let me know. 如果有人知道使用其他软件包的更好方法,请告诉我。 I can solve this problem by using ndimage.map_coordinates for a bunch of radial lines, but was looking for something more elegant. 我可以使用ndimage.map_coordinates处理一堆径向线来解决此问题,但它正在寻找更优雅的方法。

A ProjectiveTransform is a linear transformation, and cannot match your deformation scheme. ProjectiveTransform是线性变换,无法匹配您的变形方案。 There may be better options, but for arbitrary curves you can make it work with a PiecewiseAffineTransform , which will match anything you throw at it by tessellating linear transformations. 可能会有更好的选择,但是对于任意曲线,您可以使其与PiecewiseAffineTransform一起使用,该方法可以通过细分线性变换来匹配您向其扔出的任何东西。 If you simply change the name of the transform in your code, this is the output I get: 如果仅在代码中更改转换的名称,这就是我得到的输出:

在此处输入图片说明

So you'll probably need to tweak it a little bit to get what you are after, but at least it produces the two parallel lines you were expecting in the area where your transformation is well defined. 因此,您可能需要稍微调整一下才能得到您想要的东西,但是至少它会产生您在变换定义明确的区域中期望的两条平行线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM