MedicalDemo2
Repository source: MedicalDemo2
Description¶
Skin and bone isosurfaces.
Usage
MedicalDemo2 FullHead.mhd
Note
The skin color was selected from Table 7 in Improvement of Haar Feature Based Face Detection in OpenCV Incorporating Human Skin Color Characteristic
Note
The original source code for this example is here.
Info
See Figure 12-3 in Chapter 12 the VTK Textbook.
Info
The example uses src/Testing/Data/FullHead.mhd which references src/Testing/Data/FullHead.raw.gz.
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
MedicalDemo2.py
#!/usr/bin/env python
import sys
from pathlib import Path
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkFiltersCore import (
vtkFlyingEdges3D,
vtkMarchingCubes,
vtkStripper
)
from vtkmodules.vtkFiltersModeling import vtkOutlineFilter
from vtkmodules.vtkIOImage import vtkMetaImageReader
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkCamera,
vtkPolyDataMapper,
vtkProperty,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer
)
def main():
colors = vtkNamedColors()
file_name, use_flying_edges = get_program_parameters()
colors.SetColor('SkinColor', 240, 184, 160, 255)
colors.SetColor('BackfaceColor', 255, 229, 200, 255)
colors.SetColor('BkgColor', 51, 77, 102, 255)
# Create the renderer, the render window, and the interactor. The renderer
# draws into the render window, the interactor enables mouse- and
# keyboard-based interaction with the data within the render window.
#
# Set a background color for the renderer and set the name and
# size of the render window (expressed in pixels).
ren = vtkRenderer(background=colors.GetColor3d('BkgColor'))
ren_win = vtkRenderWindow(size=(640, 480),
window_name=f'{Path(sys.argv[0]).stem:s}')
ren_win.AddRenderer(ren)
iren = vtkRenderWindowInteractor()
iren.render_window = ren_win
# Since we import vtkmodules.vtkInteractionStyle we can do this
# because vtkInteractorStyleSwitch is automatically imported:
iren.interactor_style.SetCurrentStyleToTrackballCamera()
# The following reader is used to read a series of 2D slices (images)
# that compose the volume. The slice dimensions are set, and the
# pixel spacing. The data Endianness must also be specified. The reader
# uses the FilePrefix in combination with the slice number to construct
# filenames using the format FilePrefix.%d. (In this case the FilePrefix
# is the root name of the file: quarter.)
reader = vtkMetaImageReader(file_name=file_name)
# An isosurface, or contour value of 500 is known to correspond to the
# skin of the patient.
if use_flying_edges:
skin_extractor = vtkFlyingEdges3D()
else:
skin_extractor = vtkMarchingCubes()
skin_extractor.SetValue(0, 500)
# The triangle stripper is used to create triangle strips from the
# isosurface these render much faster on many systems.
skin_stripper = vtkStripper()
skin_mapper = vtkPolyDataMapper(scalar_visibility=False)
reader >> skin_extractor >> skin_stripper >> skin_mapper
skin_prop = vtkProperty(diffuse_color=colors.GetColor3d('SkinColor'), specular=0.3, specular_power=20, opacity=0.5)
back_prop = vtkProperty(diffuse_color=colors.GetColor3d('BackfaceColor'))
skin = vtkActor(mapper=skin_mapper, property=skin_prop, backface_property=back_prop)
# An isosurface, or contour value of 1150 is known to correspond to the
# bone of the patient.
# The triangle stripper is used to create triangle strips from the
# isosurface these render much faster on may systems.
if use_flying_edges:
bone_extractor = vtkFlyingEdges3D()
else:
bone_extractor = vtkMarchingCubes()
bone_extractor.SetValue(0, 1150)
bone_stripper = vtkStripper()
bone_mapper = vtkPolyDataMapper(scalar_visibility=False)
reader >> bone_extractor >> bone_stripper >> bone_mapper
bone_prop = vtkProperty(diffuse_color=colors.GetColor3d('Ivory'))
bone = vtkActor(mapper=bone_mapper, property=bone_prop)
# An outline provides context around the data.
#
outline_data = vtkOutlineFilter()
outline_mapper = vtkPolyDataMapper()
reader >> outline_data >> outline_mapper
outline_prop = vtkProperty(diffuse_color=colors.GetColor3d('Black'))
outline = vtkActor(mapper=outline_mapper, property=outline_prop)
# It is convenient to create an initial view of the data. The FocalPoint
# and Position form a vector direction. Later on (ResetCamera() method)
# this vector is used to position the camera to look at the data in
# this direction.
camera = vtkCamera(view_up=(0, 0, 1), position=(0, -1, 0), focal_point=(0, 0, 0))
camera.ComputeViewPlaneNormal()
camera.Azimuth(30.0)
camera.Elevation(30.0)
# Actors are added to the renderer. An initial camera view is created.
# The Dolly() method moves the camera towards the FocalPoint,
# thereby enlarging the image.
ren.AddActor(outline)
ren.AddActor(skin)
ren.AddActor(bone)
ren.SetActiveCamera(camera)
ren.ResetCamera()
camera.Dolly(1.5)
# Note that when camera movement occurs (as it does in the Dolly()
# method), the clipping planes often need adjusting. Clipping planes
# consist of two planes: near and far along the view direction. The
# near plane clips out objects in front of the plane the far plane
# clips out objects behind the plane. This way only what is drawn
# between the planes is actually rendered.
ren.ResetCameraClippingRange()
# Initialize the event loop and then start it.
iren.Initialize()
iren.Start()
def get_program_parameters():
import argparse
description = 'The Skin and bone isosurfaces extracted from a CT dataset of the head.'
epilogue = '''
Derived from VTK/Examples/Cxx/Medical2.cxx
This example reads a volume dataset, extracts two isosurfaces that
represent the skin and bone, and then displays it.
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('filename', help='FullHead.mhd.')
parser.add_argument('-m', '--marching_cubes', action='store_false',
help='Use Marching Cubes instead of Flying Edges.')
args = parser.parse_args()
return args.filename, args.marching_cubes
if __name__ == '__main__':
main()