IsoSubsample
VTKExamples/Python/ImageProcessing/IsoSubsample
Description¶
An artifact called aliasing occurs when sub-sampling and is often associated with stair-stepping edges. Sampling theory proves that discrete sampled signals with spacing S, completely describe continuous functions composed of frequencies less than S/2. When a signal is sub-sampled, its capacity to hold high frequency information is reduced. However, the high frequency energy does not disappear. It wraps around the frequency spectrum appearing as a low frequency alias artifact. The solution, which eliminates this artifact, is to low-pass filter before sub-sampling.
Low-pass smoothing reduces the high frequency range of an image that would cause aliasing. The same aliasing phenomena occurs when acquiring data. If a signal from an analog source contains high frequencies, saving the analog data in a discrete form requires sub-sampling that will introduce alias artifacts. For this reason, it is common practice to acquire data at high resolutions,then smooth and subsample to reduce the image to a manageable size.
This example demonstrates aliasing that occurs when a high-frequency signal is sub-sampled. High frequencies appear as low frequency artifacts. The left image is an isosurface of a skull after sub-sampling. The right image used a low-pass filter before sub-sampling to reduce aliasing.
Note
This example uses the FullHead.mhd, FullHead.raw.gz dataset.
Code¶
IsoSubsample.py
#!/usr/bin/env python """ """ import vtk def main(): colors = vtk.vtkNamedColors() colors.SetColor("ActorColor", [235, 235, 235, 255]) fileName = get_program_parameters() # Read the image. readerFactory = vtk.vtkImageReader2Factory() reader = readerFactory.CreateImageReader2(fileName) reader.SetFileName(fileName) reader.Update() # Smoothed pipeline. smooth = vtk.vtkImageGaussianSmooth() smooth.SetDimensionality(3) smooth.SetInputConnection(reader.GetOutputPort()) smooth.SetStandardDeviations(1.75, 1.75, 0.0) smooth.SetRadiusFactor(2) subsampleSmoothed = vtk.vtkImageShrink3D() subsampleSmoothed.SetInputConnection(smooth.GetOutputPort()) subsampleSmoothed.SetShrinkFactors(4, 4, 1) isoSmoothed = vtk.vtkImageMarchingCubes() isoSmoothed.SetInputConnection(smooth.GetOutputPort()) isoSmoothed.SetValue(0, 1150) isoSmoothedMapper = vtk.vtkPolyDataMapper() isoSmoothedMapper.SetInputConnection(isoSmoothed.GetOutputPort()) isoSmoothedMapper.ScalarVisibilityOff() isoSmoothedActor = vtk.vtkActor() isoSmoothedActor.SetMapper(isoSmoothedMapper) isoSmoothedActor.GetProperty().SetColor(colors.GetColor3d("ActorColor")) # Unsmoothed pipeline. # Sub sample the data. subsample = vtk.vtkImageShrink3D() subsample.SetInputConnection(reader.GetOutputPort()) subsample.SetShrinkFactors(4, 4, 1) iso = vtk.vtkImageMarchingCubes() iso.SetInputConnection(subsample.GetOutputPort()) iso.SetValue(0, 1150) isoMapper = vtk.vtkPolyDataMapper() isoMapper.SetInputConnection(iso.GetOutputPort()) isoMapper.ScalarVisibilityOff() isoActor = vtk.vtkActor() isoActor.SetMapper(isoMapper) isoActor.GetProperty().SetColor(colors.GetColor3d("ActorColor")) # The rendering Pipeline. # Setup the render window, renderer, and interactor. leftViewport = [0.0, 0.0, 0.5, 1.0] rightViewport = [0.5, 0.0, 1.0, 1.0] rendererLeft = vtk.vtkRenderer() rendererLeft.SetViewport(leftViewport) rendererRight = vtk.vtkRenderer() rendererRight.SetViewport(rightViewport) renderWindow = vtk.vtkRenderWindow() renderWindow.AddRenderer(rendererLeft) renderWindow.AddRenderer(rendererRight) renderWindowInteractor = vtk.vtkRenderWindowInteractor() renderWindowInteractor.SetRenderWindow(renderWindow) rendererLeft.AddActor(isoActor) rendererRight.AddActor(isoSmoothedActor) rendererLeft.GetActiveCamera().SetFocalPoint(0.0, 0.0, 0.0) rendererLeft.GetActiveCamera().SetPosition(0.0, -1.0, 0.0) rendererLeft.GetActiveCamera().SetViewUp(0.0, 0.0, -1.0) rendererLeft.ResetCamera() rendererLeft.GetActiveCamera().Azimuth(-20.0) rendererLeft.GetActiveCamera().Elevation(20.0) rendererLeft.ResetCameraClippingRange() rendererLeft.SetBackground(colors.GetColor3d("SlateGray")) rendererRight.SetBackground(colors.GetColor3d("LightSlateGray")) rendererRight.SetActiveCamera(rendererLeft.GetActiveCamera()) renderWindow.SetSize(640, 480) renderWindow.Render() renderWindowInteractor.Start() def get_program_parameters(): import argparse description = 'This figure demonstrates aliasing that occurs when a high-frequency signal is subsampled.' epilogue = ''' High frequencies appear as low frequency artifacts. The left image is an isosurface of a skull after subsampling. The right image used a low-pass filter before subsampling to reduce aliasing. ''' parser = argparse.ArgumentParser(description=description, epilog=epilogue, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('filename', help='FullHead.mhd.') args = parser.parse_args() return args.filename if __name__ == '__main__': main()