3

I have some images(say 5) and each having different shapes. I want to concatenate into one single image for my project report. Can you please provide an easy way using opencv and python?

The resulting image is similar to below.

In numpy I tried something like this, it works but only for two images.

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

enter image description here

3 Answers 3

9

Getting the results that you show in the screenshot might require some more tinkering, but simply stacking the images on top of eachother can be acomplished like this:

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)

The basic idea is to find the total size of the images first, then create an array of that size and finally set the pixels in those ranges to that of each individual image while iterating downwards (or sideways, depending on what you want).

You can also implement threshold values for when you want to start another row or column.

Sign up to request clarification or add additional context in comments.

Comments

3

This modification of @ajayramesh's solution worked for me. This function takes in a list of images and outputs a single image where all input images are stacked vertically:

def get_one_image(img_list):
    max_width = 0
    total_height = 200  # padding
    for img in img_list:
        if img.shape[1] > max_width:
            max_width = img.shape[1]
        total_height += img.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 img_list:
        # add an image to the final array and increment the y coordinate
        image = np.hstack((image, np.zeros((image.shape[0], max_width - image.shape[1], 3))))
        final_image[current_y:current_y + image.shape[0], :, :] = image
        current_y += image.shape[0]
    return final_image

Comments

1

I modified code to make it a simple function, may be useful for others.

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)

1 Comment

line 20 doesn't work: ValueError: could not broadcast input array from shape (2048,6144,3) into shape (2048,2048,3)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.