У меня есть 360000 изображений размером 800x600 пикселей. Мне нужно сшить с перекрытием все эти изображения, чтобы создать полное изображение, которое можно увеличить, чтобы просмотреть детали. Как мне сделать изображение .dzi из этих базовых плиток, используя библиотеку pyvips?
Я пытался создать изображение в формате jpeg, прежде чем конвертировать его в .dzi. Это не то, чего я хочу. Я хочу создать изображение .dzi из базового изображения плитки.
вот что я делал до сих пор:
import pyvips
import glob
#creating image array
jpeg_images = glob.glob('*.jpg')
array_images= []
for i in jpeg_images:
tile = pyvips.Image.new_from_file(i, access = "sequential")
array_images.append(tile)
#Join them, across is how many pictures there be next to each other
out = pyvips.Image.arrayjoin(array_images,
across=len(jpeg_images)/2)
#write it out to file
out.write_to_file('big_dummy.jpg', Q=95)
#read the image
source_image = pyvips.Image.new_from_file(r'D:\Image
processing\merge_images_python\dummy_images3\big_dummy.joeg')
#create the dzi image
source_image.dzsave('pyramid_new')
Вау, сколько картинок. Их нужно располагать по отдельности или они расположены в обычной сетке? Вам не нужно писать во временный файл, вы можете сохранить результат объединения массивов непосредственно в dzi.
Сделал вам малюсенькую тестовую прогу:
#!/usr/bin/python3
import sys
import glob
import pyvips
input_directory = sys.argv[1]
output_file = sys.argv[2]
tiles_across = int(sys.argv[3])
images = [pyvips.Image.new_from_file(filename, access = "sequential")
for filename in glob.glob(f"{input_directory}/*.jpg")]
joined = pyvips.Image.arrayjoin(images, across=tiles_across)
joined.write_to_file(output_file)
Я сделал некоторые образцы данных, подобные этому:
$ mkdir sample
$ vips crop ~/pics/k2.jpg x.jpg 0 0 800 600
$ for i in {1..2500}; do cp x.jpg sample/$i.jpg; done
т.е. достаточно фрагментов jpg для мозаики 50x50, затем запустил программу python следующим образом:
$ /usr/bin/time -f %M:%e ./arrayjoin.py sample x.dz 50
3893844:14.39
Итак 4g памяти для мозаики 50x50 и это заняло 14 секунд. На 100x100 ушло 1 минута и 9,6 ГБ, а на мозаику 150x150 — 2 минуты и 17 ГБ.
Таким образом, использование памяти приблизительно масштабируется по тайлам, а прошедшее время масштабируется по количеству пикселей (очень приблизительно).
Вам нужно около 600x600 (вау!), поэтому я ожидаю, что вам понадобится, может быть, 100 ГБ памяти и 30 минут времени обработки.
Вам понадобится очень большой компьютер, или собирать мозаику по частям. Вы можете выполнить серию соединений 100x100 с набором из 36 временных файлов, а затем, например, выполнить второе соединение 6x6.
Обновите, чтобы присоединиться к набору плиток с координатами в имени файла, просто используйте имена, чтобы составить список строк, например:
images = []
for y in range(tiles_down):
for x in range(tiles_across):
filename = f"{input_directory}/{x}_{y}.jpg"
images.append(pyvips.Image.new_from_file(filename,
access = "sequential"))
Я попробовал вашу тестовую программу. Оно работает!!!. Но все же мне нужно придумать, как масштабировать этот код для 600x600. Я думаю добавить еще две функции: 1. Я хотел бы иметь меньше уровней в файле пирамиды, чтобы я мог сэкономить немного памяти. Могу пожертвовать плавностью зума. 2. Мои файлы изображений называются с координатами их центра. Я хотел бы сшить его в соответствии с его координатой. Есть ли какое-либо решение в библиотеке pyvips?
К сожалению, пропуск уровней не сэкономит память. Вы можете уменьшить параллелизм, это немного поможет — установите VIPS_CONCURRENCY
на 1. Просто проанализируйте имена файлов и отсортируйте список в порядке строк.
Можно ли соединять тайлы по координатам?
Да, анализировать имена файлов и использовать координаты для сортировки изображений в порядке строк.
Я добавил пример кода.
хорошо. У меня есть некоторые области, где есть перекрытие между изображениями. Может быть, я смогу сделать равномерное перекрытие между всеми изображениями. Есть ли какой-либо атрибут перекрытия в Image.arrayjoin?
arrayjoin работает только с обычными сетками изображений. Я бы посмотрел на оператор слияния, но он немного сложнее.
Может быть, вы можете поделиться тем, что вы сделали до сих пор. фрагмент кода сделает