[Insight-users] itkConnectedThresholdFilter: all initial seeds being tested.

Luis Ibanez luis.ibanez@kitware.com
Wed, 30 Apr 2003 17:47:22 -0400


This is a multi-part message in MIME format.
--------------060501090502050303080407
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit


Hi Haydar,

Thanks for taking the time of preparing the test.

I added print outs to the test and actually all the seeds are
being retained on the output image. So, the FloodFill iterator
is working just as expected.  Your impression that not all seed
points where present in the output maybe the consequence of
poor visualization.

Note that all the seeds in your test satisfied the acceptance
criterion. If by any chance, one of the initial seed does not
satisfy the criterion, it will not be added to the output image.


Please find attached the modified version of your .cxx file
along with the CMakeLists.txt files used to build it.


Here is the output I got for your test image


    Seed    |Input|Output

Loading file
[100, 130] = 1405 = 1
[100, 131] = 1416 = 1
[100, 132] = 1428 = 1
[100, 133] = 1449 = 1
[100, 134] = 1403 = 1
[100, 135] = 1432 = 1
[100, 136] = 1418 = 1
[100, 137] = 1402 = 1
[100, 138] = 1431 = 1
[100, 139] = 1436 = 1
[100, 140] = 1466 = 1
[100, 141] = 1457 = 1
[100, 142] = 1434 = 1
[100, 143] = 1544 = 1
[100, 144] = 1466 = 1
[100, 145] = 1452 = 1
[101, 131] = 1407 = 1
[101, 132] = 1427 = 1
[101, 133] = 1384 = 1
[101, 134] = 1356 = 1
[101, 135] = 1416 = 1
[101, 136] = 1407 = 1
[101, 137] = 1404 = 1
[101, 138] = 1391 = 1
[101, 139] = 1377 = 1
[101, 140] = 1390 = 1
[101, 141] = 1375 = 1
[101, 142] = 1408 = 1
[101, 143] = 1428 = 1
[101, 144] = 1413 = 1
[101, 145] = 1449 = 1
[101, 146] = 1466 = 1
[101, 147] = 1524 = 1
[102, 131] = 1384 = 1
[102, 132] = 1361 = 1
[102, 133] = 1334 = 1
[102, 134] = 1345 = 1
[102, 135] = 1358 = 1
[102, 136] = 1422 = 1
[102, 137] = 1413 = 1
[102, 138] = 1367 = 1
[102, 139] = 1358 = 1
[102, 140] = 1363 = 1
[102, 141] = 1358 = 1
[102, 142] = 1386 = 1
[102, 143] = 1411 = 1
[102, 144] = 1397 = 1
[102, 145] = 1432 = 1
[102, 146] = 1412 = 1
[102, 147] = 1460 = 1


----

BTW, in your code you are opening the namespaces.
this is a pretty bad practice. You should have some

    using namespace std;
    using namespace itk;

somewhere in your headers. Please remove these lines.
They destroy the whole purpose of having namespaces in C++.


Also, avoid declaring SmartPointers as global variables,
you may as well put them inside the main(), as it is
done in the attached modified file.


Regards,


    Luis


----------------------
Haydar Talib wrote:
> Hi Luis, here is a test case where the seeds are not included in the 
> final connected threshold image although they do indeed satisfy the 
> threshold criteria. Attached are my test image, source code, as well as 
> a screen capture of the output I got from running my code. Let me know 
> what you think!
> Regards,
> Haydar Talib
> MEMCenter
> 
> 
> 
> 
> 
> 
>> From: Luis Ibanez <luis.ibanez@kitware.com>
>> To: Haydar Talib <haydartalib@hotmail.com>
>> CC: insight-users@public.kitware.com
>> Subject: Re: [Insight-users] itkConnectedThresholdFilter
>> Date: Thu, 24 Apr 2003 20:22:59 -0400
>> MIME-Version: 1.0
>> Received: from ms-smtp-01.nyroc.rr.com ([24.92.226.148]) by 
>> mc3-f32.law16.hotmail.com with Microsoft SMTPSVC(5.0.2195.5600); Thu, 
>> 24 Apr 2003 17:23:18 -0700
>> Received: from kitware.com (alb-24-194-241-249.nycap.rr.com 
>> [24.194.241.249])by ms-smtp-01.nyroc.rr.com (8.12.5/8.12.2) with ESMTP 
>> id h3P0NEGm020710;Thu, 24 Apr 2003 20:23:14 -0400 (EDT)
>> X-Message-Info: JGTYoYF78jEHjJx36Oi8+Q1OJDRSDidP
>> Message-ID: <3EA87FE3.1020401@kitware.com>
>> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.0.2) 
>> Gecko/20021216
>> X-Accept-Language: en-us, en
>> References: <Sea2-F27atd4gmSknvh000068ba@hotmail.com>
>> Return-Path: luis.ibanez@kitware.com
>> X-OriginalArrivalTime: 25 Apr 2003 00:23:19.0593 (UTC) 
>> FILETIME=[DF7BB190:01C30AC0]
>>
>>
>> Hi Haydar,
>>
>> The  FloodFilledFunctionConditionalConstIterator test the
>> seed point for the threshold condition. If they pass the
>> test, the seeds are included in the region, but if they
>> fail the test, the seeds will not be part of the final region.
>>
>> Are you certain that the seeds you are providing satisfy
>> the condition of their intensities being between the lower
>> and upper threshold that you provide to the ConnectedThreshold
>> filter.
>>
>> Could you provide a minimal test case in which this behavior
>> is failing ?
>>
>> Thanks
>>
>>
>>     Luis
>>
>>
>> --------------
>>
>> Haydar Talib wrote:
>>
>>> This question has been beating down on me for a while,
>>> but does anyone know why the ConnectedThresholdFilter does not 
>>> include the seed pixels in its output image? Looking closely at 
>>> FloodFilledFunctionConditionalConstIterator::DoFloodStep() it seems 
>>> that the seeds should be included. But they are not. Thanks!
>>> --Haydar
>>>
>>>
>>
> 
> 
> _________________________________________________________________
> Tired of spam? Get advanced junk mail protection with MSN 8.  
> http://join.msn.com/?page=features/junkmail
> 
> ------------------------------------------------------------------------
> 



