[ITK] Compilation error when changing boundary condition

Nicolas Gallego nicgallego at gmail.com
Thu Jul 3 05:54:07 EDT 2014


Hi,

For the record, while the compilation issue is solved, I found a work
around by overriding the boundary condition at run time,
here I share the code with the fix.

Nicolás Gallego-Ortiz
Université catholique de Louvain, Belgium


2014-07-02 21:06 GMT+02:00 Bill Lorensen <bill.lorensen at gmail.com>:

> I can reproduce your problem and I see the issue.
> NeighborhoodInnerProduct operator()'s second argument is const
> ConstNeighborhoodIterator< TImage >.
> Notice that the boundary condition template parameter is not specified.
>
> So, you cannot change the boundary condition when you use the
> neighborhood inner product. This is design bug. I'll take a look at
> how this could be redesigned.
>
> Bill
>
> On Wed, Jul 2, 2014 at 1:35 PM, Nicolas Gallego <nicgallego at gmail.com>
> wrote:
> > Hi Bill,
> >
> > thanks for your interest in this issue,
> > here the code that reproduces the problem
> >
> > Nicolás Gallego-Ortiz
> > Université catholique de Louvain, Belgium
> >
> >
> > 2014-07-02 18:46 GMT+02:00 Bill Lorensen <bill.lorensen at gmail.com>:
> >
> >> Can you post a complete, compilable example that illustrates the error?
> >>
> >>
> >> On Wed, Jul 2, 2014 at 12:11 PM, Nicolas Gallego <nicgallego at gmail.com>
> >> wrote:
> >> > Hi,
> >> >
> >> > I wrote a program that performs an inner product opperation between a
> >> > neighborhood and a kernel.
> >> >
> >> > typedef itk::ConstNeighborhoodIterator< ImageType >
> >> > NeighborhoodIteratorType;
> >> > typedef itk::ImageKernelOperator< TPixel, Dimension > OperatorType;
> >> >
> >> > But when I change the boundary condition as in example [1] as
> >> >
> >> > typedef itk::ConstantBoundaryCondition< ImageType >
> >> > BoundaryConditionType;
> >> > typedef itk::ConstNeighborhoodIterator< ImageType,
> BoundaryConditionType
> >> > >
> >> > NeighborhoodIteratorType;
> >> > typedef itk::ImageKernelOperator< TPixel, Dimension > OperatorType;
> >> >
> >> > I get the following compilation error ( windows 7, itk 4.5, compiler
> cl
> >> > Version 16.00.40219.01 for x64, compilation type Debug)
> >> >
> >> >
> >> >
> -----------------------------------------------------------------------------------
> >> > erreur : C2664: 'float itk::NeighborhoodInnerProduct<TImage>::operator
> >> > ()(const itk::Neighborhood<TPixel,VDimension> &,const
> >> > itk::Neighborhood<TPixel,VDimension> &) const' : cannot convert
> >> > parameter 1
> >> > from 'NeighborhoodIteratorType' to 'const
> >> > itk::Neighborhood<TPixel,VDimension> &'
> >> > with
> >> > [
> >> >     TImage=itk::Image<PixelType,3>,
> >> >     TPixel=float,
> >> >     VDimension=3
> >> > ]
> >> > and
> >> > [
> >> >     TPixel=float,
> >> >     VDimension=3
> >> > ]
> >> > Reason: cannot convert from 'NeighborhoodIteratorType' to 'const
> >> > itk::Neighborhood<TPixel,VDimension>'
> >> > with
> >> > [
> >> >     TPixel=float,
> >> >     VDimension=3
> >> > ]
> >> > No user-defined-conversion operator available that can perform this
> >> > conversion, or the operator cannot be called
> >> >
> >> >
> ----------------------------------------------------------------------------------------
> >> >
> >> > Refering to the context were the actual inner product is performed
> >> >
> >> > typename NeighborhoodInnerProduct< ImageType > innerProduct;
> >> >
> >> > typedef itk::ImageKernelOperator< TPixel, Dimension > OperatorType;
> >> >
> >> >
> >> > OperatorType imageOperator;
> >> >
> >> >         // image operator configuration
> >> >
> >> > for loop on image iterators
> >> >
> >> > outIt.Set( innerProduct( it, imageOperator) );
> >> >
> >> >
> >> > Any ideas about this issue?
> >> >
> >> > [1]
> >> >
> http://www.itk.org/Wiki/ITK/Examples/Iterators/ConstantBoundaryCondition
> >> >
> >> > Nicolás Gallego-Ortiz
> >> > Université catholique de Louvain, Belgium
> >> >
> >> > _______________________________________________
> >> > Community mailing list
> >> > Community at itk.org
> >> > http://public.kitware.com/mailman/listinfo/community
> >> >
> >>
> >>
> >>
> >> --
> >> Unpaid intern in BillsBasement at noware dot com
> >
> >
>
>
>
> --
> Unpaid intern in BillsBasement at noware dot com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/community/attachments/20140703/7b370296/attachment-0002.html>
-------------- next part --------------
#include <itkImage.h>
#include <itkNumericTraits.h>
#include <itkImageRegionIterator.h>
#include <itkNeighborhoodIterator.h>
#include <itkImageKernelOperator.h>
#include <itkNeighborhoodInnerProduct.h>
#include <itkConstantBoundaryCondition.h>

