首页 > 解决方案 > 使用 np.concatenate 连接 4 个图像(两个垂直和两个水平)

问题描述

我有四张图像,我想将它们连接成一张图像。我尝试使用连接功能,但有多个图像,我只需要一批 4 张图像。

实际上图像被命名为0.jpg, 1.jpg,2.jpg and 3.jpg 下面是包含四个图像并将它们连接成一个图像的代码。但是我在一个文件夹中有大约 500 张图像,我想根据 first4 然后是 second 4 等范围将它们分成四组。

import numpy as np 
import glob,os
import cv2

directory = "./image/"

for image in sorted(glob.glob(directory + '*.jpg'),key=os.path.getmtime):   

    name = image.split('/')[-1]
    iname = name.split('.')[0]
    print(iname)                    
    img1 = cv2.imread('0.jpg') 
    img2 = cv2.imread('1.jpg')
    vis1 = np.concatenate((img1, img2), axis=1)
    img3 = cv2.imread('2.jpg')
    img4 = cv2.imread('3.jpg')
    vis2 = np.concatenate((img3, img4), axis=1)
    vis = np.concatenate((vis1, vis2), axis=0)
    cv2.imwrite(iname+'.jpg', vis1)

标签: pythonnumpyimage-processingconcatenationglob

解决方案


这应该可以解决问题,或者至少可以帮助您入门。它选择红色作为背景颜色,并使 1x1 填充(填充)图像具有相同的颜色。然后,它将您的图像按 4 分组,如果不是 4 的倍数,则填充最后一组。然后迭代列表并在每次迭代时打开 4 个图像。它获取它们的大小,然后确定输出图像的宽度和高度。然后它创建用背景颜色填充的输出图像,然后将图像粘贴到背景上并保存结果。

您可以选择改进布局,但这只是摆弄美学,所以您可以做到这一点!

#!/usr/bin/env python3

import cv2
import os, glob
from itertools import zip_longest

def grouper(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 = 1
for 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)

它创建这样的输出图像:

在此处输入图像描述


请注意,如果您使用ImageMagick ,只需使用几行 bash shell 脚本即可执行相同的操作:

#!/bin/bash

# Build list of images
images=(*.jpg)

out=1
# Keep going till there are fewer than 4 left in list
while [ ${#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

关键词:Python、OpenCV、蒙太奇、分组、四人一组、四人一组。


推荐阅读