1
votes

I have a serious problem concerning the compilation of a small example programm which should use the VTK as well as the ITK Library. Goal of the example is to load Dicom Images from a folder into VTK image format, convert them to ITK image format, perform operations and convert them back to VTK image format to display them.

Here is the sample program:

#include <iostream>
#include <math.h>  


#include <vtkSmartPointer.h>
#include <vtkDICOMImageReader.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkResliceImageViewer.h>
#include <vtkRenderWindow.h>


#include "itkRelabelComponentImageFilter.h"
#include "itkImage.h"
#include "itkVTKImageToImageFilter.h"
#include "itkBinaryThresholdImageFilter.h"
#include "itkLabelGeometryImageFilter.h"
#include "itkImageToVTKImageFilter.h"
#include "itkConnectedComponentImageFilter.h"
#include "itkBinaryImageToLabelMapFilter.h"
#include "itkLabelMapToLabelImageFilter.h"

#include "markerLib/markerlib.h"

int main(int argc, char *argv[]) {

    const unsigned int Dimension = 3;

    //Image Type
    typedef itk::Image<short, Dimension> ShortImageType;

    //Types for converting between ITK and VTK
    typedef itk::VTKImageToImageFilter<ShortImageType> VTKImageToImageType;
    typedef itk::ImageToVTKImageFilter<ShortImageType> ConnectorType;


    //Read DICOM Data
    vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
    reader->SetDirectoryName("some_path");//Type the correct absolute path to the Dicom data here.
    reader->Update();


    //Converting to ITK Image Format
    VTKImageToImageType::Pointer vtkImageToImageFilter = VTKImageToImageType::New();
    vtkImageToImageFilter->SetInput(reader->GetOutput());
    vtkImageToImageFilter->Update();

    //Converting Back from ITK to VTK Image for Visualization.
    ConnectorType::Pointer connector = ConnectorType::New();
    connector->SetInput(vtkImageToImageFilter->GetOutput());
    //connector->SetInput(removed->GetOutput()); //The current Threshold(minVoxelCount) seems to be to high. because the marker is not visible if looking at the filtered set.
    connector->Update();


//    //Showing slice imagesvtkResliceImageViewer
    vtkSmartPointer<vtkResliceImageViewer>viewer = vtkSmartPointer<vtkResliceImageViewer>::New();
    vtkSmartPointer<vtkRenderWindowInteractor>interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(viewer->GetRenderWindow());

    viewer->SetupInteractor(interactor);
    viewer->SetInputData(connector->GetOutput());
    int midslice = viewer->GetSliceMax() / 2;
    viewer->SetSlice(midslice);
    viewer->SetSliceOrientationToXY();

    viewer->GetRenderer()->ResetCamera();
    viewer->Render();
    interactor->Start();
    return EXIT_SUCCESS;
}

The VTK must be version 6.1.0. I created a make file using cmake with the flag shared libs and qt group on. the Qt Version is installed on the machine is 5.3.1. The ITK version is less relevant, but I used Version 4.8.0. I created a make file with the VTK-glue flag enabled. Both VTK and ITK compiled without any errors. I performed a make install on both libraries. My sample programm creates a makefile with the following CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)

project(marker)

find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
if (ITKVtkGlue_LOADED)
  find_package(VTK REQUIRED)
  include(${VTK_USE_FILE})
else()
  find_package(ItkVtkGlue REQUIRED)
  include(${ItkVtkGlue_USE_FILE})
  set(Glue ItkVtkGlue)
endif()

file(GLOB HEADER_FILES *.h)
file(GLOB CPP_FILES *.cpp)

add_executable(${PROJECT_NAME} ${SRC_LIST} ${CPP_FILES})
target_link_libraries(${PROJECT_NAME} ${Glue}  ${VTK_LIBRARIES} ${ITK_LIBRARIES})

message("VTK ${VTK_LIBRARIES}            ITK  ${ITK_LIBRARIES}")

When trying to compile the program the following error gets thrown:

Scanning dependencies of target marker
[100%] Building CXX object CMakeFiles/marker.dir/main.cpp.o
Linking CXX executable marker
CMakeFiles/marker.dir/main.cpp.o: In function `vtkSmartPointer<vtkResliceImageViewer>::New()':
main.cpp:(.text._ZN15vtkSmartPointerI21vtkResliceImageViewerE3NewEv[_ZN15vtkSmartPointerI21vtkResliceImageViewerE3NewEv]+0xd): undefined reference to `vtkResliceImageViewer::New()'
collect2: error: ld returned 1 exit status
make[2]: *** [marker] Error 1
make[1]: *** [CMakeFiles/marker.dir/all] Error 2
make: *** [all] Error 2

It cannot resolve the vtkResliceImageViewer. Also, if you look at the message of the cmake generation you can see that VTK_LIBRARIES is only two libs while ITK has many more.

cmake Message:

VTK vtkCommonCore;vtksys            ITK  itkdouble-conversion;itksys;itkvnl_algo;itkvnl;itkv3p_netlib;ITKCommon;itkNetlib........

The strange thing is that on another machine the program compiles without any errors and works. So there must be some differences in the pretty complicated compilation steps of VTK and ITK.

My Question now is, has somebody seen a similar error, or has somebody a glue what the reason for the missing VTK libs could be?

1

1 Answers

2
votes

I had an issue with this before. ITK's find_package was overwriting VTK_LIBRARIES. The workaround is to store the libraries in a temp variable, like so:

find_package(VTK) 
set(VTK_LIBS_ORIG ${VTK_LIBRARIES})  # store the libs in an extra variable
include(${VTK_USE_FILE})

find_package(ITK)
include(${ITK_USE_FILE})

# now restore the variables back:
set(VTK_LIBRARIES ${VTK_LIBS_ORIG})

HTH, Miro