int main()
{
    typedef float PixelType;
    const unsigned int Dimension = 3;
    typedef itk::Image< PixelType, Dimension > ImageType;

    ImageType::Pointer data = ImageType::New();
    ImageType::RegionType region;
    ImageType::IndexType start;
    start.Fill(0);
    ImageType::SizeType size;
    size.Fill(32);
    region.SetIndex( start );
    region.SetSize( size );
    data->SetRegions( region );
    data->Allocate();
    data->FillBuffer( 1.0f );

    // Build kernel
    double m_Sigma = 1.5;
    int sz =  itk::Math::Round< int, double>( m_Sigma * 5.0 );
    sz = sz + (1 -(sz % 2) );   // ensure odd sized filter
    int rd = sz / 2;
    std::cout << "kernel size: " << sz << " radius: " << rd << std::endl;

    std::vector< ImageType::PixelType > kernelValues( sz );
    double sigma2 = 2 * m_Sigma * m_Sigma;
    double sum = 0.0;
    std::cout << "unormalized kernel " << std::endl;
    for (unsigned int i = 0; i < sz; i++ ) {
        double u2 = (i - rd)*(i - rd);
        kernelValues[i] = std::exp( -u2 / sigma2 );
        sum += kernelValues[i];
        std::cout << kernelValues[i] << " ";
    }
    std::cout << std::endl;
    std::cout << "sum = " << sum << std::endl;
    std::cout << "normalized kernel " << std::endl;
    for (unsigned int i = 0; i < sz; i++ ) {
        kernelValues[i] /= sum;
        std::cout << kernelValues[i] << " ";
    }
    std::cout << std::endl;

    ImageType::Pointer kernelImage = ImageType::New();
    ImageType::RegionType kernelRegion;
    ImageType::SizeType kernelSize;
    kernelSize.Fill(1);
    kernelSize[0] = sz;
    ImageType::IndexType kernelStart;
    kernelStart.Fill(0);
    kernelRegion.SetIndex( kernelStart );
    kernelRegion.SetSize( kernelSize );
    kernelImage->SetRegions( kernelRegion );
    kernelImage->Allocate();
    std::cout << "copied values: " << std::endl;

    typedef itk::ImageRegionIterator< ImageType >   ImageIteratorType;
    ImageIteratorType kIt( kernelImage, kernelRegion );
    std::vector< ImageType::PixelType >::const_iterator vIt = kernelValues.begin();
    for( kIt.GoToBegin();
         !kIt.IsAtEnd();
         ++kIt, vIt++ ) {
        kIt.Set( *vIt );
        std::cout << *vIt << " ";
    }
    std::cout << std::endl;

    // FIXME, here compilation issue when specifiying boundary condition

    // neighborhood iterator and operator
    typedef itk::ConstantBoundaryCondition< ImageType >  BoundaryConditionType;
//    typedef itk::ConstNeighborhoodIterator< ImageType, BoundaryConditionType >     NeighborhoodIteratorType;
    typedef itk::ConstNeighborhoodIterator< ImageType >     NeighborhoodIteratorType;

    ImageType::SizeType radius;
    radius.Fill(0);
    radius[0] = rd;
    NeighborhoodIteratorType it( radius, data, region );

    // FIX. Override boundary condition at run time
    itk::ConstantBoundaryCondition< ImageType >*  constantBoundaryCondition = new itk::ConstantBoundaryCondition< ImageType >();
    constantBoundaryCondition->SetConstant( ImageType::PixelType( 0.0f ) );

    it.OverrideBoundaryCondition( constantBoundaryCondition );

    ImageType::Pointer outdata = ImageType::New();
    outdata->SetRegions( region );
    outdata->Allocate();

    ImageIteratorType outIt( outdata, region );

    typedef itk::ImageKernelOperator< PixelType, Dimension >  OperatorType;
    OperatorType imageOperator;
    imageOperator.SetImageKernel( kernelImage );
    imageOperator.SetDirection( 0 );
    imageOperator.CreateDirectional();
    std::cout << "imageOperator " << imageOperator << std::endl;

    itk::NeighborhoodInnerProduct< ImageType > innerProduct;

    for ( it.GoToBegin(), outIt.GoToBegin();
          !it.IsAtEnd();
          ++it, ++outIt ) {

        outIt.Set( innerProduct(it, imageOperator ) );
    }
    delete constantBoundaryCondition;

    std::cout << "outdata " << outdata << std::endl;
    return 0;
}
-------------- next part --------------
PROJECT(test)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

FIND_PACKAGE(ITK)
IF(ITK_FOUND)
    INCLUDE(${ITK_USE_FILE})
ELSE(ITK_FOUND)
    MESSAGE(FATAL_ERROR
            "ITK not found. Please set ITK_DIR.")
ENDIF(ITK_FOUND)

ADD_EXECUTABLE( boundaryConditionTest boundaryConditionTest.cxx )
TARGET_LINK_LIBRARIES( boundaryConditionTest ${ITK_LIBRARIES} )


More information about the Community mailing list