Search code examples
pythonopencvimage-processingpython-imaging-libraryhandwriting-recognition

Is there any way to merge multiple image into one single image in Python?


I want to merge multiple images into one single image horizontaly. I tried to merge images through given code but it gives white image? For merge Images I tried PIL .

Input1

Input2

Input3

output Image

import sys
from PIL import Image


def append_images(images,bg_color=(255,255,255), aligment='center'):

    widths, heights = zip(*(i.size for i in images))


    new_width = sum(widths)
    new_height = max(heights)


    new_im = Image.new('RGB', (new_width, new_height), color=bg_color)

    offset = 0
    for im in images:
        y = 0
        if aligment == 'center':
            y = int((new_height - im.size[1])/2)
        elif aligment == 'bottom':
            y = new_height - im.size[1]
        new_im.paste(im, (offset, y))
        offset += im.size[0]


    return new_im
date=input("Enter Date:")
l=['1.jpg','2.jpg','3.jpg']


images = map(Image.open,l)
combo_2 = append_images(images, aligment='center')
combo_2.save('combo_2.jpg')

Solution

  • I prefer working with OpenCV&Numpy combo. That means working with arrays. The code below simply take first image as starting point - Height. Any image you will append with it will be horizontaly stacked based on height. That means, appended image will be resized by the montage Height and then horizontally stacked to montage.

    Working Code

    import cv2
    import numpy as np
    
    image1 = cv2.imread("img1.jpg")[:,:,:3]
    image2 = cv2.imread("img2.jpg")[:,:,:3]
    
    class Montage(object):
        def __init__(self,initial_image):
            self.montage = initial_image
            self.x,self.y = self.montage.shape[:2]
    
        def append(self,image):
            image = image[:,:,:3]
            x,y = image.shape[0:2]
            new_image = cv2.resize(image,(int(y*float(self.x)/x),self.x))
            self.montage = np.hstack((self.montage,new_image))
        def show(self):
            cv2.imshow('montage',self.montage)
            cv2.waitKey()
            cv2.destroyAllWindows()
    

    Firstly, you initialize class with first image which will define HEIGHT. So if you want different height, pass into the class resized image. After that you can append horizontaly the image

    Usage

    >>> m = Montage(image1)
    >>> m.append(image2)
    >>> m.show()
    

    Result in your case: enter image description here


    But generally it can work with totaly different sizes

    Image 1

    enter image description here

    Image 2

    enter image description here

    Montage

    enter image description here