Геометрическая деформация изображения в python - программирование
Подтвердить что ты не робот

Геометрическая деформация изображения в python

Я хотел бы использовать python для выполнения геометрического преобразования над изображением, для "выпрямления" или исправления изображения вдоль данной кривой. Кажется, что scikit-image 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))

И это можно построить, например:

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

enter image description here

Итак, моя цель - исправить изображение в квадранте, заданное красными контрольными точками. (В этом случае это то же самое, что декартово-полярное преобразование.) Используя 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)

Я ожидал, что этот warped образ будет показывать две параллельные линии, но вместо этого я получаю: enter image description here

Что я здесь делаю неправильно?

Заметим, что, хотя в этом случае он является декартовым по отношению к полярному преобразованию, в самом общем случае я искал преобразование из некоторой произвольной кривой. Если кто-то знает лучший способ, используя какой-либо другой пакет, пожалуйста, дайте мне знать. Я могу решить эту проблему, используя ndimage.map_coordinates для пучка радиальных линий, но искал что-то более элегантное.

4b9b3361

Ответ 1

A ProjectiveTransform является линейным преобразованием и не может соответствовать вашей схеме деформации. Могут быть лучшие варианты, но для произвольных кривых вы можете заставить его работать с PiecewiseAffineTransform, который будет соответствовать всем, что вы бросаете на него путем тесселяции линейных преобразований. Если вы просто измените имя преобразования в своем коде, это результат, который я получаю:

enter image description here

Поэтому вам, вероятно, придется немного подкорректировать его, чтобы получить то, что вам нужно, но по крайней мере он создает две параллельные линии, которые вы ожидали в области, где ваше преобразование хорошо определено.