объединить 4 изображения с помощью np.concatenate (два по вертикали и два по горизонтали) - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть четыре изображения, и я хочу объединить их в 1 изображение. Я попытался использовать функцию объединения, но есть несколько изображений, и из них мне нужно только в серии из 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)

1 Ответ

2 голосов
/ 22 апреля 2020

Это должно сработать, или, по крайней мере, начать. Он выбирает красный цвет в качестве фона и делает изображение заливки 1x1 того же цвета. Затем он группирует ваши изображения по четыре и заполняет последнюю группу, если не кратно 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)

Он создает выходные изображения, как это:

enter image description here


Обратите внимание, что вы можете сделать то же самое просто используя несколько строк bash сценария оболочки, если вы используете ImageMagick :

#!/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, монтаж, группировка, группировка, по четыре, по четыре.

...