nm97  
                
                  
                    July 3, 2019, 10:54am
                   
                  1 
               
             
            
              How can I specify image channels.
        using ImageType = itk::Image< uint8_t, 2 >;
        ImageType::Pointer image = ImageType::New();
        ImageType::SizeType  size;
        size[0] = width;
        size[1] = height;
        ImageType::IndexType start;
        start.Fill( 0 );
        ImageType::RegionType region;
        region.SetSize( size );
        region.SetIndex( start );
        image->SetRegions( region );
        image->Allocate();
I can specify size, start but could not find in documentation how to specify image channels.
             
            
              
            
           
          
            
              
                dzenanz  
              
                  
                    July 3, 2019,  2:30pm
                   
                  2 
               
             
            
              You just have to define vector image type.
using VectorPixelType = itk::Vector<uint8_t, 10>; // 10 channel pixel
using ImageType = itk::Image< VectorPixelType, 2 >; // 2D image
Read more about it in the software guide , section 4.1.6.
             
            
              
            
           
          
            
              
                nm97  
              
                  
                    July 3, 2019,  2:57pm
                   
                  3 
               
             
            
              Thank you very much for quick response.
In that case I get an error in this line
  rescaler->SetOutputMaximum( 255 );
  rescaler->SetOutputMinimum( 0 );
 error: conversion from āintā to āitk::RescaleIntensityImageFilter<itk::Image<itk::Vector<float, 3>, 2>, itk::Image<itk::Vector<unsigned char, 3>, 2> >::OutputPixelTypeā {aka āitk::Vector<unsigned char, 3>ā} is ambiguous
  180 |         rescaler->SetOutputMinimum(   0 );
 
            
              
            
           
          
            
            
              These methods expect arguments of same type as the pixels in your image. Since the pixel in your image is a vector (aka multi-channel image), you should input a vector.
Giving only one value is ambiguous, i.e. in which channel should the value goes ? first? all?
itk::Vector<uint8_t, 3> MaxPixel, MinPixel;
MaxPixel[0] = MaxPixel[1] = MaxPixel[2] = 255;
MinPixel[0] = MinPixel[1] = MinPixel[2] = 0;
rescaler->SetOutputMaximum( MaxPixel );
rescaler->SetOutputMinimum( MinPixel );
HTH,
Tim
             
            
              1 Like 
            
            
           
          
            
              
                nm97  
              
                  
                    July 3, 2019,  4:50pm
                   
                  5 
               
             
            
              In that case I get an error in the last line
        using VectorPixelType = itk::Vector<uint8_t, 3>; // 10 channel pixel
        using ImageType = itk::Image< VectorPixelType, 2 >; // 2D image
        using OutputVectorPixelType = itk::Vector<float, 3>; 
        // using OutputPixelType = float;
        using OutputImageType = itk::Image< OutputVectorPixelType, 2 >;
        using FilterType = itk::MinMaxCurvatureFlowImageFilter< ImageType, OutputImageType >;
        FilterType::Pointer filter = FilterType::New();
 invalid static_cast from type āitk::Vector<unsigned char, 3>ā to type āfloatā
  185 |       auto b = static_cast< T2 >( a );
 
            
              
            
           
          
            
              
                dzenanz  
              
                  
                    July 3, 2019,  5:01pm
                   
                  6 
               
             
            
              I guess that MinMaxCurvatureFlowImageFilter does not support vector images. You might use SplitComponentsImageFilter  or VectorImageToImageAdaptor  to split the image into constituent channels, apply some processing on each channel independently, and combine them using ComposeImageFilter .
             
            
              1 Like 
            
            
           
          
            
              
                blowekamp  
              
                  
                    July 3, 2019,  5:28pm
                   
                  7 
               
             
            
              Here is a snippet of code generated in SimpleITK which run certain filters on a āper component basisā:
//
// Dispatched methods to call ExecuteInternal on each component of the VectorImage
//
template <class TImageType> Image BilateralImageFilter::ExecuteInternalVectorImage ( const Image& inImage1 )
{
  typedef TImageType                                                               VectorInputImageType;
  typedef typename VectorInputImageType::InternalPixelType                         ComponentType;
  typedef typename itk::Image<ComponentType, VectorInputImageType::ImageDimension> ComponentImageType;
  // we must define the input and output image types should be the
  // same as the scalar execute internal method
  typedef ComponentImageType  InputImageType;
  // Define output image type
  typedef InputImageType OutputImageType;
  // Get the pointer to the ITK image contained in image1
  typename VectorInputImageType::ConstPointer image1 =
    this->CastImageToITK<VectorInputImageType>( inImage1 );
  typedef itk::VectorIndexSelectionCastImageFilter< VectorInputImageType, ComponentImageType > ComponentExtratorType;
  typename ComponentExtratorType::Pointer extractor = ComponentExtratorType::New();
  extractor->SetInput( image1 );
  typedef itk::ComposeImageFilter<OutputImageType> ToVectorFilterType;
  typename ToVectorFilterType::Pointer toVector = ToVectorFilterType::New();
  unsigned int numComps = image1->GetNumberOfComponentsPerPixel();
  for ( unsigned int i = 0; i < numComps; ++i )
    {
    extractor->SetIndex( i );
    extractor->Update();
    Image tmp = this->ExecuteInternal<InputImageType>( Image( extractor->GetOutput() ) );
    typename OutputImageType::ConstPointer tempITKImage = this->CastImageToITK<OutputImageType>( tmp );
    toVector->SetInput( i, tempITKImage );
    }
  toVector->Update();
  return Image( toVector->GetOutput() );
}
 
            
              
            
           
          
            
              
                nm97  
              
                  
                    July 3, 2019,  5:44pm
                   
                  8 
               
             
            
              
Ok, but in InsightToolkit-5.0.0/Examples/Filtering/MinMaxCurvatureFlowImageFilter.cxx in this example input image has 3 channels and still it does not specify the number of channels.
             
            
              
            
           
          
            
              
                nm97  
              
                  
                    July 3, 2019,  6:02pm
                   
                  9 
               
             
            
              And one more question,MaxCurvatureFlowImageFilter does not support vector images how can I filter multi channel images without using vector? Because as I said in example there is no use of vector, but it filters fine
             
            
              
            
           
          
            
              
                dzenanz  
              
                  
                    July 3, 2019,  6:34pm
                   
                  10 
               
             
            
              Instead of itk::Vector<uint8_t, 3>, you might want to try itk::RGBPixel<uint8_t>.
In the example you mentioned, the pixel type is scalar = grayscale (float). If color image is supplied, the IO mechanism in ITK converts it to grayscale and the example deals with that afterwards.
             
            
              1 Like