I have 360000 images of 800x600 pixel size. I need to stitch with overlap all these images to create a full image that can be zoomed in to view details. How do I make a .dzi image from these base tiles using pyvips library?
I tried to create a jpeg image before coverting it to .dzi. Which is not something that i want. I want to build .dzi image from the base tile image.
the following is what i did until now:
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')
I made you a tiny test prog:
#!/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)
I made some sample data like this:
$ 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
ie. enough jpg tiles for a 50x50 mosaic, then ran the python program like this:
$ /usr/bin/time -f %M:%e ./arrayjoin.py sample x.dz 50
3893844:14.39
So 4g of memory for a 50x50 mosaic and it took 14 seconds. A 100x100 took 1 minute and 9.6gb, and a 150x150 mosaic took 2 minutes and 17gb.
Therefore, memory use scales approximately with tiles across and elapsed time scales with number of pixels (very roughly).
You need about 600x600 (wow!) so I'd expect you to need maybe 100gb of memory and 30 minutes of processing time.
You are going to need a very large PC, or to assemble the mosaic in sections. You could do a series of 100x100 joins to a set of 36 temporary files, then do a second 6x6 join, for example.
Update to join a set of tiles with the coordinates in the filename, just use the names to make a row-major list, perhaps:
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"))