[Insight-users] RE: Problem with HistogramType::ConstIterator inside function

Benjamin King king.benjamin at mh-hannover.de
Thu, 12 Feb 2004 09:04:01 +0100


------------kcurxnQGudjR5JiIi4EeBw
Content-Type: text/plain; format=flowed; charset=iso-8859-15
Content-Transfer-Encoding: 8bit

Hello Radhika,

most of the error messages you got stem from implicit typenames. A quick 
fix is to visit each line number and add the 'typename' keyword in front 
of the type you find there. I did that for the file you sent and hope that 
it works.
And to explain gcc's behavior, see the following code:

   const int i = 3;

   template <class mysterious>
   void f() { mysterious::whatIsThis i; }

   template <class mysterious>
   void g() { mysterious::whatIsThis = i; }

   struct typeForF
   { typedef int whatIsThis; };

   struct typeForG
   { static int whatIsThis; };
   int typeForG::whatIsThis = 0;

f() and g() look almost the same but actually they have very little in 
common - besides being totally useless that is =)

f() needs a template parameter that has defined a type called whatIsThis 
and instantiates a local variable i with it.
g() needs a template parameter with a static member variable called 
whatIsThis and assigns a global variable i to it.

gcc wants you to be more explicit about whether you want a type and you 
have to change f()'s definition to

   template <class mysterious>
   void f() { typename mysterious::whatIsThis i; }

This also holds if you do a chain of typedefs:

   template <class mysterious>
   void h()
   {
     typedef mysterious::andWhatIsThat MyFirstType;
     typedef MyFirstType::andWhatIsThis MySecondType;
     typedef MySecondType::youNeverKnow MyThirdType;

     MyThirdType::Pointer myVariable = MyThirdType::New();
   }

Is MyThirdType::Pointer a type or a variable? By it's usage (= implicitly) 
it certainly looks like a type, but to save you from harm, gcc requires 
you to be explicit every time you want to access a type member that 
somehow depends on the template parameter:

   template <class mysterious>
   void h()
   {
     typedef typename mysterious::andWhatIsThat MyFirstType;
     typedef typename MyFirstType::andWhatIsThis MySecondType;
     typedef typename MySecondType::youNeverKnow MyThirdType;

     typename MyThirdType::Pointer myVariable = MyThirdType::New();
   }

Hope that helps,
   Benjamin


On Wed, 11 Feb 2004 14:39:29 -0800, Radhika Sivaramakrishna 
<radhika.sivaramakrishna at synarc.com> wrote:

> Hi Luis,
> You are the first person I know who looked through 145 lines of error so
> quickly and actually appeared to be enjoying the task.
> Well, unfortunately, the suggestion did not work. First of all, line 37 
> has
> no typedef in it. But it references line 26 where I put in a typename but
> that did not work. Also I have used MaskImageFilter through a function
> before and have not had this problem, so I added in typename for the
> HistogramGenerator and that also did not work.
>
[...]
>
> I have attached just the HistogramThreshold.txx with this email (with the
> histogram stuff commented out).
>
> Thanks
> Radhika


-- 
Benjamin King
Institut für Medizinische Informatik
Medizinische Hochschule Hannover
Tel.: +49  511  532-2663
------------kcurxnQGudjR5JiIi4EeBw
Content-Disposition: attachment; filename=HistogramThreshold.txx
Content-Type: application/octet-stream; name=HistogramThreshold.txx
Content-Transfer-Encoding: 8bit

