Add initial files.

This commit is contained in:
jmsgrogan 2017-02-16 15:26:55 +00:00
parent 1f228d3d2a
commit 00fa3da2eb
24 changed files with 14465 additions and 0 deletions

47
README.md Normal file
View file

@ -0,0 +1,47 @@
This is a collection of tools for working with 3D image stacks of microvessel networks
### All Dependencies (individual scripts have only a subset of these dependencies)
* [bftools](http://www.openmicroscopy.org/site/support/bio-formats5.3/users/comlinetools/)
* [pyxb](https://pypi.python.org/pypi/PyXB)
* [VTK with Python Interface](http://www.vtk.org/download/)
* [Scikit Image]
* [VMTK](http://www.vmtk.org/)
* [Microvessel Chaste](https://jmsgrogan.github.io/MicrovesselChaste/)
### Working with ZEISS (IMS, LSM, CZI) Image Data
It is useful to first extract the image metadata. This requires a copy of [bftools](http://www.openmicroscopy.org/site/support/bio-formats5.3/users/comlinetools/).
Download it and set`$BFTOOLS_DIR` to the directory obtained after unzipping. Then do:
```bash
python format_conversion/extract_zeiss_metadata.py -i $IMAGE_PATH -o $OUTPUT_FILE --verbose 1
```
To proceed we need to convert the format to an OME TIFF and then a generic TIFF. It is easiest to work with
one series and one channel at a time. Since we work with large images it is best to split the images into tiles and
work in parallel.
```bash
python format_conversion/zeiss_to_tiff.py -i $IMAGE_PATH -o $OUTPUT_FOLDER
```
### Working with 3D TIFFs
After conversion we can work with the 3D TIFFs using packages like sci-kit. It is important to remember that
the generic TIFFs we have produced have all of their physical dimensions stripped. We do not trust any tools to
preserve physical dimensions. The original OME metadata XML is the only reference we use.
For easy visualization it is useful to downsample and then re-assemble the tiles.
```bash
python image/downsample_tiffs.py -i $IMAGE_PATH -x 3 -y 3 -z 1
```
### Visualizing
We can use FIJI or VTK to visualize. VTK is nicer, but struggles with full resolution datasets. We can downsample
as described previoulsy and then create VTK files for use in paraview.
```bash
python format_conversion/tiff_to_vtk.py -i $IMAGE_PATH -m $METADATA_FILE -tx 1024 -ty 1024 -dx 3 -dy 3 -dz 1
```
Even with this it is difficult to make nice volume renders as resource use is high. To launch a simple VTK window do:

View file

View file

@ -0,0 +1,50 @@
"""
Wrapper over bftools
"""
import os
import subprocess
def convert(input_path, output_path, tile_x=None, tile_y=None,
channel=0, series=0, crop_indices = None, bigtiff=False):
"""
Convert an input image in ZEISS LSM or CZI format to an OME TIFF.
Slice spacing information is lost in this operation for some reason.
"""
# Set up the command for bfconvert
bf_tools_dir = os.getenv('BFTOOLS_DIR', os.getcwd()) + "/"
command = bf_tools_dir + "/bfconvert "
if not os.path.exists(output_path):
os.makedirs(output_path)
output_path += "/" + os.path.splitext(input_path)[0] + "_T%t"
# Only one channel at a time
command += " -channel " + str(channel) + " "
output_path += "_C%c"
# Only one series at a time
command += " -series " + str(series) + " "
output_path += "_S%s"
# Set up tiles
if tile_x is not None and tile_y is not None:
command += " -tilex " + str(tile_x) + " -tiley " + str(tile_y) + " "
output_path += "_tile_X%x_Y%y_ID_%m"
# bigtiff
if bigtiff:
command += " -bigtiff "
# crop
if crop_indices is not None:
command += " -crop " + str(int(crop_indices[4])) + "," + str(int(crop_indices[5]))
command += "," + str(int(crop_indices[6])) + "," + str(int(crop_indices[7])) + " "
global_index = crop_indices[0] + crop_indices[1]*crop_indices[2]
output_path += "_x_"+ str(int(crop_indices[0])) + "_y_" + str(int(crop_indices[1])) + "_m_" + str(int(global_index))
command += input_path + " " + output_path + ".tiff"
# Do the conversion
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
p.wait()

View file

@ -0,0 +1,103 @@
#!/usr/bin/env python
"""
Extract and Parse Metadata from IMS/LSM/CZI files.
"""
from argparse import ArgumentParser
import os
import subprocess
import logging
import utility
import ome_schema
def extract_metadata(input_path, output_path):
"""
Extract OME metadata from the input file and write it out as a nicely formatted xml using
bftools. (http://www.openmicroscopy.org/site/support/bio-formats5.3/users/comlinetools/display.html)
"""
bf_tools_dir = os.getenv('BFTOOLS_DIR', os.getcwd()) + "/"
command = bf_tools_dir +"showinf -omexml-only -nopix " + input_path + " | " + bf_tools_dir + "xmlindent > " + output_path
p = subprocess.Popen(command, shell=True)
p.wait()
def get_metadata_as_class(input_xml_path):
"""
Return the OME metadata from the input XML file as a Python class. The class is automatically generated
using pyxbgen (http://pyxb.sourceforge.net/pyxbgen_cli.html) and the current OME XML Schema
(https://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd).
If you need to use a newer schema you need to regenerate the file ome_schema.py by doing:
pip install pyxb
pyxbgen -m ome_schema -u https://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd
where the web address points to the new schema. You can then access the elements of the OME XML as
instance attributes etc.
"""
xml = open(input_xml_path).read()
image_metadata = ome_schema.CreateFromDocument(xml)
return image_metadata
def integer_color_to_rgb(color):
"""
Convert integer color to (r,g,b)
"""
return ((color >> 16) & 255, (color >> 8) & 255, color & 255)
def print_metadata_overview(image_metadata):
"""
Print a reader-friendly metadata summary
"""
print "Number of Images: ", len(image_metadata.Image)
print "Image '0' - Name: ", image_metadata.Image[0].Name
print "Image '0' - Num Channels: ", image_metadata.Image[0].Pixels.SizeC
print "Image '0' - Num Times: ", image_metadata.Image[0].Pixels.SizeT
pixel_size_x = image_metadata.Image[0].Pixels.PhysicalSizeX
pixel_size_y = image_metadata.Image[0].Pixels.PhysicalSizeY
pixel_size_z = image_metadata.Image[0].Pixels.PhysicalSizeZ
pixel_unit_x = image_metadata.Image[0].Pixels.PhysicalSizeXUnit
pixel_unit_y = image_metadata.Image[0].Pixels.PhysicalSizeYUnit
pixel_unit_z = image_metadata.Image[0].Pixels.PhysicalSizeZUnit
print "Image '0' - Pixel Physical Size X: ", pixel_size_x, pixel_unit_x
print "Image '0' - Pixel Physical Size Y: ", pixel_size_y, pixel_unit_y
print "Image '0' - Pixel Physical Size Z: ", pixel_size_z, pixel_unit_z
print "Image '0' - Pixel Size X: ", image_metadata.Image[0].Pixels.SizeX
print "Image '0' - Pixel Size Y:", image_metadata.Image[0].Pixels.SizeY
print "Image '0' - Pixel Size Z:", image_metadata.Image[0].Pixels.SizeZ
print "Image '0' - Pixel Dimension Order: ", image_metadata.Image[0].Pixels.DimensionOrder
print "Image '0' - Pixel Bits: ", image_metadata.Image[0].Pixels.SignificantBits
for idx, eachChannel in enumerate(image_metadata.Image[0].Pixels.Channel):
print "Image '0' - Channel " +str(idx) + " Color: ", integer_color_to_rgb(eachChannel.Color)
if __name__ == "__main__":
# Do setup
tool_name = "extract_metadata"
utility.do_setup(tool_name)
logger1 = logging.getLogger('format_conversion.'+tool_name)
# Suppress XML Parse warnings
pyxb_logger = logging.getLogger('pyxb')
pyxb_logger.setLevel(logging.CRITICAL)
parser = ArgumentParser()
parser.add_argument("-i", "--input_file", type=str, help='Input file in a ZEISS format.')
parser.add_argument("-o", "--output_file", type=str, help='Output metadata file.')
parser.add_argument("--verbose", type=bool, help='Output a simple metadata summary.')
args = parser.parse_args()
logger1.info('Reading Metadata At: ' + args.input_file)
extract_metadata(args.input_file, args.output_file)
if(args.verbose):
image_metadata = get_metadata_as_class(args.output_file)
print_metadata_overview(image_metadata)
logger1.info('Completed Reading Metadata')

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,120 @@
"""
Convert to VTK. Use pvti files for final assembly.
"""
import os
import logging
import math
from argparse import ArgumentParser
from functools import partial
import multiprocessing as mp
import vtk
import utility
import extract_zeiss_metadata
def do_conversion(file_attributes, working_directory):
reader = vtk.vtkTIFFReader()
reader.SetFileName(file_attributes["FileName"])
reader.Update()
image_data = reader.GetOutput()
image_data.SetExtent(file_attributes["Extents"])
image_data.SetSpacing(file_attributes["PhysicalSize"])
out_path = working_directory + "/" + os.path.splitext(os.path.basename(file_attributes["FileName"]))[0] + ".vti"
writer = vtk.vtkXMLImageDataWriter()
writer.SetInputData(image_data)
writer.SetFileName(out_path)
writer.Write()
def convert_to_vti(input_folder, metadata_file, tile_dimensions, downsample_dimensions):
extract_zeiss_metadata.extract_metadata(metadata_file, os.getcwd() + "temp_metadata.xml")
image_metadata = extract_zeiss_metadata.get_metadata_as_class(os.getcwd() + "temp_metadata.xml")
num_x = int(math.floor(image_metadata.Image[0].Pixels.SizeX/tile_dimensions[0]))+1
num_y = int(math.floor(image_metadata.Image[0].Pixels.SizeY/tile_dimensions[1]))+1
size_x = int(math.floor(tile_dimensions[0]/downsample_dimensions[0]))+1
size_y = int(math.floor(tile_dimensions[1]/downsample_dimensions[1]))+1
size_z = int(math.floor(image_metadata.Image[0].Pixels.SizeZ/downsample_dimensions[2]))
physical_x = float(image_metadata.Image[0].Pixels.PhysicalSizeX)*float(downsample_dimensions[0])
physical_y = float(image_metadata.Image[0].Pixels.PhysicalSizeY)*float(downsample_dimensions[1])
physical_z = float(image_metadata.Image[0].Pixels.PhysicalSizeZ)*float(downsample_dimensions[2])
# Grab the file base name. Assume the input folder only has the tiff files we want to convert
path_base_name = ""
for eachFile in os.listdir(input_folder):
if eachFile.endswith(".tiff"):
loc_start_index = eachFile.find("_tile")
if loc_start_index>-1:
path_base_name = input_folder + "/" + eachFile[:loc_start_index]
break
file_attribute_collection = []
for jdx in range(num_y):
for idx in range(num_x):
global_index = idx + jdx*num_x
file_name = path_base_name + "_tile_X" + str(idx) + "_Y" + str(jdx) + "_ID_" + str(global_index)+"_pixels_only_downsampled.tiff"
min_ext_x = idx*size_x
min_ext_y = jdx*size_y
max_ext_x = (idx+1)*size_x-1
max_ext_y = (jdx+1)*size_y-1
min_ext_z = 0
max_ext_z = size_z-1
if idx == num_x - 1:
max_ext_x = int(math.floor(image_metadata.Image[0].Pixels.SizeX/downsample_dimensions[0]))+2
if jdx == num_y - 1:
max_ext_y = int(math.floor(image_metadata.Image[0].Pixels.SizeY/downsample_dimensions[1]))+2
extents = [min_ext_x, max_ext_x, min_ext_y, max_ext_y, min_ext_z, max_ext_z]
file_attributes = {}
file_attributes["PhysicalSize"]= (physical_x, physical_y, physical_z)
file_attributes["Extents"]= extents
file_attributes["FileName"]= file_name
file_attribute_collection.append(file_attributes)
# Make a partial function for multiple arg mapping
working_directory = os.getcwd() + "/VTK_Files/"
if not os.path.exists(working_directory):
os.makedirs(working_directory)
partial_extract_pixel_values_only = partial(do_conversion, working_directory=working_directory)
# Limit to max 6 cpus
num_available_cpus = mp.cpu_count()
if num_available_cpus > 6:
num_available_cpus = 6
# Distribute across processes - Be conservative with available CPUs
run_cpus = int(math.floor(num_available_cpus/2))
if run_cpus == 0:
run_cpus = 1
#pool = mp.Pool(processes = run_cpus)
pool = mp.Pool(processes = 1)
pool.map(partial_extract_pixel_values_only, file_attribute_collection)
if __name__ == "__main__":
# Do setup
tool_name = "zeiss_to_tiff"
utility.do_setup(tool_name)
logger1 = logging.getLogger('tiff_to_vtk.'+tool_name)
# Suppress XML Parse warnings
pyxb_logger = logging.getLogger('pyxb')
pyxb_logger.setLevel(logging.CRITICAL)
parser = ArgumentParser()
parser.add_argument("-i", "--input_folder", type=str, help='Folder with tiffs to be converted.')
parser.add_argument("-m", "--metadatafile", type=str, help='File with image metadata.')
parser.add_argument("-tx", "--tile_x", type=int, help='X Tile size.')
parser.add_argument("-ty", "--tile_y", type=int, help='Y Tile Size.')
parser.add_argument("-dx", "--downsample_x", type=int, help='X Downsample Factor.', default=1)
parser.add_argument("-dy", "--downsample_y", type=int, help='Y Downsample Factor.', default=1)
parser.add_argument("-dz", "--downsample_z", type=int, help='Y Downsample Factor.', default=1)
args = parser.parse_args()
logger1.info('Start Converting Images to VTI at: ' + args.input_folder)
convert_to_vti(args.input_folder, args.metadatafile, (args.tile_x, args.tile_y),
(args.downsample_x, args.downsample_y, args.downsample_z))
logger1.info('Completed Converting')

View file

@ -0,0 +1,97 @@
"""
Conversion of IMS/LSM/CZI files to OME and then Generic TIFFs
"""
import os
import logging
import math
from argparse import ArgumentParser
from functools import partial
import multiprocessing as mp
import skimage.external.tifffile
import utility
import extract_zeiss_metadata
import bftools_wrapper
def extract_pixel_values_only(input_file, working_directory, channel=0, significant_bits=8):
im = skimage.external.tifffile.imread(input_file)
pixel_vals_only = im[0, :, 0, channel, :, :] # Strip excess data
out_path = working_directory + "/" + os.path.splitext(os.path.basename(input_file))[0] + "_pixels_only.tiff"
if significant_bits==8:
skimage.external.tifffile.imsave(out_path, skimage.img_as_ubyte(pixel_vals_only))
elif significant_bits==16:
skimage.external.tifffile.imsave(out_path, skimage.img_as_uint(pixel_vals_only))
else:
# Let skiimage decide
skimage.external.tifffile.imsave(out_path, pixel_vals_only)
def do_conversion(input_file, output_file, channel = 0, series = 0):
#
# # Get the image metadata
extract_zeiss_metadata.extract_metadata(input_file, os.getcwd() + "temp_metadata.xml")
image_metadata = extract_zeiss_metadata.get_metadata_as_class(os.getcwd() + "temp_metadata.xml")
#
# # Choose the tile size
tile_x = 1024
tile_y = 1024
# Black box JVM conversion via CLI. Be skeptical of outputs,
# at least the Z-physical size is silently lost!!!
bftools_wrapper.convert(input_file, output_file, tile_x, tile_y, channel, series)
# Make versions with just XYZ pixel values for easier use in scikit-image/VTK etc.
# DANGER, now all physical size is lost. Only trust physical sizes
# in the standalone xml metadata file, obtained (and validated) using `extract_zeiss_metadata()`.
# Collect the file names
file_names = []
for eachFile in os.listdir(output_file):
if eachFile.endswith(".tiff"):
file_names.append(output_file + "/" + eachFile)
# Make a partial function for multiple arg mapping
working_directory = output_file + "/Pixel_Values_Only/"
if not os.path.exists(working_directory):
os.makedirs(working_directory)
significant_bits = int(image_metadata.Image[0].Pixels.SignificantBits)
partial_extract_pixel_values_only = partial(extract_pixel_values_only,
working_directory=working_directory,
channel=channel,
significant_bits=significant_bits)
# Limit to max 6 cpus
num_available_cpus = mp.cpu_count()
if num_available_cpus > 6:
num_available_cpus = 6
# Distribute across processes - Be conservative with available CPUs
run_cpus = int(math.floor(num_available_cpus/2))
if run_cpus == 0:
run_cpus = 1
run_cpus = 1
#pool = mp.Pool(processes = run_cpus)
pool = mp.Pool(processes = 1)
pool.map(partial_extract_pixel_values_only, file_names)
if __name__ == "__main__":
# Do setup
tool_name = "zeiss_to_tiff"
utility.do_setup(tool_name)
logger1 = logging.getLogger('format_conversion.'+tool_name)
# Suppress XML Parse warnings
pyxb_logger = logging.getLogger('pyxb')
pyxb_logger.setLevel(logging.CRITICAL)
parser = ArgumentParser()
parser.add_argument("-i", "--input_file", type=str, help='Input file in a ZEISS format.')
parser.add_argument("-o", "--output_folder", type=str, help='Output Tiff Location.')
args = parser.parse_args()
logger1.info('Start Converting Image at: ' + args.input_file)
do_conversion(args.input_file, args.output_folder, channel = 1, series = 0)
logger1.info('Completed Processing')

0
image/__init__.py Normal file
View file

75
image/downsample_tiffs.py Normal file
View file

@ -0,0 +1,75 @@
"""
Downsample the tiffs for easier postprocessing
"""
import os
import logging
import math
from argparse import ArgumentParser
from functools import partial
import multiprocessing as mp
import skimage.external.tifffile
import skimage.transform
from skimage import exposure
import utility
def do_downsample(input_file, working_directory, downsample_ratios):
im = skimage.external.tifffile.imread(input_file)
downsampled = skimage.transform.downscale_local_mean(im, downsample_ratios)
out_path = working_directory + "/" + os.path.splitext(os.path.basename(input_file))[0] + "_downsampled.tiff"
scaled_image = exposure.rescale_intensity(downsampled, out_range=(0.0, 1.0))
skimage.external.tifffile.imsave(out_path, skimage.img_as_ubyte(scaled_image))
def downsample_tiffs(input_folder, downsample_ratios, channel = 0, series = 0):
file_names = []
dir_name = os.path.dirname(input_folder)
for eachFile in os.listdir(input_folder):
if eachFile.endswith(".tiff"):
file_names.append(dir_name + "/" + eachFile)
# Make a partial function for multiple arg mapping
working_directory = os.getcwd() + "/Downsampled_X"+str(downsample_ratios[2]) + "_Y"+str(downsample_ratios[1])
working_directory += "_Z"+str(downsample_ratios[0]) + "/"
if not os.path.exists(working_directory):
os.makedirs(working_directory)
partial_extract_pixel_values_only = partial(do_downsample,
working_directory=working_directory,
downsample_ratios=downsample_ratios)
# Limit to max 6 cpus
num_available_cpus = mp.cpu_count()
if num_available_cpus > 6:
num_available_cpus = 6
# Distribute across processes - Be conservative with available CPUs
run_cpus = int(math.floor(num_available_cpus/2))
if run_cpus == 0:
run_cpus = 1
#pool = mp.Pool(processes = run_cpus)
pool = mp.Pool(processes = 3)
pool.map(partial_extract_pixel_values_only, file_names)
if __name__ == "__main__":
# Do setup
tool_name = "zeiss_to_tiff"
utility.do_setup(tool_name)
logger1 = logging.getLogger('downsample_tiffs.'+tool_name)
# Suppress XML Parse warnings
pyxb_logger = logging.getLogger('pyxb')
pyxb_logger.setLevel(logging.CRITICAL)
parser = ArgumentParser()
parser.add_argument("-i", "--input_folder", type=str, help='Folder with tiffs to be downsampled.')
parser.add_argument("-x", "--x_reduction", type=int, help='Factor reduction in x.', default=1)
parser.add_argument("-y", "--y_reduction", type=int, help='Factor reduction in y.', default=1)
parser.add_argument("-z", "--z_reduction", type=int, help='Factor reduction in z.', default=1)
args = parser.parse_args()
logger1.info('Start Downsampling Images at: ' + args.input_folder)
downsample_ratios = (args.z_reduction, args.y_reduction, args.x_reduction)
downsample_tiffs(args.input_folder, downsample_ratios)
logger1.info('Completed Downsampling')

135
image/processing.py Normal file
View file

@ -0,0 +1,135 @@
import itk
def default_image_type():
return itk.Image[itk.UC, 3]
def image_type_2d():
return itk.Image[itk.UC, 2]
def read_image(path, image_type):
"""
Read the image from file
"""
reader = itk.ImageFileReader[image_type].New()
reader.SetFileName(path)
reader.Update()
return reader
def write_image(path, image_type, image_container):
"""
Write the image to file
"""
writer = itk.ImageFileWriter[image_type].New()
writer.SetInput(image_container.GetOutput())
writer.SetFileName(path)
writer.Update()
def convert_vtk(image_container, image_type):
itk_vtk_converter = itk.ImageToVTKImageFilter[image_type].New()
itk_vtk_converter.SetInput(image_container.GetOutput())
itk_vtk_converter.Update()
return itk_vtk_converter
def merge_tiles(image_containers, image_type, num_x):
tiler = itk.TileImageFilter[image_type,image_type].New()
layout = [num_x, num_x, 0]
tiler.SetLayout(layout)
for idx, eachContainer in enumerate(image_containers):
tiler.SetInput(idx, eachContainer.GetOutput())
tiler.Update()
return tiler
def median_filter(image_container, image_type, radius):
median_filter = itk.MedianImageFilter[image_type, image_type].New()
median_filter.SetInput(image_container.GetOutput())
median_filter.SetRadius(radius)
median_filter.Update()
return median_filter
def correct_spacing(image_container, image_type, z_spacing):
correct = itk.ChangeInformationImageFilter[image_type].New()
correct.SetInput(image_container.GetOutput())
spacing = image_container.GetOutput().GetSpacing()
spacing[2] = z_spacing
correct.SetOutputSpacing(spacing)
correct.ChangeSpacingOn()
correct.Update()
return correct
def sum_projection(image_container, image_type):
output_type = itk.Image[itk.UC, 2]
sum_projection = itk.SumProjectionImageFilter[image_type, output_type].New()
sum_projection.SetInput(image_container.GetOutput())
sum_projection.Update()
return sum_projection
def shrink_image(image_type, image_container, factors = [2,2,2]):
"""
Reduce the size of the image in each dimension by the specified factors
"""
shrink = itk.ShrinkImageFilter[image_type, image_type].New()
shrink.SetInput(image_container.GetOutput())
shrink.SetShrinkFactor(0, factors[0])
shrink.SetShrinkFactor(1, factors[1])
shrink.SetShrinkFactor(2, factors[2])
shrink.Update()
return shrink
def get_roi(image_type, image_container, start = [0,0,0], size = [200, 200, 10]):
"""
Select a region of interest in the image
"""
roi = itk.RegionOfInterestImageFilter[image_type, image_type].New()
roi.SetInput(image_container.GetOutput())
region = itk.ImageRegion[3]()
region.SetIndex(start)
region.SetSize(size)
roi.SetRegionOfInterest(region)
roi.Update()
return roi
def threshold_image(image_type, image_container, lower = 195, upper = 200):
"""
Do a binary thresholding
"""
threshold = itk.BinaryThresholdImageFilter[image_type,image_type].New()
threshold.SetInput(image_container.GetOutput())
threshold.SetLowerThreshold(lower)
threshold.SetUpperThreshold(upper)
threshold.Update()
return threshold
def get_intensity_histogram(image_type, image_container):
"""
Write an intensity histogram
"""
histogram = itk.ImageToHistogramFilter[image_type].New()
histogram.SetInput(image_container.GetOutput())
histogram.Update()
for idx in range(histogram.GetOutput().GetSize()[0]):
print "Hist Intensity: ", idx, " Frequency: ", histogram.GetOutput().GetFrequency(idx)

View file

View file

View file

@ -0,0 +1,30 @@
"""
Median filter on chosen image
"""
import logging
from code.image.tools import it_wrapper
import code.image.settings
if __name__ == "__main__":
# Do setup
tool_name = "median"
work_dir, image_data = code.image.settings.do_setup(tool_name)
logger1 = logging.getLogger('processing.'+tool_name)
output_path = work_dir+"/median"
logger1.info('Start Filtering Image at: ' + work_dir)
image_type = it_wrapper.default_image_type()
input_path = work_dir + "/convert/itk_tile_0_2_6.tiff"
logger1.info("Reading the image: " +input_path + " into ITK")
reader = it_wrapper.read_image(input_path, image_type)
correct = it_wrapper.correct_spacing(reader, image_type, image_data["VoxelSizeZ"])
logger1.info('Doing Median Filter')
median_filter = it_wrapper.median_filter(correct, image_type, 1)
logger1.info('Writing TIFF Stack')
it_wrapper.write_image(output_path+"/itk_tile_0_2_6.tiff", image_type, median_filter)

View file

@ -0,0 +1,36 @@
"""
SUM projection of tiled images
"""
import logging
from code.image.tools import it_wrapper
import code.image.settings
if __name__ == "__main__":
# Do setup
tool_name = "projection"
work_dir, image_data = code.image.settings.do_setup(tool_name)
logger1 = logging.getLogger('processing.'+tool_name)
output_path = work_dir+"/projection"
logger1.info('Start Projecting Image at: ' + work_dir)
image_type = it_wrapper.default_image_type()
num_tiles_y = 3
num_tiles_x = 3
for jdx in range(num_tiles_y):
for idx in range(num_tiles_x):
label = str(idx) + "_" + str(jdx) +"_"+ str(idx+ num_tiles_x*jdx)
input_path = work_dir + "/convert/itk_tile_" + label + ".tiff"
logger1.info("Reading the image: " +input_path + " into ITK")
reader = it_wrapper.read_image(input_path, image_type)
correct = it_wrapper.correct_spacing(reader, image_type, image_data["VoxelSizeZ"])
logger1.info('Doing SUM projection')
project = it_wrapper.sum_projection(correct, image_type)
output_image_type = it_wrapper.image_type_2d()
logger1.info('Writing TIFF Stack')
it_wrapper.write_image(output_path+"/sum_tile_" + label + ".tiff", output_image_type, project)

View file

@ -0,0 +1,30 @@
"""
Median filter on chosen image
"""
import logging
from code.image.tools import it_wrapper
import code.image.settings
if __name__ == "__main__":
# Do setup
tool_name = "reduce"
work_dir, image_data = code.image.settings.do_setup(tool_name)
logger1 = logging.getLogger('processing.'+tool_name)
output_path = work_dir+"/reduce"
logger1.info('Start Reducing Image at: ' + work_dir)
image_type = it_wrapper.default_image_type()
input_path = work_dir + "/median/itk_tile_0_2_6.tiff"
logger1.info("Reading the image: " +input_path + " into ITK")
reader = it_wrapper.read_image(input_path, image_type)
correct = it_wrapper.correct_spacing(reader, image_type, image_data["VoxelSizeZ"])
logger1.info('Doing Reduction')
im_reduce = it_wrapper.shrink_image(image_type, correct, [2,2,1])
logger1.info('Writing TIFF Stack')
it_wrapper.write_image(output_path+"/itk_tile_0_2_6.tiff", image_type, im_reduce)

17
image/processing/show.py Normal file
View file

@ -0,0 +1,17 @@
"""
Show a tiff using vtk
"""
import code.image.settings
from code.image.tools import simple_render
from code.image.tools import it_wrapper
work_dir, input_data = code.image.settings.do_setup("show")
input_path = work_dir + "/threshold/itk_tile_0_2_6.tiff"
image_type = it_wrapper.default_image_type()
reader = it_wrapper.read_image(input_path, image_type)
correct = it_wrapper.correct_spacing(reader, image_type, input_data["VoxelSizeZ"])
converter = it_wrapper.convert_vtk(reader, image_type)
simple_render.render_image(converter, threshold = 1.0)

View file

@ -0,0 +1,30 @@
"""
Threshold on chosen image
"""
import logging
from code.image.tools import it_wrapper
import code.image.settings
if __name__ == "__main__":
# Do setup
tool_name = "threshold"
work_dir, image_data = code.image.settings.do_setup(tool_name)
logger1 = logging.getLogger('processing.'+tool_name)
output_path = work_dir+"/threshold"
logger1.info('Start Thresholding Image at: ' + work_dir)
image_type = it_wrapper.default_image_type()
input_path = work_dir + "/reduce/itk_tile_0_2_6.tiff"
logger1.info("Reading the image: " +input_path + " into ITK")
reader = it_wrapper.read_image(input_path, image_type)
correct = it_wrapper.correct_spacing(reader, image_type, image_data["VoxelSizeZ"])
logger1.info('Doing Thresholding')
threshold = it_wrapper.threshold_image(image_type, correct, lower = 20, upper = 255)
logger1.info('Writing TIFF Stack')
it_wrapper.write_image(output_path+"/itk_tile_0_2_6.tiff", image_type, threshold)

39
image/processing/tile.py Normal file
View file

@ -0,0 +1,39 @@
"""
Merging of tiled images
"""
import logging
from code.image.tools import it_wrapper
import code.image.settings
if __name__ == "__main__":
# Do setup
tool_name = "tile"
work_dir, image_data = code.image.settings.do_setup(tool_name)
logger1 = logging.getLogger('processing.'+tool_name)
output_path = work_dir+"/projection"
logger1.info('Start Merging Images at: ' + work_dir)
image_type = it_wrapper.default_image_type()
num_tiles_y = 3
num_tiles_x = 3
container = []
for jdx in range(num_tiles_y):
for idx in range(num_tiles_x):
label = str(idx) + "_" + str(jdx) +"_"+ str(idx+ num_tiles_x*jdx)
input_path = work_dir + "/projection/sum_tile_" + label + ".tiff"
logger1.info("Reading the image: " +input_path + " into ITK")
reader = it_wrapper.read_image(input_path, image_type)
correct = it_wrapper.correct_spacing(reader, image_type, image_data["VoxelSizeZ"])
container.append(correct)
logger1.info('Merging Tiles')
merged = it_wrapper.merge_tiles(container, image_type, num_tiles_x)
output_image_type = it_wrapper.default_image_type()
logger1.info('Writing TIFF Stack')
it_wrapper.write_image(output_path+"/sum_merge.tiff", output_image_type, merged)

171
image/surface.py Normal file
View file

@ -0,0 +1,171 @@
import vtk
from vmtk import pypes
class Surface2d():
def __init__(self, input_path):
self.input_path = input_path
self.surface = None
self.boundaries = None
def generate(self, target_reduction = 0.9994, num_subdivisions = 3, resize_factors = None, clipping_factor = 0.0):
# Convert to VTI
myArguments = 'vmtkimagereader -ifile ' + self.input_path
my_pype = pypes.PypeRun(myArguments)
vtk_image = my_pype.GetScriptObject('vmtkimagereader','0').Image
# Size the image if needed
if resize_factors is not None:
reduction_filter = vtk.vtkImageResize()
reduction_filter.SetInput(vtk_image)
reduction_filter.SetMagnificationFactors(resize_factors[0], resize_factors[1], resize_factors[2])
reduction_filter.SetResizeMethodToMagnificationFactors()
reduction_filter.Update()
# Threshold
threshold = vtk.vtkThreshold()
if resize_factors is not None:
threshold.SetInputConnection(reduction_filter.GetOutputPort())
else:
threshold.SetInput(vtk_image)
threshold.ThresholdByUpper(1.0)
threshold.Update()
# Convert to polydata
surface = vtk.vtkGeometryFilter()
surface.SetInputConnection(threshold.GetOutputPort())
surface.Update()
# Triangulate
triangle = vtk.vtkTriangleFilter()
triangle.SetInputConnection(surface.GetOutputPort())
triangle.Update()
# Decimate
decimate = vtk.vtkDecimatePro()
decimate.SetInputConnection(triangle.GetOutputPort())
decimate.SetTargetReduction(target_reduction)
decimate.SetFeatureAngle(15.0)
decimate.Update()
# Do loop subdivision
su = vtk.vtkLinearSubdivisionFilter()
su.SetInputConnection(decimate.GetOutputPort())
su.SetNumberOfSubdivisions(num_subdivisions)
su.Update()
# Clip the boundaries, recommended to ensure straight inlets and outlets
if clipping_factor > 0.0:
bounds = su.GetOutput().GetBounds()
width = bounds[1] - bounds[0]
height = bounds[3] - bounds[2]
print bounds[2], bounds[3], height
p1 = vtk.vtkPlane()
p1.SetOrigin(bounds[0] + clipping_factor*width, 0.0, 0)
p1.SetNormal(1, 0, 0)
p2 = vtk.vtkPlane()
p2.SetOrigin(0.0, bounds[2] + clipping_factor*height, 0)
p2.SetNormal(0, 1, 0)
p3 = vtk.vtkPlane()
p3.SetOrigin(bounds[1] - clipping_factor*width, 0.0, 0)
p3.SetNormal(-1, 0, 0)
p4 = vtk.vtkPlane()
p4.SetOrigin(0.0, bounds[3] - clipping_factor*height, 0)
p4.SetNormal(0, -1, 0)
c1 = vtk.vtkClipPolyData()
c1.SetInputConnection(su.GetOutputPort())
c1.SetClipFunction(p1)
c1.SetValue(0.0)
c2 = vtk.vtkClipPolyData()
c2.SetInputConnection(c1.GetOutputPort())
c2.SetClipFunction(p2)
c2.SetValue(0.0)
#
c3 = vtk.vtkClipPolyData()
c3.SetInputConnection(c2.GetOutputPort())
c3.SetClipFunction(p3)
c3.SetValue(0.0)
c4 = vtk.vtkClipPolyData()
c4.SetInputConnection(c3.GetOutputPort())
c4.SetClipFunction(p4)
c4.SetValue(0.0)
su = vtk.vtkGeometryFilter()
su.SetInputConnection(c4.GetOutputPort())
su.Update()
feature_edges = vtk.vtkFeatureEdges()
feature_edges.SetInputConnection(su.GetOutputPort())
feature_edges.Update()
clean = vtk.vtkCleanPolyData()
clean.SetInputConnection(feature_edges.GetOutputPort())
clean.Update()
triangle2 = vtk.vtkTriangleFilter()
triangle2.SetInputConnection(clean.GetOutputPort())
triangle2.Update()
self.surface = su.GetOutput()
self.boundaries = triangle2.GetOutput()
return su.GetOutput(), triangle2.GetOutput()
def write(self, output_directory):
surface_writer = vtk.vtkXMLPolyDataWriter()
surface_writer.SetFileName(output_directory + "/surface.vtp")
surface_writer.SetInput(self.surface)
surface_writer.Write()
surface_writer.SetFileName(output_directory + "/boundaries.vtp")
surface_writer.SetInput(self.boundaries)
surface_writer.Write()
class Surface3d():
def __init__(self):
pass
def generate(self, input_path, output_directory, part_name):
input_path = work_dir + "/vtk_image/itk_tile_0_2_6.vti"
reader = vtk.vtkXMLImageDataReader()
reader.SetFileName(input_path)
reader.Update()
pad_filter = vtk.vtkImageConstantPad()
pad_filter.SetInputConnection(reader.GetOutputPort())
pad_filter.SetConstant(0)
pad_filter.SetOutputWholeExtent(reader.GetOutput().GetExtent()[0]-5,
reader.GetOutput().GetExtent()[1]+5,
reader.GetOutput().GetExtent()[2]-5,
reader.GetOutput().GetExtent()[3]+5,
reader.GetOutput().GetExtent()[4]-5,
reader.GetOutput().GetExtent()[5]+5)
pad_filter.Update()
writer = vtk.vtkXMLImageDataWriter()
writer.SetFileName(work_dir + "/surface/itk_tile_0_2_6_pad.vti")
writer.SetInputConnection(pad_filter.GetOutputPort())
writer.Update()
myArguments = 'vmtklevelsetsegmentation -ifile ' + work_dir + "/surface/itk_tile_0_2_6_pad.vti" + ' -ofile ' + output_path+"/itk_tile_0_2_6_ls.vti"
myPype = pypes.PypeRun(myArguments)
myArguments = 'vmtkmarchingcubes -ifile ' + output_path+"/itk_tile_0_2_6_ls.vti" + ' -ofile ' + output_path+"/itk_tile_0_2_6_model.vtp"
myPype = pypes.PypeRun(myArguments)

44
process_russ_format.py Normal file
View file

@ -0,0 +1,44 @@
"""
Reader for the MATLAB vessel network format provided by Russel Bates (russell.bates@new.ox.ac.uk)
"""
from argparse import ArgumentParser
import scipy.io
import numpy as np
def compare(x, y):
return (x[0] == y[0]) and (x[1] == y[1]) and (x[2] == y[2])
def convert_to_vtk(mat):
"""
Convert the format to VTK
"""
nodes = []
edges = []
for idx, eachConnectedComponent in enumerate(mat["Vessels"][0]):
adjacency = eachConnectedComponent['Adj']
branches = eachConnectedComponent['Branch'][0][0][0]
if idx ==0:
for kdx, eachBranch in enumerate(branches):
if kdx <200:
for jdx, eachPoint in enumerate(eachBranch['Points'][0][0]):
nodes.append(np.array(eachPoint))
for idx, eachEntry in enumerate(nodes):
for jdx, eachOtherEntry in enumerate(nodes):
if idx!=jdx:
if compare(eachEntry, eachOtherEntry):
print eachEntry, eachOtherEntry, idx, jdx
break
#nodes.append(eachBranch['Points'][0][0][0])
#print eachBranch['Points'][0][0][0]
#adjacency_indices = adjacency[0][0].nonzero()
#print adjacency_indices[0]
mat = scipy.io.loadmat('/home/grogan/Vessels.mat', struct_as_record=True)
convert_to_vtk(mat)

36
utility.py Normal file
View file

@ -0,0 +1,36 @@
"""
Utilities for logging, parallel execution
"""
import os
import logging
def do_setup(tool_name = None):
out_directory = os.getcwd() + "/Stack3D_Logging/"
if not os.path.exists(out_directory):
os.makedirs(out_directory)
if tool_name is not None:
filename = out_directory + tool_name + ".log"
else:
filename = out_directory + "/root.log"
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename=filename,
filemode='w')
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)

0
viewing/__init__.py Normal file
View file

534
viewing/mp_color_map.py Normal file
View file

@ -0,0 +1,534 @@
import vtk
def get_disc_ctf():
ctf = vtk.vtkColorTransferFunction()
disc_colors = [[0.498039215803,0.78823530674,0.498039215803],
[0.504821223137,0.785328732519,0.507189542873],
[0.511603230472,0.782422158297,0.516339869943],
[0.518385237806,0.779515584076,0.525490197013],
[0.52516724514,0.776609009855,0.534640524083],
[0.531949252475,0.773702435634,0.543790851154],
[0.538731259809,0.770795861412,0.552941178224],
[0.545513267143,0.767889287191,0.562091505294],
[0.552295274477,0.76498271297,0.571241832364],
[0.559077281812,0.762076138749,0.580392159434],
[0.565859289146,0.759169564528,0.589542486504],
[0.57264129648,0.756262990306,0.598692813574],
[0.579423303814,0.753356416085,0.607843140644],
[0.586205311149,0.750449841864,0.616993467714],
[0.592987318483,0.747543267643,0.626143794784],
[0.599769325817,0.744636693422,0.635294121854],
[0.606551333152,0.7417301192,0.644444448925],
[0.613333340486,0.738823544979,0.653594775995],
[0.62011534782,0.735916970758,0.662745103065],
[0.626897355154,0.733010396537,0.671895430135],
[0.633679362489,0.730103822315,0.681045757205],
[0.640461369823,0.727197248094,0.690196084275],
[0.647243377157,0.724290673873,0.699346411345],
[0.654025384492,0.721384099652,0.708496738415],
[0.660807391826,0.718477525431,0.717647065485],
[0.66758939916,0.715570951209,0.726797392555],
[0.674371406494,0.712664376988,0.735947719625],
[0.681153413829,0.709757802767,0.745098046695],
[0.687935421163,0.706851228546,0.754248373766],
[0.694717428497,0.703944654324,0.763398700836],
[0.701499435832,0.701038080103,0.772549027906],
[0.708281443166,0.698131505882,0.781699354976],
[0.7150634505,0.695224931661,0.790849682046],
[0.721845457834,0.69231835744,0.800000009116],
[0.728627465169,0.689411783218,0.809150336186],
[0.735409472503,0.686505208997,0.818300663256],
[0.742191479837,0.683598634776,0.827450990326],
[0.748973486704,0.68346022648,0.826574404801],
[0.75575549322,0.685397942627,0.818177634828],
[0.762537499736,0.687335658775,0.809780864856],
[0.769319506253,0.689273374922,0.801384094883],
[0.776101512769,0.69121109107,0.792987324911],
[0.782883519285,0.693148807217,0.784590554939],
[0.789665525801,0.695086523365,0.776193784966],
[0.796447532317,0.697024239512,0.767797014994],
[0.803229538833,0.69896195566,0.759400245021],
[0.81001154535,0.700899671807,0.751003475049],
[0.816793551866,0.702837387954,0.742606705077],
[0.823575558382,0.704775104102,0.734209935104],
[0.830357564898,0.706712820249,0.725813165132],
[0.837139571414,0.708650536397,0.717416395159],
[0.84392157793,0.710588252544,0.709019625187],
[0.850703584447,0.712525968692,0.700622855215],
[0.857485590963,0.714463684839,0.692226085242],
[0.864267597479,0.716401400987,0.68382931527],
[0.871049603995,0.718339117134,0.675432545297],
[0.877831610511,0.720276833282,0.667035775325],
[0.884613617028,0.722214549429,0.658639005352],
[0.891395623544,0.724152265577,0.65024223538],
[0.89817763006,0.726089981724,0.641845465408],
[0.904959636576,0.728027697872,0.633448695435],
[0.911741643092,0.729965414019,0.625051925463],
[0.918523649608,0.731903130167,0.61665515549],
[0.925305656125,0.733840846314,0.608258385518],
[0.932087662641,0.735778562462,0.599861615546],
[0.938869669157,0.737716278609,0.591464845573],
[0.945651675673,0.739653994757,0.583068075601],
[0.952433682189,0.741591710904,0.574671305628],
[0.959215688705,0.743529427052,0.566274535656],
[0.965997695222,0.745467143199,0.557877765684],
[0.972779701738,0.747404859347,0.549480995711],
[0.979561708254,0.749342575494,0.541084225739],
[0.98634371477,0.751280291641,0.532687455766],
[0.992187620612,0.75391004927,0.525782419653],
[0.992402922406,0.760692055786,0.527827786698],
[0.9926182242,0.767474062303,0.529873153743],
[0.992833525994,0.774256068819,0.531918520787],
[0.993048827788,0.781038075335,0.533963887832],
[0.993264129583,0.787820081851,0.536009254876],
[0.993479431377,0.794602088367,0.538054621921],
[0.993694733171,0.801384094883,0.540099988965],
[0.993910034965,0.8081661014,0.54214535601],
[0.994125336759,0.814948107916,0.544190723055],
[0.994340638553,0.821730114432,0.546236090099],
[0.994555940348,0.828512120948,0.548281457144],
[0.994771242142,0.835294127464,0.550326824188],
[0.994986543936,0.84207613398,0.552372191233],
[0.99520184573,0.848858140497,0.554417558277],
[0.995417147524,0.855640147013,0.556462925322],
[0.995632449318,0.862422153529,0.558508292366],
[0.995847751113,0.869204160045,0.560553659411],
[0.996063052907,0.875986166561,0.562599026456],
[0.996278354701,0.882768173078,0.5646443935],
[0.996493656495,0.889550179594,0.566689760545],
[0.996708958289,0.89633218611,0.568735127589],
[0.996924260083,0.903114192626,0.570780494634],
[0.997139561878,0.909896199142,0.572825861678],
[0.997354863672,0.916678205658,0.574871228723],
[0.997570165466,0.923460212175,0.576916595768],
[0.99778546726,0.930242218691,0.578961962812],
[0.998000769054,0.937024225207,0.581007329857],
[0.998216070848,0.943806231723,0.583052696901],
[0.998431372643,0.950588238239,0.585098063946],
[0.998646674437,0.957370244755,0.58714343099],
[0.998861976231,0.964152251272,0.589188798035],
[0.999077278025,0.970934257788,0.591234165079],
[0.999292579819,0.977716264304,0.593279532124],
[0.999507881613,0.98449827082,0.595324899169],
[0.999723183408,0.991280277336,0.597370266213],
[0.999938485202,0.998062283853,0.599415633258],
[0.984698193038,0.988696655222,0.601768574294],
[0.963275663292,0.972871972533,0.604244544927],
[0.941853133545,0.957047289844,0.60672051556],
[0.920430603799,0.941222607154,0.609196486193],
[0.899008074052,0.925397924465,0.611672456825],
[0.877585544306,0.909573241776,0.614148427458],
[0.856163014559,0.893748559087,0.616624398091],
[0.834740484813,0.877923876398,0.619100368724],
[0.813317955066,0.862099193709,0.621576339357],
[0.79189542532,0.846274511019,0.62405230999],
[0.770472895573,0.83044982833,0.626528280623],
[0.749050365827,0.814625145641,0.629004251256],
[0.72762783608,0.798800462952,0.631480221889],
[0.706205306334,0.782975780263,0.633956192521],
[0.684782776587,0.767151097573,0.636432163154],
[0.663360246841,0.751326414884,0.638908133787],
[0.641937717094,0.735501732195,0.64138410442],
[0.620515187348,0.719677049506,0.643860075053],
[0.599092657601,0.703852366817,0.646336045686],
[0.577670127855,0.688027684128,0.648812016319],
[0.556247598108,0.672203001438,0.651287986952],
[0.534825068362,0.656378318749,0.653763957585],
[0.513402538615,0.64055363606,0.656239928217],
[0.491980008869,0.624728953371,0.65871589885],
[0.470557479122,0.608904270682,0.661191869483],
[0.449134949376,0.593079587992,0.663667840116],
[0.427712419629,0.577254905303,0.666143810749],
[0.406289889883,0.561430222614,0.668619781382],
[0.384867360136,0.545605539925,0.671095752015],
[0.36344483039,0.529780857236,0.673571722648],
[0.342022300643,0.513956174547,0.676047693281],
[0.320599770897,0.498131491857,0.678523663914],
[0.29917724115,0.482306809168,0.680999634546],
[0.277754711404,0.466482126479,0.683475605179],
[0.256332181657,0.45065744379,0.685951575812],
[0.234909651911,0.434832761101,0.688427546445],
[0.225267206746,0.420269131785,0.688688984104],
[0.245074973036,0.408858135901,0.683414089329],
[0.264882739327,0.397447140018,0.678139194554],
[0.284690505617,0.386036144135,0.672864299779],
[0.304498271907,0.374625148252,0.667589405004],
[0.324306038197,0.363214152368,0.662314510229],
[0.344113804488,0.351803156485,0.657039615453],
[0.363921570778,0.340392160602,0.651764720678],
[0.383729337068,0.328981164719,0.646489825903],
[0.403537103358,0.317570168835,0.641214931128],
[0.423344869649,0.306159172952,0.635940036353],
[0.443152635939,0.294748177069,0.630665141578],
[0.462960402229,0.283337181186,0.625390246803],
[0.48276816852,0.271926185302,0.620115352028],
[0.50257593481,0.260515189419,0.614840457252],
[0.5223837011,0.249104193536,0.609565562477],
[0.54219146739,0.237693197653,0.604290667702],
[0.561999233681,0.226282201769,0.599015772927],
[0.581806999971,0.214871205886,0.593740878152],
[0.601614766261,0.203460210003,0.588465983377],
[0.621422532551,0.19204921412,0.583191088602],
[0.641230298842,0.180638218236,0.577916193827],
[0.661038065132,0.169227222353,0.572641299051],
[0.680845831422,0.15781622647,0.567366404276],
[0.700653597713,0.146405230587,0.562091509501],
[0.720461364003,0.134994234703,0.556816614726],
[0.740269130293,0.12358323882,0.551541719951],
[0.760076896583,0.112172242937,0.546266825176],
[0.779884662874,0.100761247054,0.540991930401],
[0.799692429164,0.0893502511705,0.535717035625],
[0.819500195454,0.0779392552872,0.53044214085],
[0.839307961744,0.066528259404,0.525167246075],
[0.859115728035,0.0551172635208,0.5198923513],
[0.878923494325,0.0437062676375,0.514617456525],
[0.898731260615,0.0322952717543,0.50934256175],
[0.918539026906,0.020884275871,0.504067666975],
[0.938346793196,0.00947327998777,0.4987927722],
[0.936655136417,0.0160553639755,0.488442906737],
[0.93138024246,0.0256362946083,0.477247212827],
[0.926105348503,0.0352172252412,0.466051518917],
[0.920830454546,0.044798155874,0.454855825007],
[0.915555560589,0.0543790865069,0.443660131097],
[0.910280666632,0.0639600171397,0.432464437187],
[0.905005772675,0.0735409477726,0.421268743277],
[0.899730878718,0.0831218784054,0.410073049366],
[0.894455984761,0.0927028090383,0.398877355456],
[0.889181090804,0.102283739671,0.387681661546],
[0.883906196847,0.111864670304,0.376485967636],
[0.87863130289,0.121445600937,0.365290273726],
[0.873356408933,0.13102653157,0.354094579816],
[0.868081514976,0.140607462203,0.342898885906],
[0.862806621019,0.150188392835,0.331703191996],
[0.857531727062,0.159769323468,0.320507498085],
[0.852256833105,0.169350254101,0.309311804175],
[0.846981939148,0.178931184734,0.298116110265],
[0.84170704519,0.188512115367,0.286920416355],
[0.836432151233,0.198093046,0.275724722445],
[0.831157257276,0.207673976632,0.264529028535],
[0.825882363319,0.217254907265,0.253333334625],
[0.820607469362,0.226835837898,0.242137640715],
[0.815332575405,0.236416768531,0.230941946805],
[0.810057681448,0.245997699164,0.219746252894],
[0.804782787491,0.255578629797,0.208550558984],
[0.799507893534,0.26515956043,0.197354865074],
[0.794232999577,0.274740491062,0.186159171164],
[0.78895810562,0.284321421695,0.174963477254],
[0.783683211663,0.293902352328,0.163767783344],
[0.778408317706,0.303483282961,0.152572089434],
[0.773133423749,0.313064213594,0.141376395524],
[0.767858529792,0.322645144227,0.130180701613],
[0.762583635835,0.33222607486,0.118985007703],
[0.757308741878,0.341807005492,0.107789313793],
[0.752033847921,0.351387936125,0.0965936198831],
[0.744913509663,0.357370250716,0.09384083257],
[0.735332579005,0.358554410584,0.102345254053],
[0.725751648347,0.359738570452,0.110849675536],
[0.716170717688,0.36092273032,0.119354097019],
[0.70658978703,0.362106890188,0.127858518502],
[0.697008856371,0.363291050055,0.136362939985],
[0.687427925713,0.364475209923,0.144867361468],
[0.677846995055,0.365659369791,0.153371782951],
[0.668266064396,0.366843529659,0.161876204435],
[0.658685133738,0.368027689527,0.170380625918],
[0.649104203079,0.369211849395,0.178885047401],
[0.639523272421,0.370396009263,0.187389468884],
[0.629942341762,0.371580169131,0.195893890367],
[0.620361411104,0.372764328999,0.20439831185],
[0.610780480446,0.373948488867,0.212902733333],
[0.601199549787,0.375132648734,0.221407154816],
[0.591618619129,0.376316808602,0.229911576299],
[0.58203768847,0.37750096847,0.238415997782],
[0.572456757812,0.378685128338,0.246920419265],
[0.562875827154,0.379869288206,0.255424840748],
[0.553294896495,0.381053448074,0.263929262231],
[0.543713965837,0.382237607942,0.272433683714],
[0.534133035178,0.38342176781,0.280938105198],
[0.52455210452,0.384605927678,0.289442526681],
[0.514971173861,0.385790087546,0.297946948164],
[0.505390243203,0.386974247414,0.306451369647],
[0.495809312545,0.388158407281,0.31495579113],
[0.486228381886,0.389342567149,0.323460212613],
[0.476647451228,0.390526727017,0.331964634096],
[0.467066520569,0.391710886885,0.340469055579],
[0.457485589911,0.392895046753,0.348973477062],
[0.447904659253,0.394079206621,0.357477898545],
[0.438323728594,0.395263366489,0.365982320028],
[0.428742797936,0.396447526357,0.374486741511],
[0.419161867277,0.397631686225,0.382991162994],
[0.409580936619,0.398815846093,0.391495584477],
];
for idx, eachColor in enumerate(disc_colors):
ctf.AddRGBPoint(float(idx)/255.0,disc_colors[idx][0], disc_colors[idx][1],disc_colors[idx][2])
return ctf
def get_ctf():
ctf = vtk.vtkColorTransferFunction()
viridis_colors = [ [0.0267004, 0.004874, 0.329415],
[0.0268510, 0.009605, 0.335427],
[0.0269944, 0.014625, 0.341379],
[0.0271305, 0.019942, 0.347269],
[0.0272594, 0.025563, 0.353093],
[0.0273809, 0.031497, 0.358853],
[0.0274952, 0.037752, 0.364543],
[0.0276022, 0.044167, 0.370164],
[0.0277018, 0.050344, 0.375715],
[0.0277941, 0.056324, 0.381191],
[0.0278791, 0.062145, 0.386592],
[0.0279566, 0.067836, 0.391917],
[0.0280267, 0.073417, 0.397163],
[0.0280894, 0.078907, 0.402329],
[0.0281446, 0.084320, 0.407414],
[0.0281924, 0.089666, 0.412415],
[0.0282327, 0.094955, 0.417331],
[0.0282656, 0.100196, 0.422160],
[0.0282910, 0.105393, 0.426902],
[0.0283091, 0.110553, 0.431554],
[0.0283197, 0.115680, 0.436115],
[0.0283229, 0.120777, 0.440584],
[0.0283187, 0.125848, 0.444960],
[0.0283072, 0.130895, 0.449241],
[0.0282884, 0.135920, 0.453427],
[0.0282623, 0.140926, 0.457517],
[0.0282290, 0.145912, 0.461510],
[0.0281887, 0.150881, 0.465405],
[0.0281412, 0.155834, 0.469201],
[0.0280868, 0.160771, 0.472899],
[0.0280255, 0.165693, 0.476498],
[0.0279574, 0.170599, 0.479997],
[0.0278826, 0.175490, 0.483397],
[0.0278012, 0.180367, 0.486697],
[0.0277134, 0.185228, 0.489898],
[0.0276194, 0.190074, 0.493001],
[0.0275191, 0.194905, 0.496005],
[0.0274128, 0.199721, 0.498911],
[0.0273006, 0.204520, 0.501721],
[0.0271828, 0.209303, 0.504434],
[0.0270595, 0.214069, 0.507052],
[0.0269308, 0.218818, 0.509577],
[0.0267968, 0.223549, 0.512008],
[0.0266580, 0.228262, 0.514349],
[0.0265145, 0.232956, 0.516599],
[0.0263663, 0.237631, 0.518762],
[0.0262138, 0.242286, 0.520837],
[0.0260571, 0.246922, 0.522828],
[0.0258965, 0.251537, 0.524736],
[0.0257322, 0.256130, 0.526563],
[0.0255645, 0.260703, 0.528312],
[0.0253935, 0.265254, 0.529983],
[0.0252194, 0.269783, 0.531579],
[0.0250425, 0.274290, 0.533103],
[0.0248629, 0.278775, 0.534556],
[0.0246811, 0.283237, 0.535941],
[0.0244972, 0.287675, 0.537260],
[0.0243113, 0.292092, 0.538516],
[0.0241237, 0.296485, 0.539709],
[0.0239346, 0.300855, 0.540844],
[0.0237441, 0.305202, 0.541921],
[0.0235526, 0.309527, 0.542944],
[0.0233603, 0.313828, 0.543914],
[0.0231674, 0.318106, 0.544834],
[0.0229739, 0.322361, 0.545706],
[0.0227802, 0.326594, 0.546532],
[0.0225863, 0.330805, 0.547314],
[0.0223925, 0.334994, 0.548053],
[0.0221989, 0.339161, 0.548752],
[0.0220057, 0.343307, 0.549413],
[0.0218130, 0.347432, 0.550038],
[0.0216210, 0.351535, 0.550627],
[0.0214298, 0.355619, 0.551184],
[0.0212395, 0.359683, 0.551710],
[0.0210503, 0.363727, 0.552206],
[0.0208623, 0.367752, 0.552675],
[0.0206756, 0.371758, 0.553117],
[0.0204903, 0.375746, 0.553533],
[0.0203063, 0.379716, 0.553925],
[0.0201239, 0.383670, 0.554294],
[0.0199430, 0.387607, 0.554642],
[0.0197636, 0.391528, 0.554969],
[0.0195860, 0.395433, 0.555276],
[0.0194100, 0.399323, 0.555565],
[0.0192357, 0.403199, 0.555836],
[0.0190631, 0.407061, 0.556089],
[0.0188923, 0.410910, 0.556326],
[0.0187231, 0.414746, 0.556547],
[0.0185556, 0.418570, 0.556753],
[0.0183898, 0.422383, 0.556944],
[0.0182256, 0.426184, 0.557120],
[0.0180629, 0.429975, 0.557282],
[0.0179019, 0.433756, 0.557430],
[0.0177423, 0.437527, 0.557565],
[0.0175841, 0.441290, 0.557685],
[0.0174274, 0.445044, 0.557792],
[0.0172719, 0.448791, 0.557885],
[0.0171176, 0.452530, 0.557965],
[0.0169646, 0.456262, 0.558030],
[0.0168126, 0.459988, 0.558082],
[0.0166617, 0.463708, 0.558119],
[0.0165117, 0.467423, 0.558141],
[0.0163625, 0.471133, 0.558148],
[0.0162142, 0.474838, 0.558140],
[0.0160665, 0.478540, 0.558115],
[0.0159194, 0.482237, 0.558073],
[0.0157729, 0.485932, 0.558013],
[0.0156270, 0.489624, 0.557936],
[0.0154815, 0.493313, 0.557840],
[0.0153364, 0.497000, 0.557724],
[0.0151918, 0.500685, 0.557587],
[0.0150476, 0.504369, 0.557430],
[0.0149039, 0.508051, 0.557250],
[0.0147607, 0.511733, 0.557049],
[0.0146180, 0.515413, 0.556823],
[0.0144759, 0.519093, 0.556572],
[0.0143343, 0.522773, 0.556295],
[0.0141935, 0.526453, 0.555991],
[0.0140536, 0.530132, 0.555659],
[0.0139147, 0.533812, 0.555298],
[0.0137770, 0.537492, 0.554906],
[0.0136408, 0.541173, 0.554483],
[0.0135066, 0.544853, 0.554029],
[0.0133743, 0.548535, 0.553541],
[0.0132444, 0.552216, 0.553018],
[0.0131172, 0.555899, 0.552459],
[0.0129933, 0.559582, 0.551864],
[0.0128729, 0.563265, 0.551229],
[0.0127568, 0.566949, 0.550556],
[0.0126453, 0.570633, 0.549841],
[0.0125394, 0.574318, 0.549086],
[0.0124395, 0.578002, 0.548287],
[0.0123463, 0.581687, 0.547445],
[0.0122606, 0.585371, 0.546557],
[0.0121831, 0.589055, 0.545623],
[0.0121148, 0.592739, 0.544641],
[0.0120565, 0.596422, 0.543611],
[0.0120092, 0.600104, 0.542530],
[0.0119738, 0.603785, 0.541400],
[0.0119512, 0.607464, 0.540218],
[0.0119423, 0.611141, 0.538982],
[0.0119483, 0.614817, 0.537692],
[0.0119699, 0.618490, 0.536347],
[0.0120081, 0.622161, 0.534946],
[0.0120638, 0.625828, 0.533488],
[0.0121380, 0.629492, 0.531973],
[0.0122312, 0.633153, 0.530398],
[0.0123444, 0.636809, 0.528763],
[0.0124780, 0.640461, 0.527068],
[0.0126326, 0.644107, 0.525311],
[0.0128087, 0.647749, 0.523491],
[0.0130067, 0.651384, 0.521608],
[0.0132268, 0.655014, 0.519661],
[0.0134692, 0.658636, 0.517649],
[0.0137339, 0.662252, 0.515571],
[0.0140210, 0.665859, 0.513427],
[0.0143303, 0.669459, 0.511215],
[0.0146616, 0.673050, 0.508936],
[0.0150148, 0.676631, 0.506589],
[0.0153894, 0.680203, 0.504172],
[0.0157851, 0.683765, 0.501686],
[0.0162016, 0.687316, 0.499129],
[0.0166383, 0.690856, 0.496502],
[0.0170948, 0.694384, 0.493803],
[0.0175707, 0.697900, 0.491033],
[0.0180653, 0.701402, 0.488189],
[0.0185783, 0.704891, 0.485273],
[0.0191090, 0.708366, 0.482284],
[0.0196571, 0.711827, 0.479221],
[0.0202219, 0.715272, 0.476084],
[0.0208030, 0.718701, 0.472873],
[0.0214000, 0.722114, 0.469588],
[0.0220124, 0.725509, 0.466226],
[0.0226397, 0.728888, 0.462789],
[0.0232815, 0.732247, 0.459277],
[0.0239374, 0.735588, 0.455688],
[0.0246070, 0.738910, 0.452024],
[0.0252899, 0.742211, 0.448284],
[0.0259857, 0.745492, 0.444467],
[0.0266941, 0.748751, 0.440573],
[0.0274149, 0.751988, 0.436601],
[0.0281477, 0.755203, 0.432552],
[0.0288921, 0.758394, 0.428426],
[0.0296479, 0.761561, 0.424223],
[0.0304148, 0.764704, 0.419943],
[0.0311925, 0.767822, 0.415586],
[0.0319809, 0.770914, 0.411152],
[0.0327796, 0.773980, 0.406640],
[0.0335885, 0.777018, 0.402049],
[0.0344074, 0.780029, 0.397381],
[0.0352360, 0.783011, 0.392636],
[0.0360741, 0.785964, 0.387814],
[0.0369214, 0.788888, 0.382914],
[0.0377779, 0.791781, 0.377939],
[0.0386433, 0.794644, 0.372886],
[0.0395174, 0.797475, 0.367757],
[0.0404001, 0.800275, 0.362552],
[0.0412913, 0.803041, 0.357269],
[0.0421908, 0.805774, 0.351910],
[0.0430983, 0.808473, 0.346476],
[0.0440137, 0.811138, 0.340967],
[0.0449368, 0.813768, 0.335384],
[0.0458674, 0.816363, 0.329727],
[0.0468053, 0.818921, 0.323998],
[0.0477504, 0.821444, 0.318195],
[0.0487026, 0.823929, 0.312321],
[0.0496615, 0.826376, 0.306377],
[0.0506271, 0.828786, 0.300362],
[0.0515992, 0.831158, 0.294279],
[0.0525776, 0.833491, 0.288127],
[0.0535621, 0.835785, 0.281908],
[0.0545524, 0.838039, 0.275626],
[0.0555484, 0.840254, 0.269281],
[0.0565498, 0.842430, 0.262877],
[0.0575563, 0.844566, 0.256415],
[0.0585678, 0.846661, 0.249897],
[0.0595839, 0.848717, 0.243329],
[0.0606045, 0.850733, 0.236712],
[0.0616293, 0.852709, 0.230052],
[0.0626579, 0.854645, 0.223353],
[0.0636902, 0.856542, 0.216620],
[0.0647257, 0.858400, 0.209861],
[0.0657642, 0.860219, 0.203082],
[0.0668054, 0.861999, 0.196293],
[0.0678489, 0.863742, 0.189503],
[0.0688944, 0.865448, 0.182725],
[0.0699415, 0.867117, 0.175971],
[0.0709898, 0.868751, 0.169257],
[0.0720391, 0.870350, 0.162603],
[0.0730889, 0.871916, 0.156029],
[0.0741388, 0.873449, 0.149561],
[0.0751884, 0.874951, 0.143228],
[0.0762373, 0.876424, 0.137064],
[0.0772852, 0.877868, 0.131109],
[0.0783315, 0.879285, 0.125405],
[0.0793760, 0.880678, 0.120005],
[0.0804182, 0.882046, 0.114965],
[0.0814576, 0.883393, 0.110347],
[0.0824940, 0.884720, 0.106217],
[0.0835270, 0.886029, 0.102646],
[0.0845561, 0.887322, 0.099702],
[0.0855810, 0.888601, 0.097452],
[0.0866013, 0.889868, 0.095953],
[0.0876168, 0.891125, 0.095250],
[0.0886271, 0.892374, 0.095374],
[0.0896320, 0.893616, 0.096335],
[0.0906311, 0.894855, 0.098125],
[0.0916242, 0.896091, 0.100717],
[0.0926106, 0.897330, 0.104071],
[0.0935904, 0.898570, 0.108131],
[0.0945636, 0.899815, 0.112838],
[0.0955300, 0.901065, 0.118128],
[0.0964894, 0.902323, 0.123941],
[0.0974417, 0.903590, 0.130215],
[0.0983868, 0.904867, 0.136897],
[0.0993248, 0.906157, 0.143936]]
for idx, eachColor in enumerate(viridis_colors):
ctf.AddRGBPoint(float(idx)/255.0,viridis_colors[idx][0], viridis_colors[idx][1],viridis_colors[idx][2])
return ctf

309
viewing/simple_render.py Normal file
View file

@ -0,0 +1,309 @@
"""
Rendering of 3D TIFF stacks with VTK
"""
import os
from argparse import ArgumentParser
import vtk
import mp_color_map
def get_ox_map():
files = ["/home/grogan/oxygen_solution_loc_0.vti",
"/home/grogan/oxygen_solution_loc_1.vti",
"/home/grogan/oxygen_solution_loc_2.vti",
"/home/grogan/oxygen_solution_loc_3.vti"]
offsets = [(0.0,0.0), (40.0, 0.0), (40.0, 40.0), (0.0, 40.0)]
ox_actors = []
for idx, eachFile in enumerate(files):
reader = vtk.vtkXMLImageDataReader()
reader.SetFileName(eachFile)
reader.Update()
reader.GetOutput().GetPointData().SetScalars(reader.GetOutput().GetPointData().GetArray("oxygen"))
plane = vtk.vtkPlane()
plane.SetOrigin(0.0, 0, 3)
plane.SetNormal(0, 0, 1)
cutter = vtk.vtkCutter()
cutter.SetInputData(reader.GetOutput())
cutter.SetCutFunction(plane)
cutter.GenerateCutScalarsOn()
cutter.Update()
trans = vtk.vtkTransform()
trans.Scale(42.375, 42.375, 42.375)
transf = vtk.vtkTransformFilter()
transf.SetInputData(cutter.GetOutput())
transf.SetTransform(trans)
transf.Update()
trans1 = vtk.vtkTransform()
trans1.Translate(42.375*offsets[idx][0], 42.375*offsets[idx][1], 0.0)
transf2 = vtk.vtkTransformFilter()
transf2.SetInputData(transf.GetOutput())
transf2.SetTransform(trans1)
transf2.Update()
warp = vtk.vtkWarpScalar()
warp.SetInputData(transf2.GetOutput())
warp.SetScaleFactor(0.15*42.375)
warp.Update()
scaled_ctf = vtk.vtkColorTransferFunction()
scalar_range = [0, 0]
warp.GetOutput().GetPointData().GetArray("oxygen").GetRange(scalar_range)
for idx in range(256):
color = [0, 0, 0]
mp_color_map.get_ctf().GetColor(float(idx)/255.0, color)
scaled_ctf.AddRGBPoint(scalar_range[0] + float(idx)*(scalar_range[1]-scalar_range[0])/255.0,
color[0], color[1], color[2])
ox_mapper = vtk.vtkPolyDataMapper()
ox_mapper.SetInputData(warp.GetOutput())
ox_mapper.ScalarVisibilityOn()
ox_mapper.SetLookupTable(scaled_ctf)
ox_mapper.SelectColorArray("oxygen")
ox_mapper.SetScalarModeToUsePointFieldData()
ox_mapper.SetColorModeToMapScalars()
#ox_mapper.ScalarVisibilityOn()
ox_actor = vtk.vtkActor()
ox_actor.SetMapper(ox_mapper)
ox_actor.GetProperty().SetColor(0.0, 1.0, 0.0)
ox_actor.GetProperty().SetOpacity(0.5)
ox_actors.append(ox_actor)
scale_bar = vtk.vtkScalarBarActor()
scale_bar.SetLookupTable(scaled_ctf);
#scale_bar.SetTitle("Oxygen Tension (mmHg)");
scale_bar.SetOrientationToVertical();
scale_bar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport();
scale_bar.GetPositionCoordinate().SetValue(0.23, 0.27);
scale_bar.SetWidth(0.08);
scale_bar.SetHeight(0.6);
#scale_bar.SetAnnotationTextScalingOff()
#scale_bar.UnconstrainedFontSizeOn()
scale_bar.GetTitleTextProperty().ItalicOff();
scale_bar.GetLabelTextProperty().ItalicOff();
scale_bar.GetTitleTextProperty().BoldOff();
scale_bar.GetLabelTextProperty().BoldOff();
scale_bar.GetTitleTextProperty().ShadowOff();
scale_bar.GetLabelTextProperty().ShadowOff();
scale_bar.SetLabelFormat("%.2g");
scale_bar.GetTitleTextProperty().SetFontSize(15)
scale_bar.GetLabelTextProperty().SetFontSize(15)
scale_bar.GetTitleTextProperty().SetColor(1.0, 1.0, 1.0);
scale_bar.GetLabelTextProperty().SetColor(1.0, 1.0, 1.0);
return ox_actors, scale_bar
def add_cells():
cell_files = ["/scratch/jgrogan/TBME_16_Work/Simulations/BioHigh_15x/Bio3d_1/results_from_time_0/results_20.vtu",
"/scratch/jgrogan/TBME_16_Work/Simulations/BioHigh_15x/Bio3d_1/results_from_time_0/results_100.vtu",
"/scratch/jgrogan/TBME_16_Work/Simulations/BioHigh_15x/Bio3d_1/results_from_time_0/results_150.vtu"]
cell_actors = []
for eachFile in cell_files:
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName(eachFile)
reader.Update()
spheres = vtk.vtkSphereSource()
spheres.SetRadius(0.6)
spheres.SetPhiResolution(8)
spheres.SetThetaResolution(8)
glyph = vtk.vtkGlyph3D()
glyph.SetInputData(reader.GetOutput());
glyph.SetSourceConnection(spheres.GetOutputPort());
glyph.ClampingOff();
glyph.SetScaleModeToScaleByScalar();
glyph.SetScaleFactor(0.8);
glyph.Update();
trans = vtk.vtkTransform()
trans.Scale(42.375, 42.375, 42.375)
transf = vtk.vtkTransformFilter()
transf.SetInputData(glyph.GetOutput())
transf.SetTransform(trans)
transf.Update()
scaled_ctf = vtk.vtkColorTransferFunction()
scalar_range = [0, 0]
reader.GetOutput().GetPointData().GetArray("Cell types").GetRange(scalar_range)
for idx in range(256):
color = [0, 0, 0]
mp_color_map.get_disc_ctf().GetColor(float(idx)/255.0, color)
scaled_ctf.AddRGBPoint(scalar_range[0] + float(idx)*(scalar_range[1]-scalar_range[0])/255.0,
color[0], color[1], color[2])
mapper = vtk.vtkPolyDataMapper();
mapper.SetInputData(transf.GetOutput());
mapper.SetLookupTable(scaled_ctf);
mapper.ScalarVisibilityOn();
mapper.SelectColorArray("Cell types");
mapper.SetScalarModeToUsePointFieldData();
mapper.SetColorModeToMapScalars();
actor = vtk.vtkActor();
actor.SetMapper(mapper);
actor.GetProperty().SetOpacity(0.8);
cell_actors.append(actor)
return cell_actors
# if(!this->mDataLabel.empty() and this->mShowScaleBar)
# {
# this->mpScaleBar->SetLookupTable(p_scaled_ctf);
# this->mpScaleBar->SetTitle(this->mDataLabel.c_str());
# pRenderer->AddActor(this->mpScaleBar);
# }
def render_image(image_path, threshold = 20.0):
"""
Render the 3D stack with VTK
"""
input_files = []
for eachFile in os.listdir(image_path):
if eachFile.endswith(".vti"):
input_files.append(image_path + "/"+eachFile)
renderer = vtk.vtkRenderer()
renderer.SetBackground(20.0/255.0,30.0/255.0,48.0/255.0);
renderer.SetBackground2(36.0/255.0,59.0/255.0,85.0/255.0);
for eachImage in input_files:
reader= vtk.vtkXMLImageDataReader()
reader.SetFileName(eachImage)
reader.Update()
volume_mapper = vtk.vtkVolumeRayCastMapper()
volume_mapper.SetInputData(reader.GetOutput())
composite_function = vtk.vtkVolumeRayCastCompositeFunction()
volume_mapper.SetVolumeRayCastFunction(composite_function)
color_transfer_func = vtk.vtkColorTransferFunction()
color_transfer_func.AddRGBPoint(0, 0.0, 1.0, 0.0 )
color_transfer_func.AddRGBPoint(threshold-1, 0.0, 1.0, 0.0 )
color_transfer_func.AddRGBPoint(threshold, 1.0, 0.0, 0.0 )
color_transfer_func.AddRGBPoint(255.0, 1.0, 0.0, 0.0 )
opacity_transfer_func = vtk.vtkPiecewiseFunction()
opacity_transfer_func.AddPoint(0, 0.0 )
opacity_transfer_func.AddPoint(threshold-1.0, 0.0 )
#opacity_transfer_func.AddPoint(threshold, 1.0 )
opacity_transfer_func.AddPoint(255.0, 0.1 )
volume_properties = vtk.vtkVolumeProperty()
volume_properties.SetColor( color_transfer_func )
volume_properties.SetScalarOpacity( opacity_transfer_func )
volume = vtk.vtkVolume()
volume.SetMapper(volume_mapper)
volume.SetProperty(volume_properties)
renderer.AddVolume(volume)
# textActor = vtk.vtkTextActor()
# textActor.SetTextScaleModeToNone()
# textActor.SetDisplayPosition(200, 300)
# textActor.SetInput("Oxygen Tension (mmHg)")
# tprop = textActor.GetTextProperty()
# tprop.SetFontSize(10)
# tprop.SetFontFamilyToArial()
# tprop.SetJustificationToCentered()
# tprop.BoldOff()
# tprop.ItalicOff()
# tprop.ShadowOff()
# tprop.SetColor(1, 1, 1)
# #renderer.AddActor2D(textActor)
renderer.ResetCamera()
render_window = vtk.vtkRenderWindow()
window_interactor = vtk.vtkRenderWindowInteractor()
render_window.AddRenderer(renderer)
window_interactor.SetRenderWindow(render_window)
render_window.SetSize(170, 177)
render_window.Render()
ox_actors, scale_bar_actor = get_ox_map()
#renderer.AddActor(scale_bar_actor)
render_window.Render()
renderer.GetActiveCamera().Elevation(-33.0)
renderer.GetActiveCamera().Zoom(1.0)
position = list(renderer.GetActiveCamera().GetFocalPoint())
#position[0] = position[0] - 750
#position[1] = position[1] - 105
renderer.GetActiveCamera().SetFocalPoint(position)
renderer.ResetCameraClippingRange()
render_window.Render()
window_to_image_filter = vtk.vtkWindowToImageFilter()
window_to_image_filter.SetInput(render_window)
writer = vtk.vtkTIFFWriter()
extension = ".tiff"
writer.SetInputConnection(window_to_image_filter.GetOutputPort())
writer.SetFileName("vtk_animation_0"+extension)
writer.Write()
num_samples = 1
for idx in range(num_samples):
if idx==0:
for eachActor in ox_actors:
renderer.AddActor(eachActor)
renderer.GetActiveCamera().OrthogonalizeViewUp()
#time.sleep(0.02)
#renderer.GetActiveCamera().Dolly(1.002))
render_window.Render()
window_to_image_filter.Modified()
writer.SetFileName("vtk_animation_"+str(idx+1)+extension)
writer.Write()
renderer.RemoveActor(ox_actors[0])
render_window.Render()
window_to_image_filter.Modified()
writer.SetFileName("vtk_animation_"+str(num_samples+1)+extension)
writer.Write()
cell_actors = add_cells()
renderer.AddActor(cell_actors[0])
render_window.Render()
window_to_image_filter.Modified()
writer.SetFileName("vtk_animation_"+str(num_samples+2)+extension)
writer.Write()
renderer.RemoveActor(cell_actors[0])
renderer.AddActor(cell_actors[1])
render_window.Render()
window_to_image_filter.Modified()
writer.SetFileName("vtk_animation_"+str(num_samples+3)+extension)
writer.Write()
renderer.RemoveActor(cell_actors[1])
renderer.AddActor(cell_actors[2])
render_window.Render()
window_to_image_filter.Modified()
writer.SetFileName("vtk_animation_"+str(num_samples+4)+extension)
writer.Write()
window_interactor.Start()
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("-i", "--input_file", type=str, help='vtk input file')
args = parser.parse_args()
render_image(args.input_file)