Tengo algunas imágenes (digamos 5) y cada una tiene diferentes formas. Quiero concatenar en una sola imagen para el informe de mi proyecto. ¿Puede proporcionar una forma fácil de usar opencv y python?

La imagen resultante es similar a la siguiente.

En numpy probé algo como esto, funciona pero solo para dos imágenes.

r = np.concatenate((images[1][:, :, 1], images[1][:, :, 3]), axis=1)

enter image description here

2
ajayramesh 13 nov. 2017 a las 00:39

2 respuestas

La mejor respuesta

Obtener los resultados que muestra en la captura de pantalla puede requerir algunos retoques más, pero simplemente apilar las imágenes una encima de la otra se puede lograr así:

import cv2
import numpy as np

image_names = ['original_field_1_0.PNG','original_field_1_1.PNG','original_field_1_3.PNG','original_field_1_4.PNG','original_field_1_5.PNG']
images = []
max_width = 0 # find the max width of all the images
total_height = 0 # the total height of the images (vertical stacking)

for name in image_names:
    # open all images and find their sizes
    images.append(cv2.imread(name))
    if images[-1].shape[1] > max_width:
        max_width = images[-1].shape[1]
    total_height += images[-1].shape[0]

# create a new array with a size large enough to contain all the images
final_image = np.zeros((total_height,max_width,3),dtype=np.uint8)

current_y = 0 # keep track of where your current image was last placed in the y coordinate
for image in images:
    # add an image to the final array and increment the y coordinate
    final_image[current_y:image.shape[0]+current_y,:image.shape[1],:] = image
    current_y += image.shape[0]

cv2.imwrite('fin.PNG',final_image)

La idea básica es encontrar primero el tamaño total de las imágenes, luego crear una matriz de ese tamaño y finalmente establecer los píxeles en esos rangos a los de cada imagen individual mientras se itera hacia abajo (o hacia los lados, dependiendo de lo que desee).

También puede implementar valores de umbral para cuando desee iniciar otra fila o columna.

4
en_lorithai 12 nov. 2017 a las 22:33

Modifiqué el código para convertirlo en una función simple, puede ser útil para otros.

def get_one_image(images):
        img_list = []
        padding = 200
        for img in images:
            img_list.append(cv2.imread(img))
        max_width = []
        max_height = 0
        for img in img_list:
            max_width.append(img.shape[0])
            max_height += img.shape[1]
        w = np.max(max_width)
        h = max_height + padding

        # create a new array with a size large enough to contain all the images
        final_image = np.zeros((h, w, 3), dtype=np.uint8)

        current_y = 0  # keep track of where your current image was last placed in the y coordinate
        for image in img_list:
            # add an image to the final array and increment the y coordinate
            final_image[current_y:image.shape[0] + current_y, :image.shape[1], :] = image
            current_y += image.shape[0]
        cv2.imwrite('out.png', final_image)
0
ajayramesh 13 nov. 2017 a las 19:47