--------------060501090502050303080407
Content-Type: text/plain;
 name="CMakeLists.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="CMakeLists.txt"

# This project is designed to be built outside the Insight source tree.
PROJECT(ConnectedTest)

# Find ITK.
FIND_PACKAGE(ITK)
IF(ITK_FOUND)
  INCLUDE(${ITK_USE_FILE})
ELSE(ITK_FOUND)
  MESSAGE(FATAL_ERROR
          "Cannot build without ITK.  Please set ITK_DIR.")
ENDIF(ITK_FOUND)

ADD_EXECUTABLE(ConnectedTest itkConnectedTest.cxx )

TARGET_LINK_LIBRARIES(ConnectedTest ITKIO ITKBasicFilters ITKCommon)


--------------060501090502050303080407
Content-Type: text/plain;
 name="itkConnectedTest.cxx"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="itkConnectedTest.cxx"

/*=========================================================================

  Program:   Haydar Talib, MEMCenter, taken from Insight S & R Toolkit
  =======================================================================*/

#include <vector> 
#include <iostream>
#include <string>

#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkSize.h>

#include <itkConnectedThresholdImageFilter.h>


int main(int argc, const char* argv[])
{
   if ( argc < 2 )
       {
         std::cout<< "usage: "<< argv[0]<< std::endl
             << "  infile"<< std::endl;
         exit(0);
       }
     
     std::string fileName( argv[1] );


typedef short ImagePixelType;
typedef itk::Image<ImagePixelType,2> ImageType;
typedef unsigned char BinaryImagePixelType;
typedef itk::Image<BinaryImagePixelType,2> BinaryImageType;

ImageType::Pointer image;
BinaryImageType::Pointer outImage;

typedef itk::ImageFileReader<ImageType> VolumeReaderType;
VolumeReaderType::Pointer imageReader= VolumeReaderType::New();

typedef itk::ConnectedThresholdImageFilter<ImageType, BinaryImageType> connectedFilterType;




     std::cout<< "Loading file "<< std::endl;
     try
     {
       imageReader->SetFileName(fileName.c_str());
       imageReader->Update();
       image = imageReader->GetOutput();
     }
	 catch (itk::ExceptionObject & e)
     {
	   std::cout << e << std::endl;
       exit(0);
     }
     
     
  connectedFilterType::Pointer connectedFilter = connectedFilterType::New();
  connectedFilter->SetInput(image);

  connectedFilter->SetLower(1168); //Value obtained from previous Otsu calculation
  connectedFilter->SetUpper(2047);
  connectedFilter->SetReplaceValue(1);
  
  //Setting up the seed points
  connectedFilterType::IndexType seed;
  seed[0] = 100;
  seed[1] = 130;

  typedef std::vector< connectedFilterType::IndexType > SeedsContainer;
 
  SeedsContainer seeds;

  for (int n=0; n<50; n++)
    {
    if (n<=15)
      {
      seed[0] = 100;
      seed[1] = 130+n;
      connectedFilter->AddSeed(seed);
      seeds.push_back( seed );
      }
    if (n>=16 && n<=32)
      {
      seed[0] = 101;
      seed[1] = 115+n;
      connectedFilter->AddSeed(seed);
      seeds.push_back( seed );
      }
    if (n>=33 && n<=49)
      {
      seed[0] = 102;
      seed[1] = 98+n;
      connectedFilter->AddSeed(seed);
      seeds.push_back( seed );
      }
    }
      
  connectedFilter->Update();  
  outImage=connectedFilter->GetOutput();
         
  SeedsContainer::const_iterator  ss   = seeds.begin();
  SeedsContainer::const_iterator  send = seeds.end();
  
  while( ss != send )
    {
    std::cout << *ss << " = " << image->GetPixel( *ss );
    std::cout << " = " << static_cast<int>( outImage->GetPixel( *ss ) );
	std::cout << std::endl;
    ++ss;
    }
    
 
  return 0; 
}

--------------060501090502050303080407--