una - filtros para imagenes en python
Deformación geométrica de la imagen en python (1)
Un ProjectiveTransform
es una transformación lineal y no puede coincidir con su esquema de deformación. Puede haber mejores opciones, pero para las curvas arbitrarias puede hacer que funcione con un PiecewiseAffineTransform
, que coincidirá con cualquier cosa que le arroje mediante el tessellating de transformaciones lineales. Si simplemente cambias el nombre de la transformación en tu código, este es el resultado que obtengo:
Por lo tanto, probablemente necesite modificarlo un poco para obtener lo que busca, pero al menos produce las dos líneas paralelas que esperaba en el área donde su transformación está bien definida.
Me gustaría utilizar Python para realizar una transformación geométrica sobre una imagen, para "enderezar" o rectificar una imagen a lo largo de una curva determinada. Parece que scikit-image ProjectiveTransform()
y warp()
son muy buenos para esto, pero la documentación es escasa. Seguí la documentación aquí , pero no pude hacerlo funcionar correctamente para un caso de muestra.
Aquí hay un ejemplo: crearé una imagen con dos círculos concéntricos, y el objetivo es rectificar un cuarto de estos círculos, de modo que la imagen resultante sea dos líneas paralelas. Aquí está la muestra de datos:
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))
Y esto se puede trazar, por ejemplo:
imshow(a, cmap=''gist_gray_r'')
plot(x, y, ''r.'')
plot(x2, y2, ''r.'')
Entonces mi objetivo es rectificar la imagen en el cuadrante dado por los puntos de control rojos. (En este caso, esto es lo mismo que una transformación de cartesiano a polar.) Utilizando la imagen scikit del ejemplo de documentación, he hecho lo siguiente:
# 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)
Esperaba que esta imagen warped
mostrara dos líneas paralelas, pero en cambio me da:
¿Qué estoy haciendo mal aquí?
Tenga en cuenta que, si bien en este caso es una transformación cartesiana a polar, en el caso más general estoy buscando una transformación a partir de una curva arbitraria. Si alguien conoce una forma mejor de usar otro paquete, por favor avíseme. Puedo resolver este problema usando ndimage.map_coordinates
para un grupo de líneas radiales, pero estaba buscando algo más elegante.