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

Я хотел бы использовать 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.')

введите здесь описание изображения

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

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

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


person tiago    schedule 29.10.2013    source источник


Ответы (1)


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

введите здесь описание изображения

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

person Jaime    schedule 29.10.2013
comment
Я не думаю, что это точная причина, по которой это не работает: гомография линейна в однородных координатах, но соответствующее двумерное проективное преобразование нелинейно. - person YXD; 29.10.2013
comment
Хороший вопрос, возможно, я слишком обобщил. Я все еще не думаю, что он может смоделировать преобразование декартовых координат в полярные, что и делает eOP. - person Jaime; 29.10.2013
comment
Спасибо, это решает. Можно использовать аргумент output_shape в warp, чтобы выходные данные имели размеры, в которых определено преобразование. Например, в этом случае: output_shape=(90, 100). Теперь я вижу, что есть также PolynomialTransform, который, я думаю, также может быть использован здесь (к сожалению, примеров снова мало). - person tiago; 29.10.2013
comment
@tiago Я пытался настроить его с помощью PolynomialTransform, но не получил ничего, кроме пустого изображения... Возможно, вы захотите пропинговать список рассылки skimage, я уверен, что они будут более чем рады помочь вам разобраться с любыми трансформациями. - person Jaime; 29.10.2013
comment
Я только сейчас столкнулся с этим вопросом, но если у вас все еще есть проблемы, сообщите нам об этом. Мы будем рады добавить дополнительные примеры в галерею. - person Stefan van der Walt; 13.01.2014