note.nkmk.me

Concatenate images with Python, OpenCV (hconcat, vconcat, np.tile)

Posted: 2019-05-14 / Tags: Python, OpenCV, Image Processing

Use cv2.vconcat(), cv2.hconcat() to concatenate (combine) images vertically and horizontally with Python, OpenCV. v means vertical and h means horizontal.

Pass a list of images (ndarray), an image (ndarray) in which the images in the list are vertically or horizontally concatenated is returned. Images with different sizes need to be resized beforehand. Errors will occur if the width or height is not aligned.

numpy.tile() is convenient when arranging the same image repeatedly.

When concatenating color images (3D ndarray), set the second parameter (reps) to (The number of vertical repetitions、The number of horizontal repetitions、1). For grayscale images (2D ndarray), set reps to (n vertical, n horizontal).

This post describes the following contents with sample codes.

  • Concatenate vertically
  • Concatenate horizontally
  • Concatenate vertically and horizontally (like tiles)

Read two images as an example.

import cv2
import numpy as np

im1 = cv2.imread('data/src/lena.jpg')
im2 = cv2.imread('data/src/rocket.jpg')

Please refer to the following post for image concatenation in Pillow.

Sponsored Link

Concatenate vertically

Concatenate images of same width vertically

When concatenating images of same width vertically, cv2.vconcat() can be used as it is.

im_v = cv2.vconcat([im1, im1])
cv2.imwrite('data/dst/opencv_vconcat.jpg', im_v)

Python OpenCV concat v

Repeat the same image vertically

You can use np.tile() as well if you are arranging the same image repeatedly.

im_v_np = np.tile(im1, (2, 1, 1))
cv2.imwrite('data/dst/opencv_vconcat_np.jpg', im_v_np)

Concatenate images of different widths vertically

It is useful to define a function to combine images of different widths. Here, the bigger one is resized.

shape[0] represents height and shape[1] represents width.

def vconcat_resize_min(im_list, interpolation=cv2.INTER_CUBIC):
    w_min = min(im.shape[1] for im in im_list)
    im_list_resize = [cv2.resize(im, (w_min, int(im.shape[0] * w_min / im.shape[1])), interpolation=interpolation)
                      for im in im_list]
    return cv2.vconcat(im_list_resize)

im_v_resize = vconcat_resize_min([im1, im2, im1])
cv2.imwrite('data/dst/opencv_vconcat_resize.jpg', im_v_resize)

Python OpenCV concat v resize

List comprehensions is used to create a list of resized images.

Concatenate horizontally

The horizontal case is basically the same concept as the vertical case.

Concatenate images of same height horizontally

When concatenating images of same height horizontally, cv2.hconcat() can be used as it is.

im_h = cv2.hconcat([im1, im1])
cv2.imwrite('data/dst/opencv_hconcat.jpg', im_h)

Python OpenCV concat h

Repeat the same image horizontally

You can use np.tile() as well if you are arranging the same image repeatedly.

im_h_np = np.tile(im1, (1, 2, 1))
cv2.imwrite('data/dst/opencv_hconcat_np.jpg', im_h_np)

Concatenate images of different heights horizontally

As with vertical concatenation, it is useful to define a function to combine images of different sizes. Here, the bigger one is resized.

def hconcat_resize_min(im_list, interpolation=cv2.INTER_CUBIC):
    h_min = min(im.shape[0] for im in im_list)
    im_list_resize = [cv2.resize(im, (int(im.shape[1] * h_min / im.shape[0]), h_min), interpolation=interpolation)
                      for im in im_list]
    return cv2.hconcat(im_list_resize)

im_h_resize = hconcat_resize_min([im1, im2, im1])
cv2.imwrite('data/dst/opencv_hconcat_resize.jpg', im_h_resize)

Python OpenCV concat h resize

Sponsored Link

Concatenate vertically and horizontally (like tiles)

Concatenate images of the same size vertically and horizontally

Using cv2.vconcat() and cv2.hconcat(), images can be concatenated vertically and horizontally in tile form.

A function that concatenates images of the same size with a 2D list (array) can be defined as follows.

def concat_tile(im_list_2d):
    return cv2.vconcat([cv2.hconcat(im_list_h) for im_list_h in im_list_2d])

im1_s = cv2.resize(im1, dsize=(0, 0), fx=0.5, fy=0.5)
im_tile = concat_tile([[im1_s, im1_s, im1_s, im1_s],
                       [im1_s, im1_s, im1_s, im1_s],
                       [im1_s, im1_s, im1_s, im1_s]])
cv2.imwrite('data/dst/opencv_concat_tile.jpg', im_tile)

Python OpenCV concat tile

The example uses the same image for sake of simplicity, but it is useful when comparing the results of changing the image processing coefficients.

Concatenate same images vertically and horizontally

When arranging the same image repeatedly, np.tile() can be used as before.

When concatenating color images (3D ndarray), set the second parameter (reps) to (The number of vertical repetitions、The number of horizontal repetitions、1). For grayscale images (2D ndarray), set reps to (n vertical, n horizontal).

Concatenate images of different sizes in vertical and horizontal tiles

When concatenating images of different sizes in vertical and horizontal tiles, use the resizing and concatenating function defined above.

def concat_tile_resize(im_list_2d, interpolation=cv2.INTER_CUBIC):
    im_list_v = [hconcat_resize_min(im_list_h, interpolation=cv2.INTER_CUBIC) for im_list_h in im_list_2d]
    return vconcat_resize_min(im_list_v, interpolation=cv2.INTER_CUBIC)

im_tile_resize = concat_tile_resize([[im1],
                                     [im1, im2, im1, im2, im1],
                                     [im1, im2, im1]])
cv2.imwrite('data/dst/opencv_concat_tile_resize.jpg', im_tile_resize)

Python OpenCV concat tile resize

Sponsored Link
Share

Related Categories

Related Posts