сшивать изображения вместе в python

Я пытаюсь сшить вместе около 50 изображений (все одного размера 287x287). В частности, должно быть 25 изображений в верхней строке и 25 изображений в нижней строке, а также существует небольшое расстояние между каждыми двумя изображениями.

Во время своих попыток я столкнулся с двумя трудностями:

Первая проблема заключается в том, что 25 изображений находятся в папке с их именем 'prefix-70',...,'prefix-94', а остальные 25 изображений находятся в другой папке с тем же именем 'prefix-70',...,'prefix-94'. Я не знаю, как им в Python без конфликтов.

Вторая проблема заключается в том, что я написал следующий код для чтения изображений одной папки для формирования строки, но он выводит столбец.

#!/usr/bin/python3.0
#encoding=utf-8

import numpy as np
from PIL import Image
import glob,os

if __name__=='__main__':
    #prefix=input('Input the prefix of images:')
    prefix = 'prefix'
    files=glob.glob(prefix+'-*')
    num=len(files)

    filename_lens=[len(x) for x in files] #length of the files
    min_len=min(filename_lens) #minimal length of filenames
    max_len=max(filename_lens) #maximal length of filenames
    if min_len==max_len:#the last number of each filename has the same length
    files=sorted(files) #sort the files in ascending order
else:
    index=[0 for x in range(num)]
    for i in range(num):
        filename=files[i]
        start=filename.rfind('-')+1
        end=filename.rfind('.')
        file_no=int(filename[start:end])
        index[i]=file_no
    index=sorted(index)
    files=[prefix+'-'+str(x)+'.png' for x in index]

print(files[0])
baseimg=Image.open(files[0])
sz=baseimg.size
basemat=np.atleast_2d(baseimg)
for i in range(1,num):
    file=files[i]
    im=Image.open(file)
    im=im.resize(sz,Image.ANTIALIAS)
    mat=np.atleast_2d(im)
    print(file)
    basemat=np.append(basemat,mat,axis=0)
final_img=Image.fromarray(basemat)
final_img.save('merged.png')

Я думаю, что я попал в неправильный путь... Как я могу их правильно сшить? Любое предложение приветствуется.


person Community    schedule 17.03.2017    source источник
comment
Чтобы получить строку вместо столбца, просто измените axis=0 на axis=1.   -  person Junuxx    schedule 17.03.2017
comment
Спасибо. И как я мог сделать расстояние между изображениями и как построить две строки, как сказано в задаче один?   -  person    schedule 17.03.2017


Ответы (2)


Попробуйте это (объяснение в комментариях):

from PIL import Image
from os import listdir, path

space_between_row = 10
new_image_path = 'result.jpg'
im_dirs = ['images/1', 'images/2']

# get sorted list of images
im_path_list = [[path.join(p, f) for f in sorted(listdir(p))] for p in im_dirs]

# open images and calculate total widths and heights
im_list = []
total_width = 0
total_height = 0
for path_list in im_path_list:
    images = list(map(Image.open, path_list))
    widths, heights = zip(*(i.size for i in images))
    total_width = max(total_width, sum(widths))
    total_height += max(heights)
    im_list.append(images)

# concat images
new_im = Image.new('RGB', (total_width, total_height))
y_offset = 0
for images in im_list:
    x_offset = 0
    max_height = 0
    for im in images:
        new_im.paste(im, (x_offset, y_offset))
        x_offset += im.size[0]
        max_height = max(im.size[1], max_height)
    y_offset = y_offset + max_height + space_between_row

# show and save
new_im.show()
new_im.save(new_image_path)
person Yohanes Gultom    schedule 17.03.2017
comment
Огромное спасибо вам, как новичок, я многому у вас научился. У меня есть еще один вопрос, поскольку все изображения на самом деле представляют собой черный фон с несколькими белыми точками, я обнаружил, что кажется, что изображения тесно сшиты, поскольку приведенный выше код разделяет два изображения черной областью. Могу ли я разделить их по белой области? - person ; 17.03.2017
comment
@fdafdsjflasdjlfas вы можете передать параметр color при создании базового образа new_im = Image.new('RGB', (total_width, total_height), color=(255, 255, 255)). Это то, что вы имели ввиду? - person Yohanes Gultom; 17.03.2017

Установите ImageMagick, а затем сообщите ему, где находятся ваши два каталога.

#!/usr/bin/python3
##=========================================================
##  required  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##
##  imagemagick.org/script/download.php
##
##=========================================================
##  libs  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

import subprocess as sp

##=========================================================
##  vars  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

offset  = 2                    ##  pixel gap between images
color  = '#000000'        ##  background color to fill gaps

dir1  = '/home/me/Pictures/topRow/'

dir2  = '/home/me/Pictures/bottomRow/'

##  note: windows dirs use double backslashes
##  'C:\\Users\\me\\Pictures\\topRow\\'
##=========================================================
##  script  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

row1args  = ['convert', '+smush', offset, '-background', color, dir1 + '*.png', 'row1.png']
row2args  = ['convert', '+smush', offset, '-background', color, dir2 + '*.png', 'row2.png']
merge  = ['convert', '-smush', offset, '-background', color, 'row*.png', 'merged.png']

##=========================================================
##  main  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

sp .call(row1args)
sp .call(row2args)
sp .call(merge)

##=========================================================
##  eof  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
person Doyousketch2    schedule 17.03.2017
comment
На самом деле это не ответ на то, что показал ОП. - person MKesper; 17.03.2017
comment
Это то, как я сделал бы это в Python. ImageMagick создан именно для этого, поэтому есть смысл его использовать. - person Doyousketch2; 17.03.2017