[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