[Insight-users] Help with GeodesicActiveContourImageFilter --> Modification to example code does not seem to work
Ella Maria Kadas
ella_kadas at yahoo.com
Thu Feb 10 19:05:59 EST 2011
--- Ella Maria Kadas <ella_kadas at yahoo.com> schrieb am Fr, 11.2.2011:
Von: Ella Maria Kadas <ella_kadas at yahoo.com>
Betreff: Re: [Insight-users] Help with GeodesicActiveContourImageFilter --> Modification to example code does not seem to work
An: "Vimal Singh" <vimal at mail.utexas.edu>
Datum: Freitag, 11. Februar, 2011 02:05 Uhr
Hi,
I am trying to use this filter for a plugin n Osirix for lesion detection in MRT images.
ItkImageImporter is a itk wrap for the dicom images read with Osirix.
And the seed point in taken from a mouse klick in the viewer from Osirix.
I already used the ConnectedThresholdFilter but i am not really satisfied with the results.
I also don;t really know how to retrieve from the writer the information to create Roi
For the Connected Threshold Filter i used
typedef float InternalPixelType;
typedef itk::Image< InternalPixelType, 3 > InternalImageType;
// Char Output image
typedef unsigned char OutputPixelType;
typedef itk::Image< OutputPixelType, 3 > OutputImageType;
// Type
Caster
typedef itk::CastImageFilter< InternalImageType, OutputImageType > CastingFilterType;
CastingFilterType::Pointer caster = CastingFilterType::New();
//.....
caster->SetInput(thresholdFilter->GetOutput()); // <- FLOAT TO CHAR
NSLog(@"RegionGrowing starts...");
try
{
caster->Update();
}
catch( itk::ExceptionObject & excep )
{
NSLog(@"RegionGrowing failed...");
}
NSLog(@"Done...");
//...
unsigned char *buff = caster->GetOutput()->GetBufferPointer();
ROI *theNewROI = [[ROI alloc] initWithTexture:buff
textWidth:buffWidth
textHeight:buffHeight
textName:newname
positionX:0
positionY:0
spacingX:[[[srcViewer imageView] curDCM] pixelSpacingX]
spacingY:[[[srcViewer imageView] curDCM] pixelSpacingY]
imageOrigin:NSMakePoint([[[srcViewer imageView] curDCM] originX], [[[srcViewer imageView] curDCM] originY])];
The code is for GeodesicActiveContours is :
@implementation ActiveContours
- (id) initWith :(ViewerController*) v :(int) slice {
if (self = [super init])
{
itkImage = [[Importer alloc]Create:[v pixList] slice:slice volume:[v volumePtr]];
}
return self;
}
-(void) dealloc
{
[itkImage release];
[super dealloc];
}
- (void) ActiveContour3D:(ViewerController *)sourceV :(int)slice :(NSPoint)startingPoint :(NSString*)newname
{
typedef float InternalPixelType;
const unsigned int Dimension = 3;
typedef itk::Image< InternalPixelType, Dimension > InternalImageType;
typedef itk::OrientedImage< PixelType, Dimension > ImageType;
typedef itk::ImageSeriesReader< ImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
typedef itk::GDCMImageIO ImageIOType;
ImageIOType::Pointer dicomIO = ImageIOType::New();
reader->SetImageIO( dicomIO );
typedef unsigned char OutputPixelType;
typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
typedef itk::BinaryThresholdImageFilter<
InternalImageType,
OutputImageType > ThresholdingFilterType;
ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
//I supose here is the problem in settin the lower and Upper threshold for thresholder. the timestep=upperThreshold
//in the userGuide should come from the fastmarching Filter??????
thresholder->SetLowerThreshold( -1000.0
);
thresholder->SetUpperThreshold( 0.0 );
thresholder->SetOutsideValue( 0 );
thresholder->SetInsideValue( 255 );
//typedef itk::ImageFileReader< InternalImageType > ReaderType;
typedef itk::GDCMImageIO ImageIOType;
ImageIOType::Pointer gdcmImageIO = ImageIOType::New();
typedef itk::VTKImageIO VTKIOType;
VTKIOType::Pointer vtkIO = VTKIOType::New();
typedef itk::GiplImageIO GiplIOType;
GiplIOType::Pointer giplIO = GiplIOType::New();
typedef itk::ImageFileWriter< OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
char *name =
"volume_dataset";
writer->SetFileName(name);
writer->SetImageIO(gdcmImageIO);
typedef itk::RescaleIntensityImageFilter<InternalImageType,OutputImageType > CastFilterType;
typedef itk::CurvatureAnisotropicDiffusionImageFilter<InternalImageType,InternalImageType > SmoothingFilterType;
SmoothingFilterType::Pointer smoothing = SmoothingFilterType::New();
typedef itk::GradientMagnitudeRecursiveGaussianImageFilter<InternalImageType,InternalImageType > GradientFilterType;
typedef itk::SigmoidImageFilter<InternalImageType,InternalImageType > SigmoidFilterType;
GradientFilterType::Pointer gradientMagnitude = GradientFilterType::New();
SigmoidFilterType::Pointer sigmoid =
SigmoidFilterType::New();
sigmoid->SetOutputMinimum( 0.0 );
sigmoid->SetOutputMaximum( 1.0 );
typedef itk::FastMarchingImageFilter<InternalImageType,InternalImageType > FastMarchingFilterType;
FastMarchingFilterType::Pointer fastMarching = FastMarchingFilterType::New();
typedef itk::GeodesicActiveContourLevelSetImageFilter< InternalImageType,InternalImageType > GeodesicActiveContourFilterType;
GeodesicActiveContourFilterType::Pointer geodesicActiveContour = GeodesicActiveContourFilterType::New();
const double propagationScaling = 3.0;
geodesicActiveContour->SetPropagationScaling(propagationScaling);
geodesicActiveContour->SetCurvatureScaling(2.0);
geodesicActiveContour->SetAdvectionScaling( 3.0 );
geodesicActiveContour->SetMaximumRMSError( 0.02 );
geodesicActiveContour->SetNumberOfIterations( 3 );
smoothing->SetInput([itkImage itkImporter]->GetOutput() );
gradientMagnitude->SetInput( smoothing->GetOutput() );
sigmoid->SetInput( gradientMagnitude->GetOutput() );
geodesicActiveContour->SetInput( fastMarching->GetOutput() );
geodesicActiveContour->SetFeatureImage( sigmoid->GetOutput() );
thresholder->SetInput( geodesicActiveContour->GetOutput() );
writer->SetInput( thresholder->GetOutput() );
smoothing->SetTimeStep( 0.0625 );
smoothing->SetNumberOfIterations( 10 );
smoothing->SetConductanceParameter( 1.0 );
const double sigma = 1.0;
gradientMagnitude->SetSigma( sigma );
const double alpha = -4.0;
const double beta = 0.0;
sigmoid->SetAlpha( alpha );
sigmoid->SetBeta( beta );
typedef FastMarchingFilterType::NodeContainer NodeContainer;
typedef FastMarchingFilterType::NodeType NodeType;
InternalImageType::IndexType index;
index[0] = (long) startingPoint.x;
index[1] = (long)
startingPoint.y;
if(slice == -1) index[2] = [[sourceV imageView] curImage];
else index[2] = 0;
NSLog(@"StartingPoint is %d %d %d", index[0],index[1],index[2]);
NodeContainer::Pointer seeds = NodeContainer::New();
double initialDistance = 5.0;
double seedValue = -initialDistance;
NodeType node;
node.SetValue(seedValue);
node.SetIndex(index);
seeds->Initialize();
seeds->InsertElement(0,node);
fastMarching->SetTrialPoints(seeds);
fastMarching->SetSpeedConstant(1.0);
const double stoppingTime = 10.0;
fastMarching->SetStoppingValue( stoppingTime );
CastFilterType::Pointer caster1 = CastFilterType::New();
CastFilterType::Pointer caster2 = CastFilterType::New();
CastFilterType::Pointer caster3 = CastFilterType::New();
CastFilterType::Pointer caster4 = CastFilterType::New();
WriterType::Pointer writer1 = WriterType::New();
WriterType::Pointer writer2 = WriterType::New();
WriterType::Pointer writer3 = WriterType::New();
WriterType::Pointer writer4 = WriterType::New();
caster1->SetInput( smoothing->GetOutput() );
writer1->SetInput( caster1->GetOutput() );
char *name1 =
"smoothed_dataset";
writer1->SetFileName(name1);
caster1->SetOutputMinimum( 0 );
caster1->SetOutputMaximum( 255 );
writer1->SetImageIO(giplIO);
try{
writer1->Update();
}
catch( itk::ExceptionObject & excep ){
NSLog(@ "Exception caught at writer1!");
}
caster2->SetInput( gradientMagnitude->GetOutput() );
writer2->SetInput( caster2->GetOutput() );
char *name2 = "3DKanten";
writer2->SetFileName(name2);
caster2->SetOutputMinimum( 0 );
caster2->SetOutputMaximum( 255
);
writer2->SetImageIO(giplIO);
try{
writer2->Update();
}
catch( itk::ExceptionObject & excep ){
NSLog(@"Exceptionin writer2");
}
caster3->SetInput( sigmoid->GetOutput() );
writer3->SetInput( caster3->GetOutput() );
char *name3 = "inverse3DKanten";
writer3->SetFileName(name3);
caster3->SetOutputMinimum( 0 );
caster3->SetOutputMaximum( 255 );
writer3->SetImageIO(giplIO);
try{
writer3->Update();
}
catch( itk::ExceptionObject & excep
){
NSLog(@"Exception caught at writer3 !");
}
caster4->SetInput( fastMarching->GetOutput() );
writer4->SetInput( caster4->GetOutput() );
char *name4 = "FFM";
writer4->SetFileName(name4);
caster4->SetOutputMinimum( 0 );
caster4->SetOutputMaximum( 255 );
writer4->SetImageIO(giplIO);
try{
writer4->Update();
NSLog(@"FMIF: GetOutputSize: ");
}
catch( itk::ExceptionObject & excep ){
NSLog(@"Exception caught at
writer4!");
}
NSLog(@"I am here already will go further");
try
{
writer->Update();
}
catch( itk::ExceptionObject & excep )
{
NSLog(@"Exception caught at main writer!");
}
NSLog(@"DOOOOOONNNNNNEEEEEE");
/* if( slice == -1)
{
unsigned char *buff =
writer->GetOutput()->GetBufferPointer();
if( buff)
{
for( int i = 0; i < [[sourceV pixList] count]; i++)
{
int buffHeight = [[[sourceV pixList] objectAtIndex: i] pheight];
int buffWidth = [[[sourceV pixList] objectAtIndex: i] pwidth];
if( memchr( buff, 255, buffWidth * buffHeight))
{
ROI *theNewROI = [[ROI alloc] initWithTexture:buff
textWidth:buffWidth
textHeight:buffHeight
textName:newname
positionX:0
positionY:0
spacingX:[[[sourceV imageView] curDCM]
pixelSpacingX]
spacingY:[[[sourceV imageView] curDCM] pixelSpacingY]
imageOrigin:NSMakePoint([[[sourceV imageView] curDCM] originX], [[[sourceV imageView] curDCM] originY])];
NSLog(@"I am working wiht a ROI");
[[[sourceV roiList]
objectAtIndex:i] addObject:theNewROI];
[[NSNotificationCenter defaultCenter] postNotificationName: OsirixROIChangeNotification object:theNewROI userInfo: nil];
/*if( [newname isEqualToString: @"Segmentation Preview"])
{
RGBColor color;
color.red = 0.67*65535.;
color.green = 0.90*65535.;
color.blue = 0.58*65535.;
NSLog(@"I am preview in a slice -1");
[theNewROI setColor: color];
}
else {*/
/* RGBColor roiColor;
roiColor.red = 0.20 * 65535;
roiColor.blue = 0.50 * 65535;
roiColor.green = 0.50 * 65535;
[theNewROI setColor: roiColor];
//}
[theNewROI setROIMode: ROI_selected];
[[NSNotificationCenter defaultCenter] postNotificationName: OsirixROISelectedNotification object:theNewROI userInfo: nil];
[theNewROI setSliceThickness:[[[sourceV imageView] curDCM] sliceThickness]];
[theNewROI release];
}
buff+= buffHeight*buffWidth;
}
}
}
else
{
// result of the segmentation will only contain one slice.
NSLog(@"Result conteins only one slide");
unsigned char *buff = caster->GetOutput()->GetBufferPointer();
//NSLog(@"buff ISSSSS %c",buff);
if(buff) NSLog(@"The buffer is not nill");
int buffHeight =
[[[sourceV pixList] objectAtIndex: 0] pheight];
int buffWidth = [[[sourceV pixList] objectAtIndex: 0] pwidth];
ROI *theNewROI = [[ROI alloc] initWithTexture:buff
textWidth:buffWidth
textHeight:buffHeight
textName:newname
positionX:0
positionY:0
spacingX:[[[sourceV imageView] curDCM] pixelSpacingX]
spacingY:[[[sourceV imageView] curDCM] pixelSpacingY]
imageOrigin:NSMakePoint([[[sourceV imageView] curDCM] originX], [[[sourceV imageView] curDCM] originY])];
[theNewROI reduceTextureIfPossible];
[theNewROI setSliceThickness:[[[sourceV imageView] curDCM] sliceThickness]];
[[[sourceV roiList] objectAtIndex:slice] addObject:theNewROI];
[[sourceV imageView] roiSet];
[[NSNotificationCenter defaultCenter] postNotificationName: OsirixROIChangeNotification object:theNewROI userInfo: nil];
/*if( [newname isEqualToString: @"Segmentation Preview"])
{
NSLog(@"I am actually in a preview");
RGBColor color;
color.red = 0.67*65535.;
color.green = 0.90*65535.;
color.blue = 0.58*65535.;
[theNewROI setColor: color];
}*/
//else{
/*RGBColor roiColor;
roiColor.red = 0.20 * 65535;
roiColor.blue = 0.50 * 65535;
roiColor.green = 0.50 * 65535;
[theNewROI setColor: roiColor];
//}
[theNewROI setROIMode: ROI_selected];
[[NSNotificationCenter defaultCenter] postNotificationName: OsirixROISelectedNotification object:theNewROI userInfo: nil];
[theNewROI release];
}
[sourceV needsDisplayUpdate];*/
}
@end
Thanks,
Ella
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20110211/f29687fe/attachment.htm>
More information about the Insight-users
mailing list