Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

370
Views
Relleno de salida scipy affine_transform para mostrar regiones no superpuestas de imágenes transformadas

Tengo una imagen de origen ( src ) que deseo alinear con una imagen de destino ( dst ) mediante una transformación afín mientras retengo la extensión total de ambas imágenes durante la alineación (incluso las áreas que no se superponen).

Ya puedo calcular la matriz de desplazamiento y rotación de Affine Transformation, que envío a scipy.ndimage.interpolate.affine_transform para recuperar la imagen src alineada con dst .

El problema es que, cuando las imágenes no se superponen por completo, la imagen resultante se recorta solo en la huella común de las dos imágenes. Lo que necesito es la extensión completa de ambas imágenes, colocadas en el mismo sistema de coordenadas de píxeles. Esta pregunta es casi un duplicado de esta , y la excelente respuesta y el repositorio allí brindan esta funcionalidad para las transformaciones de OpenCV. Desafortunadamente, necesito esto para la implementación de scipy .

Demasiado tarde, después de golpear repetidamente una pared de ladrillos tratando de traducir la respuesta de la pregunta anterior a scipy , encontré este problema y luego seguí esta pregunta . La última pregunta me dio una idea del maravilloso mundo de la transformación afín de scipy , pero hasta ahora no he podido resolver mis necesidades particulares.

Las transformaciones de src a dst pueden tener traslaciones y rotaciones. Puedo hacer que solo funcionen las traducciones (a continuación se muestra un ejemplo) y solo puedo hacer que las rotaciones funcionen (en gran parte pirateando lo siguiente e inspirándome en el uso del argumento reshape en scipy.ndimage.interpolation.rotate ). Sin embargo, me estoy perdiendo completamente combinando los dos. He intentado calcular cuál debería ser el offset correcto (consulte las respuestas de esta pregunta nuevamente), pero no puedo hacerlo funcionar en todos los escenarios.

Ejemplo de trabajo de solo traducción de transformación afín acolchada, que sigue en gran medida este repositorio , explicado en esta respuesta :

 from scipy.ndimage import rotate, affine_transform import numpy as np import matplotlib.pyplot as plt nblob = 50 shape = (200, 100) buffered_shape = (300, 200) # buffer for rotation and translation def affine_test(angle=0, translate=(0, 0)): np.random.seed(42) # Maxiumum translation allowed is half difference between shape and buffered_shape # Generate a buffered_shape-sized base image with random blobs base = np.zeros(buffered_shape, dtype=np.float32) random_locs = np.random.choice(np.arange(2, buffered_shape[0] - 2), nblob * 2, replace=False) i = random_locs[:nblob] j = random_locs[nblob:] for k, (_i, _j) in enumerate(zip(i, j)): # Use different values, just to make it easier to distinguish blobs base[_i - 2 : _i + 2, _j - 2 : _j + 2] = k + 10 # Impose a rotation and translation on source src = rotate(base, angle, reshape=False, order=1, mode="constant") bsc = (np.array(buffered_shape) / 2).astype(int) sc = (np.array(shape) / 2).astype(int) src = src[ bsc[0] - sc[0] + translate[0] : bsc[0] + sc[0] + translate[0], bsc[1] - sc[1] + translate[1] : bsc[1] + sc[1] + translate[1], ] # Cut-out destination from the centre of the base image dst = base[bsc[0] - sc[0] : bsc[0] + sc[0], bsc[1] - sc[1] : bsc[1] + sc[1]] src_y, src_x = src.shape def get_matrix_offset(centre, angle, scale): """Follows OpenCV.getRotationMatrix2D""" angle = angle * np.pi / 180 alpha = scale * np.cos(angle) beta = scale * np.sin(angle) return ( np.array([[alpha, beta], [-beta, alpha]]), np.array( [ (1 - alpha) * centre[0] - beta * centre[1], beta * centre[0] + (1 - alpha) * centre[1], ] ), ) # Obtain the rotation matrix and offset that describes the transformation # between src and dst matrix, offset = get_matrix_offset(np.array([src_y / 2, src_x / 2]), angle, 1) offset = offset - translate # Determine the outer bounds of the new image lin_pts = np.array([[0, src_x, src_x, 0], [0, 0, src_y, src_y]]) transf_lin_pts = np.dot(matrix.T, lin_pts) - offset[::-1].reshape(2, 1) # Find min and max bounds of the transformed image min_x = np.floor(np.min(transf_lin_pts[0])).astype(int) min_y = np.floor(np.min(transf_lin_pts[1])).astype(int) max_x = np.ceil(np.max(transf_lin_pts[0])).astype(int) max_y = np.ceil(np.max(transf_lin_pts[1])).astype(int) # Add translation to the transformation matrix to shift to positive values anchor_x, anchor_y = 0, 0 if min_x < 0: anchor_x = -min_x if min_y < 0: anchor_y = -min_y shifted_offset = offset - np.dot(matrix, [anchor_y, anchor_x]) # Create padded destination image dst_h, dst_w = dst.shape[:2] pad_widths = [anchor_y, max(max_y, dst_h) - dst_h, anchor_x, max(max_x, dst_w) - dst_w] dst_padded = np.pad( dst, ((pad_widths[0], pad_widths[1]), (pad_widths[2], pad_widths[3])), "constant", constant_values=-1, ) dst_pad_h, dst_pad_w = dst_padded.shape # Create the aligned and padded source image source_aligned = affine_transform( src, matrix.T, offset=shifted_offset, output_shape=(dst_pad_h, dst_pad_w), order=3, mode="constant", cval=-1, ) # Plot the images fig, axes = plt.subplots(1, 4, figsize=(10, 5), sharex=True, sharey=True) axes[0].imshow(src, cmap="viridis", vmin=-1, vmax=nblob) axes[0].set_title("Source") axes[1].imshow(dst, cmap="viridis", vmin=-1, vmax=nblob) axes[1].set_title("Dest") axes[2].imshow(source_aligned, cmap="viridis", vmin=-1, vmax=nblob) axes[2].set_title("Source aligned to Dest padded") axes[3].imshow(dst_padded, cmap="viridis", vmin=-1, vmax=nblob) axes[3].set_title("Dest padded") plt.show()

