Add initial files.
This commit is contained in:
parent
1f228d3d2a
commit
00fa3da2eb
24 changed files with 14465 additions and 0 deletions
47
README.md
Normal file
47
README.md
Normal 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:
|
||||||
|
|
0
format_conversion/__init__.py
Normal file
0
format_conversion/__init__.py
Normal file
50
format_conversion/bftools_wrapper.py
Normal file
50
format_conversion/bftools_wrapper.py
Normal 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()
|
103
format_conversion/extract_zeiss_metadata.py
Normal file
103
format_conversion/extract_zeiss_metadata.py
Normal 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')
|
12562
format_conversion/ome_schema.py
Normal file
12562
format_conversion/ome_schema.py
Normal file
File diff suppressed because it is too large
Load diff
120
format_conversion/tiff_to_vtk.py
Normal file
120
format_conversion/tiff_to_vtk.py
Normal 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')
|
97
format_conversion/zeiss_to_tiff.py
Normal file
97
format_conversion/zeiss_to_tiff.py
Normal 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
0
image/__init__.py
Normal file
75
image/downsample_tiffs.py
Normal file
75
image/downsample_tiffs.py
Normal 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
135
image/processing.py
Normal 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)
|
||||||
|
|
0
image/processing/__init__.py
Normal file
0
image/processing/__init__.py
Normal file
0
image/processing/conversion/__init__.py
Normal file
0
image/processing/conversion/__init__.py
Normal file
30
image/processing/median.py
Normal file
30
image/processing/median.py
Normal 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)
|
36
image/processing/projection.py
Normal file
36
image/processing/projection.py
Normal 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)
|
30
image/processing/reduce.py
Normal file
30
image/processing/reduce.py
Normal 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
17
image/processing/show.py
Normal 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)
|
30
image/processing/threshold.py
Normal file
30
image/processing/threshold.py
Normal 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
39
image/processing/tile.py
Normal 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
171
image/surface.py
Normal 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
44
process_russ_format.py
Normal 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
36
utility.py
Normal 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
0
viewing/__init__.py
Normal file
534
viewing/mp_color_map.py
Normal file
534
viewing/mp_color_map.py
Normal 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
309
viewing/simple_render.py
Normal 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)
|
Loading…
Reference in a new issue