Skip to content

Instantly share code, notes, and snippets.

@ajay1685
Last active July 8, 2024 19:39
Show Gist options
  • Save ajay1685/24f07e220db6d19158f558fa2135d605 to your computer and use it in GitHub Desktop.
Save ajay1685/24f07e220db6d19158f558fa2135d605 to your computer and use it in GitHub Desktop.
Merge channels and save as OME-TIFF using pyvips.
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 19 14:45:08 2021
@author: Ajay Zalavadia (zalavadia.ajay@gmail.com)_
"""
import math
import os
import glob
import logging
from tqdm import tqdm
logging.basicConfig(level=logging.WARN) #change to INFO for more details
# Add vips binaries to path
vipshome = 'c:\\apps\\vips-dev-8.14\\bin'
os.environ['PATH'] = vipshome + ';' + os.environ['PATH']
import pyvips
logging.info("vips version: " + str(pyvips.version(0))+"."+str(pyvips.version(1))+"."+str(pyvips.version(2)))
imagedir = 'D:\\input'
outputdir = imagedir #change this to save to a different folder
dataSets = glob.glob1(imagedir, '*_ch00.tif')
def eval_cb(image, progress):
pbar_filesave.update(progress.percent - pbar_filesave.n)
for idx, dataset in enumerate(dataSets):
str1 = dataset.split("_ch00.tif", 2)
#print("Processing: "+ str1[0] + " " + str(idx) + " out of " + str(len(dataSets)))
imagePrefix = str1[0]
imageFiles = glob.glob(imagedir+'/'+imagePrefix+'_ch*.tif')
outfilename = imagePrefix + '.ome.tif'
outfile = os.path.join(outputdir, outfilename)
pbar_filesave = tqdm(total=100, unit="Percent", desc=outfilename, position=0, leave=True)
images = [pyvips.Image.new_from_file(os.path.join(imagedir, filename), access="sequential") for filename in imageFiles]
out = pyvips.Image.arrayjoin(images, across=1)
out = out.copy()
out.set_type(pyvips.GValue.gint_type, "page-height", images[0].height)
# Parameters for OME metadata
width = images[0].width
height = images[0].height
# Need to handle more data types
data_type = "uint8"
if (images[0].interpretation=="grey16"):
data_type = "uint16"
bands = int(out.height/images[0].height)
CalibrationX = 1000/float(out.xres) #Or out.xres
CalibrationY = 1000/float(out.yres) #Or out.yres
CalibrationUnits = "µm" #Or out.get("resolution-unit")
# build minimal OME metadata
metadata = f"""<?xml version="1.0" encoding="UTF-8"?>
<OME xmlns="http://www.openmicroscopy.org/Schemas/OME/2016-06"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openmicroscopy.org/Schemas/OME/2016-06 http://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd">
<Image ID="Image:0">
<!-- Minimum required fields about image dimensions -->
<Pixels DimensionOrder="XYCZT"
ID="Pixels:0"
SizeC="{bands}"
SizeT="1"
SizeX="{width}"
SizeY="{height}"
SizeZ="1"
Type="{data_type}"
PhysicalSizeX="{CalibrationX}"
PhysicalSizeXUnit="{CalibrationUnits}"
PhysicalSizeY="{CalibrationY}"
PhysicalSizeYUnit="{CalibrationUnits}">
</Pixels>
</Image>
</OME>"""
out.set_type(pyvips.GValue.gstr_type, "image-description", metadata)
out.set_progress(True)
out.signal_connect('eval', eval_cb)
out.write_to_file(outfile, compression='lzw', tile=True, tile_width=512, tile_height=512, pyramid=True, subifd=True, bigtiff=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment