Skip to content

FrogBrain

vtk-examples/Cxx/Visualization/FrogBrain


Description

The frog's brain. Model extracted without smoothing (left) and with smoothing (right).

Other languages

See (Python)

Question

If you have a question about this example, please use the VTK Discourse Forum

Code

FrogBrain.cxx

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkImageGaussianSmooth.h>
#include <vtkImageThreshold.h>
#include <vtkLookupTable.h>
#include <vtkMarchingCubes.h>
#include <vtkMetaImageReader.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyDataNormals.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkStripper.h>
#include <vtkWindowedSincPolyDataFilter.h>

#include <map>

namespace {
void CreateFrogLut(vtkLookupTable* colorLut);
void CreateFrogActor(std::string fileName, int tissue, vtkActor* actor);
void CreateSmoothFrogActor(std::string fileName, int tissue, vtkActor* actor);
void CreateTissueMap(std::map<std::string, int>& tissueMap);
} // namespace

int main(int argc, char* argv[])
{
  std::map<std::string, int> tissueMap;
  CreateTissueMap(tissueMap);

  vtkNew<vtkLookupTable> colorLut;
  colorLut->SetNumberOfColors(17);
  colorLut->SetTableRange(0, 16);
  colorLut->Build();

  CreateFrogLut(colorLut);

  vtkNew<vtkNamedColors> colors;
  // Setup render window, renderer, and interactor.
  vtkNew<vtkRenderer> rendererLeft;
  rendererLeft->SetViewport(0, 0, .5, 1);
  vtkNew<vtkRenderer> rendererRight;
  rendererRight->SetViewport(.5, 0, 1, 1);
  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->AddRenderer(rendererLeft);
  renderWindow->AddRenderer(rendererRight);
  vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
  renderWindowInteractor->SetRenderWindow(renderWindow);
  vtkNew<vtkActor> actor;
  actor->GetProperty()->SetDiffuseColor(
      colorLut->GetTableValue(tissueMap[argv[2]]));
  CreateFrogActor(argv[1], tissueMap[argv[2]], actor);
  rendererLeft->AddActor(actor);

  vtkNew<vtkActor> actorSmooth;
  actorSmooth->GetProperty()->SetDiffuseColor(
      colorLut->GetTableValue(tissueMap[argv[2]]));
  actorSmooth->GetProperty()->SetDiffuse(1.0);
  actorSmooth->GetProperty()->SetSpecular(.5);
  actorSmooth->GetProperty()->SetSpecularPower(100);
  CreateSmoothFrogActor(argv[1], tissueMap[argv[2]], actorSmooth);
  rendererRight->AddActor(actorSmooth);

  rendererLeft->ResetCamera();
  rendererLeft->GetActiveCamera()->SetViewUp(-1, 0, 0);
  rendererLeft->GetActiveCamera()->Azimuth(180);
  rendererLeft->ResetCameraClippingRange();

  rendererLeft->SetBackground(colors->GetColor3d("LightSteelBlue").GetData());
  rendererRight->SetBackground(colors->GetColor3d("LightSteelBlue").GetData());
  rendererRight->SetActiveCamera(rendererLeft->GetActiveCamera());

  renderWindow->SetSize(640, 480);
  renderWindow->SetWindowName("FrogBrain");

  renderWindow->Render();

  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

namespace {
void CreateTissueMap(std::map<std::string, int>& tissueMap)
{
  tissueMap["blood"] = 1;
  tissueMap["brain"] = 2;
  tissueMap["duodenum"] = 3;
  tissueMap["eyeRetina"] = 4;
  tissueMap["eyeWhite"] = 5;
  tissueMap["heart"] = 6;
  tissueMap["ileum"] = 7;
  tissueMap["kidney"] = 8;
  tissueMap["intestine"] = 9;
  tissueMap["liver"] = 10;
  tissueMap["lung"] = 11;
  tissueMap["nerve"] = 12;
  tissueMap["skeleton"] = 13;
  tissueMap["spleen"] = 14;
  tissueMap["stomach"] = 15;
  return;
}
void CreateSmoothFrogActor(std::string fileName, int tissue, vtkActor* actor)
{
  vtkNew<vtkMetaImageReader> reader;
  reader->SetFileName(fileName.c_str());
  reader->Update();

  vtkNew<vtkImageThreshold> selectTissue;
  selectTissue->ThresholdBetween(tissue, tissue);
  selectTissue->SetInValue(255);
  selectTissue->SetOutValue(0);
  selectTissue->SetInputConnection(reader->GetOutputPort());

  int gaussianRadius = 1;
  double gaussianStandardDeviation = 2.0;
  vtkNew<vtkImageGaussianSmooth> gaussian;
  gaussian->SetStandardDeviations(gaussianStandardDeviation,
                                  gaussianStandardDeviation,
                                  gaussianStandardDeviation);
  gaussian->SetRadiusFactors(gaussianRadius, gaussianRadius, gaussianRadius);
  gaussian->SetInputConnection(selectTissue->GetOutputPort());

  double isoValue = 127.5;
  vtkNew<vtkMarchingCubes> mcubes;
  mcubes->SetInputConnection(gaussian->GetOutputPort());
  mcubes->ComputeScalarsOff();
  mcubes->ComputeGradientsOff();
  mcubes->ComputeNormalsOff();
  mcubes->SetValue(0, isoValue);

  int smoothingIterations = 0;
  double passBand = 0.001;
  double featureAngle = 60.0;
  vtkNew<vtkWindowedSincPolyDataFilter> smoother;
  smoother->SetInputConnection(mcubes->GetOutputPort());
  smoother->SetNumberOfIterations(smoothingIterations);
  smoother->BoundarySmoothingOff();
  smoother->FeatureEdgeSmoothingOff();
  smoother->SetFeatureAngle(featureAngle);
  smoother->SetPassBand(passBand);
  smoother->NonManifoldSmoothingOn();
  smoother->NormalizeCoordinatesOn();
  smoother->Update();

  vtkNew<vtkPolyDataNormals> normals;
  normals->SetInputConnection(smoother->GetOutputPort());
  normals->SetFeatureAngle(featureAngle);

  vtkNew<vtkStripper> stripper;
  stripper->SetInputConnection(normals->GetOutputPort());

  vtkNew<vtkPolyDataMapper> mapper;
  mapper->SetInputConnection(stripper->GetOutputPort());

  actor->SetMapper(mapper);
  return;
}

void CreateFrogActor(std::string fileName, int tissue, vtkActor* actor)
{
  vtkNew<vtkMetaImageReader> reader;
  reader->SetFileName(fileName.c_str());
  reader->Update();

  vtkNew<vtkImageThreshold> selectTissue;
  selectTissue->ThresholdBetween(tissue, tissue);
  selectTissue->SetInValue(255);
  selectTissue->SetOutValue(0);
  selectTissue->SetInputConnection(reader->GetOutputPort());

  double isoValue = 63.5;
  vtkNew<vtkMarchingCubes> mcubes;
  mcubes->SetInputConnection(selectTissue->GetOutputPort());
  mcubes->ComputeScalarsOff();
  mcubes->ComputeGradientsOff();
  mcubes->ComputeNormalsOn();
  mcubes->SetValue(0, isoValue);

  vtkNew<vtkStripper> stripper;
  stripper->SetInputConnection(mcubes->GetOutputPort());

  vtkNew<vtkPolyDataMapper> mapper;
  mapper->SetInputConnection(stripper->GetOutputPort());

  actor->SetMapper(mapper);
  return;
}

void CreateFrogLut(vtkLookupTable* colorLut)
{
  vtkNew<vtkNamedColors> colors;
  colorLut->SetTableValue(0, 0, 0, 0, 0);
  colorLut->SetTableValue(1,
                          colors->GetColor4d("salmon").GetData()); // blood
  colorLut->SetTableValue(2,
                          colors->GetColor4d("beige").GetData()); // brain
  colorLut->SetTableValue(3,
                          colors->GetColor4d("orange").GetData()); // duodenum
  colorLut->SetTableValue(
      4,
      colors->GetColor4d("misty_rose").GetData()); // eye_retina
  colorLut->SetTableValue(5,
                          colors->GetColor4d("white").GetData()); // eye_white
  colorLut->SetTableValue(6,
                          colors->GetColor4d("tomato").GetData()); // heart
  colorLut->SetTableValue(7,
                          colors->GetColor4d("raspberry").GetData()); // ileum
  colorLut->SetTableValue(8,
                          colors->GetColor4d("banana").GetData()); // kidney
  colorLut->SetTableValue(9,
                          colors->GetColor4d("peru").GetData()); // l_intestine
  colorLut->SetTableValue(10,
                          colors->GetColor4d("pink").GetData()); // liver
  colorLut->SetTableValue(11,
                          colors->GetColor4d("powder_blue").GetData()); // lung
  colorLut->SetTableValue(12,
                          colors->GetColor4d("carrot").GetData()); // nerve
  colorLut->SetTableValue(13,
                          colors->GetColor4d("wheat").GetData()); // skeleton
  colorLut->SetTableValue(14,
                          colors->GetColor4d("violet").GetData()); // spleen
  colorLut->SetTableValue(15,
                          colors->GetColor4d("plum").GetData()); // stomach
}
} // namespace

CMakeLists.txt

cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

project(FrogBrain)

find_package(VTK COMPONENTS 
  vtkCommonColor
  vtkCommonCore
  vtkFiltersCore
  vtkIOImage
  vtkImagingCore
  vtkImagingGeneral
  vtkInteractionStyle
  vtkRenderingContextOpenGL2
  vtkRenderingCore
  vtkRenderingFreeType
  vtkRenderingGL2PSOpenGL2
  vtkRenderingOpenGL2
  QUIET
)

if (NOT VTK_FOUND)
  message("Skipping FrogBrain: ${VTK_NOT_FOUND_MESSAGE}")
  return ()
endif()
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
if (VTK_VERSION VERSION_LESS "8.90.0")
  # old system
  include(${VTK_USE_FILE})
  add_executable(FrogBrain MACOSX_BUNDLE FrogBrain.cxx )
  target_link_libraries(FrogBrain PRIVATE ${VTK_LIBRARIES})
else ()
  # include all components
  add_executable(FrogBrain MACOSX_BUNDLE FrogBrain.cxx )
  target_link_libraries(FrogBrain PRIVATE ${VTK_LIBRARIES})
  # vtk_module_autoinit is needed
  vtk_module_autoinit(
    TARGETS FrogBrain
    MODULES ${VTK_LIBRARIES}
    )
endif ()

Download and Build FrogBrain

Click here to download FrogBrain and its CMakeLists.txt file. Once the tarball FrogBrain.tar has been downloaded and extracted,

cd FrogBrain/build

If VTK is installed:

cmake ..

If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:

cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

make

and run it:

./FrogBrain

WINDOWS USERS

Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.