#!/usr/bin/env python
# -*- coding: utf-8 -*
import subprocess
import os
import sys
import SimpleITK as sitk
import numpy as np
import skimage
import tifffile as tf
# in order to find the metamorphosis binary
ndregDirPath = os.path.dirname(os.path.realpath(__file__)) + "/"
[docs]def is_iterable(variable):
"""
Returns True if variable is a list, tuple or any other iterable object
"""
return hasattr(variable, '__iter__')
[docs]def is_number(variable):
"""
Returns True if varible is is a number
"""
try:
float(variable)
except TypeError:
return False
return True
[docs]def run_shell_command(command, checkReturnValue=True, verbose=False):
"""
Runs a shell command and returns the output.
"""
process = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
bufsize=1)
outText = ""
for line in iter(process.stdout.readline, ''):
if verbose:
sys.stdout.write(line)
outText += line
# process.wait()
process.communicate()[0]
returnValue = process.returncode
if checkReturnValue and (returnValue != 0):
raise Exception(outText)
return (returnValue, outText)
[docs]def txt_write(text, path, mode="w"):
"""
Conveinence function to write text to a file at specified path
"""
dir_make(os.path.dirname(path))
textFile = open(path, mode)
textFile.write(text)
textFile.close()
[docs]def txt_read(path):
"""
Conveinence function to read text from file at specified path
"""
textFile = open(path, "r")
text = textFile.read()
textFile.close()
return text
[docs]def txt_read_list(path):
return map(float, txt_read(path).split())
[docs]def txt_write_list(parameterList, path):
txt_write(" ".join(map(str, parameterList)), path)
[docs]def dir_make(dirPath):
"""
Convenience function to create a directory at the given path
"""
if dirPath != "":
if not os.path.exists(dirPath):
os.makedirs(dirPath)
return os.path.normpath(dirPath) + "/"
else:
return dirPath
[docs]def imgCopy(img):
"""
Returns a copy of the input image
"""
return sitk.Image(img)
[docs]def imgWrite(img, path):
"""
Write sitk image to path.
"""
dir_make(os.path.dirname(path))
sitk.WriteImage(img, path)
outFile.write(line)
[docs]def imgCollapseDimension(inImg, dimension=3):
inSize = inImg.GetSize()
if inImg.GetDimension() == dimension and inSize[dimension - 1] == 1:
outSize = list(inSize)
outSize[dimension - 1] = 0
outIndex = [0] * dimension
inImg = sitk.Extract(inImg, outSize, outIndex, 1)
return inImg
[docs]def imgRead(path):
"""
Alias for sitk.ReadImage
"""
inImg = sitk.ReadImage(path)
inImg = imgCollapseDimension(inImg)
# if(inImg.GetDimension() == 2): inImg =
# sitk.JoinSeriesImageFilter().Execute(inImg)
inDimension = inImg.GetDimension()
inImg.SetDirection(sitk.AffineTransform(inDimension).GetMatrix())
inImg.SetOrigin([0] * inDimension)
return inImg
[docs]def img_percentile(img, percentile):
if percentile < 0.0 or percentile > 1.0:
raise Exception("Percentile should be between 0.0 and 1.0")
(values, bins) = np.histogram(sitk.GetArrayFromImage(img), bins=255)
cumValues = np.cumsum(values).astype(float)
cumValues = (cumValues - cumValues.min()) / cumValues.ptp()
index = np.argmax(cumValues > percentile) - 1
value = bins[index]
return value
[docs]def merge_tiffs(path_to_tiffs, filename):
# merge the tiffs
files = os.listdir(path_to_tiffs)
files = [f for f in files if f.endswith('.tif') or f.endswith('.tiff')]
# make sure the tifs are in the right order
files = np.sort(files)
# now lets go through them and make a tif
combined_tiff = sitk.ReadImage(files)
# now save the tiff
sitk.WriteImage(combined_tiff, filename)
return combined_tiff
[docs]def get_downsample_factor(voxel_sizes, desired_spacing):
return [int(i) for i in desired_spacing / voxel_sizes]
[docs]def downsample_and_merge_tiffs(path_to_tiffs, voxel_sizes, desired_spacing, load_at_once=50):
files = os.listdir(path_to_tiffs)
files = [f for f in files if f.endswith('.tif') or f.endswith('.tiff')]
# make sure the tifs are in the right order
files = np.sort(files)
# now lets go through them and downsample them
downsample_factor = get_downsample_factor(voxel_sizes, desired_spacing)
slice_num = 0
whole_image = []
while slice_num < len(files):
img = tf.imread(files[slice_num:slice_num+load_at_once])
# downsample image by downsample factor in x, y, and z.
# reversing direction because assuming 'z' is the first entry in the downsample factor list
img_ds = skimage.measure.block_reduce(img, downsample_factor[::-1], func=np.mean)
whole_image.append(img_ds)
slice_num += load_at_once
if slice_num > len(files): slice_num = len(files)
whole_image_np = np.zeros(whole_image[0].shape[:2].append(len(files)))
# for i in whole_image:
# np.
return img_ds