p.ej:

 affine_test(0, (-20, 40))

da:

ingrese la descripción de la imagen aquí

Con un zoom que muestra lo alineado en las imágenes rellenadas:

ingrese la descripción de la imagen aquí

Necesito la extensión completa de las imágenes src y dst alineadas en las mismas coordenadas de píxeles, con rotaciones y traslaciones.

¡Cualquier ayuda es muy apreciada!

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Si tienes dos imágenes que son similares (o iguales) y quieres alinearlas, puedes hacerlo usando ambas funciones de rotar y desplazar:

 from scipy.ndimage import rotate, shift

Primero debe encontrar la diferencia de ángulo entre las dos imágenes angle_to_rotate , teniendo que aplicar una rotación a src:

 angle_to_rotate = 25 rotated_src = rotate(src, angle_to_rotate , reshape=True, order=1, mode="constant")

Con reshape=True , evita perder información de su matriz src original y rellena el resultado para que la imagen pueda traducirse alrededor de los índices 0,0. Puede calcular esta traducción tal como es (x*cos(angle),y*sin(angle) donde x e y son las dimensiones de la imagen, pero probablemente no importe.

Ahora deberá traducir la imagen a la fuente, para hacerlo puede usar la función de cambio :

 rot_translated_src = shift(rotated_src , [distance_x, distance_y])

En este caso no hay cambio de forma (porque de lo contrario no tendría ninguna traducción real), por lo que si la imagen no se rellenó previamente, se perderá cierta información.

Pero puedes hacer algo de relleno con

 np.pad(src, number, mode='constant')

Para calcular distance_x y distance_y necesitará encontrar un punto que le sirva como referencia entre el rotated_src y el destino, luego simplemente calcule la distancia en los ejes x e y.

Resumen

  1. Haz algo de relleno en src y dst
  2. Encuentre la distancia angular entre ellos.
  3. Gire src con scipy.ndimage.rotate usando reshape=True
  4. Encuentre la distancia horizontal y vertical distancia_x distance_x, distance_y entre la imagen rotada y dst
  5. Traduce tu 'rotated_src' con scipy.ndimage.shift

Código

 from scipy.ndimage import rotate, shift import matplotlib.pyplot as plt import numpy as np

Primero hacemos la imagen de destino:

 # make and plot dest dst = np.ones([40,20]) dst = np.pad(dst,10) dst[17,[14,24]]=4 dst[27,14:25]=4 dst[26,[14,25]]=4 rotated_dst = rotate(dst, 20, order=1) plt.imshow(dst) # plot it plt.imshow(rotated_dst) plt.show()

Hacemos la imagen de origen:

 # make_src image and plot it src = np.zeros([40,20]) src = np.pad(src,10) src[0:20,0:20]=1 src[7,[4,14]]=4 src[17,4:15]=4 src[16,[4,15]]=4 plt.imshow(src) plt.show()

Luego alineamos el src al destino:

 rotated_src = rotate(src, 20, order=1) # find the angle 20, reshape true is by default plt.imshow(rotated_src) plt.show() distance_y = 8 # find this distances from rotated_src and dst distance_x = 12 # use any visual reference or even the corners translated_src = shift(rotated_src, [distance_y,distance_x]) plt.imshow(translated_src) plt.show()

pd : si encuentra problemas para encontrar el ángulo y las distancias de forma programática, deje un comentario proporcionando un poco más de información sobre lo que se puede usar como referencia que podría ser, por ejemplo, el marco de la imagen o algunas características de la imagen / datos)

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!