template <class PixelType>
void HistogramThreshold(const itk::Image< PixelType, 3> * image,
            itk::Image< PixelType, 3> * mask)
{


  typedef int                 IntType;
  const unsigned int          Dimension = 3;

  typedef typename itk::Image<PixelType, Dimension > ImageType;
  typedef itk::Image<IntType, Dimension > IntImageType;

  typedef itk::ImageFileReader< ImageType > ReaderType;
  typedef itk::ImageFileWriter< ImageType > WriterType;
  typedef typename itk::MaskImageFilter<ImageType,ImageType,ImageType> MaskFilterType;
  typedef itk::BinaryThresholdImageFilter<ImageType, ImageType> BinaryThresholdFilterType;
  typedef itk::ImageRegionConstIteratorWithIndex< ImageType > ConstIteratorType;
  typedef itk::ImageRegionIteratorWithIndex< ImageType > IteratorType;

  typedef itk::BinaryBallStructuringElement<
                        PixelType,
                        Dimension  >             StructuringElementType;

  typedef itk::BinaryErodeImageFilter<
                              ImageType,
                              ImageType,
                              StructuringElementType>  ErodeFilterType;

  typedef itk::BinaryDilateImageFilter<
                              ImageType,
                              ImageType,
                            StructuringElementType >  DilateFilterType;

  typedef itk::ConnectedComponentImageFilter<ImageType,IntImageType > CCFilterType;
  typedef itk::RelabelComponentImageFilter<IntImageType,ImageType > RCFilterType;

  typename MaskFilterType::Pointer masker = MaskFilterType::New();
  typename BinaryThresholdFilterType::Pointer thresholdermask = BinaryThresholdFilterType::New();

  typename ReaderType::Pointer readerimage = ReaderType::New();
  typename ReaderType::Pointer readermask = ReaderType::New();
  typename WriterType::Pointer writer = WriterType::New();
  typename CCFilterType::Pointer ccfilter = CCFilterType::New();
  typename RCFilterType::Pointer rcfilter = RCFilterType::New();
  typename ErodeFilterType::Pointer  binaryErode  = ErodeFilterType::New();
  typename DilateFilterType::Pointer binaryDilate = DilateFilterType::New();

  StructuringElementType structuringElement;

  // Constants  

  PixelType background =   0;
  PixelType foreground = 255;
  unsigned int NumberOfBins = 128;
  float MarginalScale = 10.0;


  structuringElement.SetRadius( 1 );  // 3x3 structuring element

  structuringElement.CreateStructuringElement();

  binaryErode->SetKernel(  structuringElement );
  binaryDilate->SetKernel( structuringElement );
  binaryErode->SetErodeValue(foreground);
  binaryDilate->SetDilateValue(foreground);

  thresholdermask->SetOutsideValue( background );
  thresholdermask->SetInsideValue(  foreground );

  typedef typename itk::Statistics::ScalarImageToHistogramGenerator<
                                                    ImageType
                                                          >   HistogramGeneratorType;

  typename HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New();

  masker->SetInput1(image);
  masker->SetInput2(mask);
  masker->Update();

  histogramGenerator->SetInput(  masker->GetOutput() );

  histogramGenerator->SetNumberOfBins( NumberOfBins );
  histogramGenerator->SetMarginalScale( MarginalScale );
  histogramGenerator->Compute();

  typedef typename HistogramGeneratorType::HistogramType  HistogramType;

  const HistogramType * histogram = histogramGenerator->GetOutput();

  const unsigned int histogramSize = histogram->Size();

  std::cout << "Histogram size " << histogramSize << std::endl;

 /* typename HistogramType::ConstIterator itr = histogram->Begin();
  typename HistogramType::ConstIterator end = histogram->End();

  unsigned int bin = 1;
  float totalhist = 0;
  ++itr; // To skip the zero count
  while( itr != end )
      {
    //  std::cout << "bin = " << bin << " frequency = ";
    //  std::cout << itr.GetFrequency() << std::endl;
      totalhist += itr.GetFrequency();
      ++itr;
      ++bin;
      }
  std::cout << " Total " << totalhist << std::endl;
 // std::cout << " Total frequency " << histogram->GetTotalFrequency() << std::endl;
//  std::cout << " Quantile at 90th percentile " << histogram->Quantile(0,0.90) << std::endl;

  float probability = 0;
  unsigned int threshold;
  bin=1;
  itr = histogram->Begin();
  ++itr; // To skip the zero count
  while( (itr != end) && (probability <= 0.90*totalhist ))
      {
      std::cout << "bin = " << bin << " frequency = ";
      probability += itr.GetFrequency();
      std::cout << probability << std::endl;
      threshold = bin*2;
      ++itr;
      ++bin;
      }

  std::cout << " Threshold value " << threshold << std::endl;
  std::cout << " Probability value " << probability << std::endl; */
  unsigned int threshold = 255;
  typename ImageType::RegionType region = image->GetBufferedRegion();
  IteratorType maskit(mask,region);
  ConstIteratorType gsit(image,region);

  gsit.GoToBegin();
  maskit.GoToBegin();
  while( ! gsit.IsAtEnd() && ! maskit.IsAtEnd())
    {
  	if (gsit.Get() > threshold)
  	{
  		maskit.Set(0);
  	}
  	++maskit;
  	++gsit;
  }

  binaryErode->SetInput(mask);
  ccfilter->SetInput(binaryErode->GetOutput());
  rcfilter->SetInput(ccfilter->GetOutput());
  rcfilter->Update();
  thresholdermask->SetInput( rcfilter->GetOutput() );
  thresholdermask->SetLowerThreshold( 1 );
  thresholdermask->SetUpperThreshold( 1 );
  binaryDilate->SetInput(thresholdermask->GetOutput());
  binaryDilate->Update();

// Copying result back into the pointer sent from main (mask)

  typename ImageType::Pointer temp = binaryDilate->GetOutput();

  ConstIteratorType tempit(temp,region);  
  tempit.GoToBegin();
  maskit.GoToBegin();
  while( ! maskit.IsAtEnd() && ! tempit.IsAtEnd() )
  {
	maskit.Set(tempit.Get());
	++tempit;
	++maskit;
  } 
 

}




------------kcurxnQGudjR5JiIi4EeBw--