【问题标题】:to concatenate 4 images using np.concatenate (two vertically and two horizontally)使用 np.concatenate 连接 4 个图像(两个垂直和两个水平)
【发布时间】:2020-04-22 03:14:20
【问题描述】:

我有四张图像,我想将它们连接成一张图像。我尝试使用连接功能,但有多个图像,我只需要一批 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)

【问题讨论】:

  • 图片的形状都一样吗?您可以遍历索引并水平堆叠前 2 个和后 2 个,然后垂直堆叠它们
  • @alan.elkin 不,它们都是不同的形状。我不知道如何遍历索引。
  • vis = np.block([[img1, img2],[img3, img4]]) 可能会做同样的事情。在幕后,它执行相同的连接集。

标签: python numpy image-processing concatenation glob


【解决方案1】:

这应该可以解决问题,或者至少可以帮助您入门。它选择红色作为背景颜色,并使 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、蒙太奇、分组、分组、四人一组、四人一组。

【讨论】:

    猜你喜欢
    • 2021-06-13
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    相关资源
    最近更新 更多