Skip to content Skip to sidebar Skip to footer

To Concatenate 4 Images Using Np.concatenate (two Vertically And Two Horizontally)

I have four images and I want to concatenate them into 1 image.I tried using concatenate function but there are multiple images and from them i need only in a batch of 4 images. Ac

Solution 1:

This should do the trick, or at least get you started. It chooses red as the background colour, and makes a 1x1 filler (padding) image the same colour. It then groups your images by four and pad-fills the final group if not a multiple of 4. It then iterates over the list and opens 4 images on each iteration. It gets their sizes and then determines the width and height of the output image. Then it creates the output image filled with the background colour and then pastes the images onto the background and saves the result.

You may choose to improve the layout, but that is just fiddling around with aesthetics, so you can do that bit!

#!/usr/bin/env python3import cv2
import os, glob
from itertools import zip_longest

defgrouper(iterable, n, fillvalue=None):
    """
    Group items of list in groups of "n" padding with "fillvalue"
    """
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

# Go to where the images are instead of managing a load of complicated paths
os.chdir('images')

# Get list of filenames sorted by mtime
filenames = sorted(glob.glob('*.jpg'),key=os.path.getmtime)

# Define a background colour onto which you will paste the images
bg = [0,0,255]   # background = red# Make a 1x1 filler image as a PNG so that it doesn't appear in your globbed list of JPEGs# Make it same as background colour so it doesn't show
fill = np.full((1,1,3), bg, dtype=np.uint8)
cv2.imwrite('fill.png', fill)

# Iterate over the files in groups of 4
out = 1for f1, f2, f3, f4 in grouper(filenames, 4, 'fill.png'):
    outfile = f'montage-{out}.jpg'print(f'DEBUG: Merging {f1},{f2},{f3},{f4} to form {outfile}')
    out += 1# Load all 4 images
    i1 = cv2.imread(f1)
    i1h, i1w = i1.shape[:2]
    i2 = cv2.imread(f2)
    i2h, i2w = i2.shape[:2]
    i3 = cv2.imread(f3)
    i3h, i3w = i3.shape[:2]
    i4 = cv2.imread(f4)
    i4h, i4w = i4.shape[:2]

    # Decide width of output image
    w = max(i1w+i2w, i3w+i4w)
    # Decide height of output image
    h = max(i1h,i2h) + max(i3h,i4h)

    # Make background image of background colour onto which to paste 4 images
    res = np.full((h,w,3), bg, dtype=np.uint8)

    # There are fancier layouts, but I will just paste into the 4 corners
    res[0:i1h, 0:i1w,  :] = i1       # image 1 into top-left
    res[0:i2h, w-i2w:, :] = i2       # image 2 into top-right
    res[h-i3h:,0:i3w,  :] = i3       # image 3 into bottom-left
    res[h-i4h:,w-i4w:, :] = i4       # image 4 into bottom-right# Save result image
    cv2.imwrite(outfile, res)

It creates output images like this:

enter image description here


Note you can do the same thing just using a couple of lines of bash shell script if you use ImageMagick:

#!/bin/bash# Build list of images
images=(*.jpg)

out=1
# Keep going till there are fewer than 4 left in listwhile [ ${#images[@]} -gt 3 ] ; do# Montage first 4 images from list
   magick montage -geometry +0+0 -tile 2x2 -background yellow "${images[@]:0:4}""montage-${out}.png"# Delete first 4 images from list
   images=(${images[@]:4})
   ((out+=1))
done

Keywords: Python, OpenCV, montage, group, grouped, by four, by fours.

Post a Comment for "To Concatenate 4 Images Using Np.concatenate (two Vertically And Two Horizontally)"