[Insight-users] Problem grafting a C++ array as an ImageToImageFilter output

Ramón Casero Cañas rcasero at gmail.com
Fri May 24 19:16:07 EDT 2013


Hi all,

I think there may be some problem with some of the itk::ImageToImageFilter
when one tries to graft a C++ array to be used as the filter's output, or
at least with the way I do it.

This was kindly reported by Peter Thalmann in [1], and I'm trying to help
him. This is a problem that I had also noticed with a couple of other
filters.

I have attached a minimal example of a C++ MEX file that creates a function
that can be run from Matlab, with the CMake files to compile it. (I have
tried this with ITK 4.3.1).

Save everything to directory test, and then build the example from the shell

cd test
mkdir bin
cd bin
cmake ..
make install

To run the example from Matlab,

cd test
% create a test binary square with a little hole
im = zeros(15, 15, 'uint8');
im(3:13, 3:13) = 1;
im(7:8, 7) = 0;
im2 = itk_test(im);

This runs filter itk::VotingBinaryIterativeHoleFillingImageFilter on the
image. The program outputs to the Matlab shell both the content of
filter->GetOutput(), and the content of the Matlab output array. As we can
see, the output is not being saved to the array

Filter result, reading from the filter
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Filter result, reading from the Matlab output array
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


But this approach works for other filters. If we choose the Median filter
instead: in ItkTestSimpleImFilter.cpp, ucomment

  // typedef itk::MedianImageFilter<ImageType, ImageType>
  //   FilterType;

and comment out

  typedef itk::VotingBinaryIterativeHoleFillingImageFilter<ImageType>
    FilterType;

[...]

  // filter parameters only for the
VotingBinaryIterativeHoleFillingImageFilter
  filter->SetMaximumNumberOfIterations(4);
  filter->SetBackgroundValue(0);
  filter->SetForegroundValue(1);
  filter->SetMajorityThreshold(2);

then we can see that the array is actually being used as the filter's output

>> im2 = itk_test(im);
Filter result, reading from the filter
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Filter result, reading from the Matlab output array
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

I have been looking at itkVotingBinaryIterativeHoleFillingImageFilter.hxx,
and I was wondering whether the problem is in
VotingBinaryIterativeHoleFillingImageFilter< TInputImage >
::GenerateData().

The filter works iteratively, doing

  while ( m_CurrentNumberOfIterations < m_MaximumNumberOfIterations )
    {
    filter->SetInput(input);
    filter->Update();

    m_CurrentNumberOfIterations++;
    progress.CompletedPixel();   // not really a pixel but an iteration
    this->InvokeEvent( IterationEvent() );

    const unsigned int numberOfPixelsChangedInThisIteration =
      filter->GetNumberOfPixelsChanged();
    m_NumberOfPixelsChanged += numberOfPixelsChangedInThisIteration;

    output = filter->GetOutput();
    output->DisconnectPipeline();
    input = output;
    if ( numberOfPixelsChangedInThisIteration == 0 )
      {
      break;
      }
    }
  this->GraftOutput(output);


Here, output gets a DisconnectPipeline(). I have tried commenting that like
out, rebuilding and reinstalling ITK, but it doesn't seem to make a
difference.

[1]
https://groups.google.com/forum/?fromgroups#!topic/gerardus-users/pLH0iR0H74o

Best regards,

Ramon.




-- 
Dr. Ramón Casero Cañas

Oxford e-Research Centre (OeRC)
University of Oxford
7 Keble Rd
Oxford OX1 3QG

tlf     +44 (0) 1865 610739
web     http://www.cs.ox.ac.uk/people/Ramon.CaseroCanas
photos  http://www.flickr.com/photos/rcasero/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130525/c6afa12b/attachment.htm>
-------------- next part --------------
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

# Find Matlab
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
FIND_PACKAGE(Matlab REQUIRED)
IF(MATLAB_FOUND)
  MESSAGE(STATUS "Matlab found")
ELSE(MATLAB_FOUND)
  MESSAGE(FATAL_ERROR "Matlab not found")
ENDIF(MATLAB_FOUND)

# some versions of Matlab or some libraries are not compatible with
# more advanced gcc versions
#
# the compiler version has to be set up before project(), otherwise we
# will get an infinite loop. We force the compiler version setting the
# corresponding environmental variables (equivalent to running e.g.  
# $ CC=gcc-4.4 CXX=g++-4.4 cmake ..  This is a better way than directly
# setting MAKE_C_COMPILER, CMAKE_CXX_COMPILER. For example, if we set these
# variables after project(), this creates an infinite loop.
if(NOT WIN32)
  if(BUILD_WITH_CUDA OR ${MATLAB_VERSION} MATCHES "R2012a")
    set(ENV{CC} gcc-4.4)
    set(ENV{CXX} g++-4.4)
  endif(BUILD_WITH_CUDA OR ${MATLAB_VERSION} MATCHES "R2012a")
endif(NOT WIN32)

PROJECT(ITKTEST)

# Find ITK.
FIND_PACKAGE(ITK REQUIRED)
IF(ITK_FOUND)
  MESSAGE(STATUS "ITK found")
  INCLUDE(${ITK_USE_FILE})
ELSE(ITK_FOUND)
  MESSAGE(FATAL_ERROR "ITK not found")
ENDIF(ITK_FOUND)

INCLUDE_DIRECTORIES(${MATLAB_INCLUDE_DIR})

# Add macros to build MEX files
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/MatlabMakeMacros.cmake)

IF(NOT WIN32)
  ADD_DEFINITIONS("-O2 -Wall")
ENDIF(NOT WIN32)

ADD_MEX_FILE(itk_test
  ItkTestSimpleImFilter.cpp)

TARGET_LINK_LIBRARIES(itk_test
  ${ITK_LIBRARIES})

IF(WIN32)
  INSTALL(TARGETS
    itk_test
    RUNTIME
    DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
ELSE(WIN32)
  INSTALL(TARGETS
    itk_test
    LIBRARY
    DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
ENDIF(WIN32)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: FindMatlab.cmake
Type: application/octet-stream
Size: 7648 bytes
Desc: not available
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130525/c6afa12b/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ItkTestSimpleImFilter.cpp
Type: text/x-c++src
Size: 5255 bytes
Desc: not available
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130525/c6afa12b/attachment.cpp>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: MatlabMakeMacros.cmake
Type: application/octet-stream
Size: 8981 bytes
Desc: not available
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130525/c6afa12b/attachment-0001.obj>


More information about the Insight-users mailing list