python - 使用 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)
解决方案
这应该可以解决问题,或者至少可以帮助您入门。它选择红色作为背景颜色,并使 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、蒙太奇、分组、四人一组、四人一组。
推荐阅读
- android - 如何防止 BottomNavigationView(使用导航组件设置)更改目标单击项目
- python - 简单的 glob 命令在打印语句中不返回任何内容
- javascript - 在Django 3.2上用ajax返回数据替换html网页
- angular - Angular2+/Rxjs Observable 构造函数/ngOnInit - 路由 onPageChange
- reactjs - 如何访问 ReactQuill api?
- reactjs - Android 上的 React Navigation 身份验证流程
- ruby-on-rails - 嵌套 jsonb 字段的 ActiveAdmin 表单
- java - 如何对素数数组进行排序
- ios - UIPasteboard 返回 nil 甚至被检测为 probableWebURL
- python - 智能算法识别错误符号的数字