cmtkVoxelRegistrationImagePreprocessor.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include <Registration/cmtkVoxelRegistration.h>
00034 
00035 #include <System/cmtkCommandLine.h>
00036 
00037 #include <Base/cmtkTypedArrayFunctionHistogramEqualization.h>
00038 #include <Base/cmtkDataGridFilter.h>
00039 
00040 namespace
00041 cmtk
00042 {
00043 
00044 VoxelRegistration::ImagePreprocessor::ImagePreprocessor( const char* name, const char* key )
00045   : m_DataClassString( NULL ),
00046     m_DataClass( DATACLASS_GREY ),
00047     m_PaddingFlag( false ),
00048     m_PaddingValue( 0 ),
00049     m_LowerThresholdActive( false ),
00050     m_LowerThresholdValue( -CMTK_ITEM_MAX ),
00051     m_UpperThresholdActive( false ),
00052     m_UpperThresholdValue( CMTK_ITEM_MAX ),
00053     m_UsePruneHistogramBins( false ),
00054     m_PruneHistogramBins( 0 ),
00055     m_HistogramEqualization( false ),
00056     m_SobelFilter( false ),
00057     m_CropIndex( NULL ),
00058     m_CropWorld( NULL ),
00059     m_AutoCropFlag( false ),
00060     m_AutoCropLevel( 0 ),
00061     m_Name( name ),
00062     m_Key( key )
00063 {
00064 }
00065 
00066 void 
00067 VoxelRegistration::ImagePreprocessor::AttachToCommandLine
00068 ( CommandLine& cl )
00069 {
00070   char buffer[64];
00071   cl.BeginGroup( this->m_Name, strcat( strcpy( buffer, this->m_Name ), " Image Preprocessing" ) )->SetProperties( CommandLine::PROPS_NOXML );
00072   
00073   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "class-" ), this->m_Key ) ), &this->m_DataClassString, "Data class: grey (default) or label" );
00074   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "pad-" ), this->m_Key ) ), &this->m_PaddingValue, "Padding value", &this->m_PaddingFlag );
00075 
00076   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "thresh-min-" ), this->m_Key ) ), &this->m_LowerThresholdValue, "Minimum value truncation threshold", &this->m_LowerThresholdActive );
00077   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "thresh-max-" ), this->m_Key ) ), &this->m_UpperThresholdValue, "Maximum value truncation threshold", &this->m_UpperThresholdActive );
00078   
00079   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "prune-histogram-" ), this->m_Key ) ), &this->m_PruneHistogramBins, "Number of bins for histogram-based pruning", &this->m_UsePruneHistogramBins );
00080   cl.AddSwitch( CommandLine::Key( strcat( strcpy( buffer, "histogram-equalization-" ), this->m_Key ) ), &this->m_HistogramEqualization, true, "Apply histogram equalization" );
00081   cl.AddSwitch( CommandLine::Key( strcat( strcpy( buffer, "sobel-filter-" ), this->m_Key ) ), &this->m_SobelFilter, true, "Apply Sobel edge detection filter" );
00082   
00083   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "crop-index-" ), this->m_Key ) ), &this->m_CropIndex, "Cropping region in pixel index coordinates [parsed as %d,%d,%d,%d,%d,%d for i0,j0,k0,i1,j1,k1]" );
00084   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "crop-world-" ), this->m_Key ) ), &this->m_CropWorld, "Cropping region in world coordinates [parsed as %f,%f,%f,%f,%f,%f for x0,y0,z0,x1,y1,z1]" );
00085   
00086   cl.EndGroup();
00087 }
00088 
00089 UniformVolume::SmartPtr
00090 VoxelRegistration::ImagePreprocessor::GetProcessedImage( const UniformVolume* original )
00091 {
00092   UniformVolume::SmartPtr volume( original->Clone() );
00093   TypedArray::SmartPtr data = volume->GetData();
00094 
00095   if ( this->m_DataClassString )
00096     {
00097     this->m_DataClass = StringToDataClass( this->m_DataClassString );
00098     data->SetDataClass( this->m_DataClass );
00099     }
00100 
00101   if ( this->m_PaddingFlag ) 
00102     {
00103     data->SetPaddingValue( this->m_PaddingValue );
00104     }
00105 
00106   if ( this->m_LowerThresholdActive || this->m_UpperThresholdActive )
00107     {
00108     data->Threshold( Types::DataItemRange( this->m_LowerThresholdValue, this->m_UpperThresholdValue ) );
00109     }
00110 
00111   if ( this->m_PruneHistogramBins )
00112     {
00113     data->PruneHistogram( true /*pruneHi*/, false /*pruneLo*/, this->m_PruneHistogramBins );
00114     }
00115   
00116   if ( this->m_HistogramEqualization ) 
00117     {
00118     data->ApplyFunctionObject( TypedArrayFunctionHistogramEqualization( *data ) );
00119     }
00120 
00121   if ( this->m_SobelFilter ) 
00122     {
00123     volume->SetData( DataGridFilter( volume ).GetDataSobelFiltered() );
00124     }
00125 
00126   if ( this->m_CropIndex )
00127     {
00128     int cropFrom[3], cropTo[3];
00129     if ( 6 != sscanf( this->m_CropIndex, "%d,%d,%d,%d,%d,%d", cropFrom, cropFrom+1, cropFrom+2, cropTo, cropTo+1, cropTo+2 ) ) 
00130       {
00131       StdErr << "Option index coordinate cropping expects six integer parameters but got '" << this->m_CropIndex << "'\n";
00132       exit( 1 );
00133       }
00134     
00135     for ( int dim=0; dim<3; ++dim ) 
00136       {
00137       if ( cropTo[dim] < 0 ) 
00138         {
00139         cropTo[dim] = volume->GetDims()[dim] + cropTo[dim] + 1;
00140         }
00141       }
00142     volume->CropRegion() = DataGrid::RegionType( DataGrid::IndexType( cropFrom ), DataGrid::IndexType( cropTo ) );
00143     }
00144   
00145   if ( this->m_CropWorld )
00146     {
00147     float crop[6];
00148     if ( 6 != sscanf( this->m_CropWorld, "%f,%f,%f,%f,%f,%f", crop, crop+1, crop+2, crop+3, crop+4, crop+5 ) ) 
00149       {
00150       StdErr << "Option world coordinate cropping expects six floating-point parameters but got '" << this->m_CropWorld << "'\n";
00151       exit( 1 );
00152       }
00153     
00154     Types::Coordinate realCropFrom[3], realCropTo[3];
00155     for ( int dim=0; dim<3; ++dim ) 
00156       {
00157       realCropFrom[dim] = crop[dim];
00158       if ( crop[3+dim] < 0 ) 
00159         {
00160         realCropTo[dim] = volume->Size[dim] + crop[3+dim];
00161         }
00162       else
00163         {
00164         realCropTo[dim] = crop[3+dim];
00165         }
00166       }
00167     volume->SetHighResCropRegion( UniformVolume::CoordinateRegionType( UniformVolume::CoordinateRegionType::IndexType( realCropFrom ), UniformVolume::CoordinateRegionType::IndexType( realCropTo ) ) );
00168     }
00169 
00170   if ( this->m_AutoCropFlag )
00171     {
00172     volume->AutoCrop( this->m_AutoCropLevel, true /*recrop*/ );
00173     }
00174 
00175   return volume;
00176 }
00177 
00178 void 
00179 VoxelRegistration::ImagePreprocessor::WriteSettings
00180 ( ClassStream& stream ) const
00181 {
00182   char buffer[64];
00183   stream.Begin( strcat( strcpy( buffer, "preprocessing_" ), this->m_Key ) );
00184   switch ( this->m_DataClass ) 
00185     {
00186     case DATACLASS_GREY:
00187       stream.WriteString( "dataclass", "GreyLevel" );
00188       break;
00189     case DATACLASS_LABEL:
00190       stream.WriteString( "dataclass", "LabelField" );
00191       break;
00192     default:
00193       stream.WriteString( "dataclass", "Unknown" );
00194       break;
00195     }
00196 
00197   if ( this->m_PaddingFlag )
00198     stream.WriteDouble( "padding_value", this->m_PaddingValue );
00199 
00200   if ( this->m_LowerThresholdActive )
00201     stream.WriteDouble( "thresh_lower", this->m_LowerThresholdValue );    
00202     
00203   if ( this->m_UpperThresholdActive )
00204     stream.WriteDouble( "thresh_upper", this->m_UpperThresholdValue );    
00205     
00206   if ( this->m_PruneHistogramBins )
00207     stream.WriteInt( "prune_histogram_bins", this->m_PruneHistogramBins );
00208 
00209   if ( this->m_HistogramEqualization ) 
00210     stream.WriteBool( "histogram_equalization", true );
00211 
00212   if ( this->m_SobelFilter ) 
00213     stream.WriteBool( "sobel_filter", true );
00214 
00215   if ( this->m_CropIndex )
00216     stream.WriteString( "crop_index", this->m_CropIndex );
00217 
00218   if ( this->m_CropWorld )
00219     stream.WriteString( "crop_world", this->m_CropWorld );
00220 
00221   if ( this->m_AutoCropFlag )
00222     stream.WriteDouble( "auto_crop_level", this->m_AutoCropLevel );
00223 
00224   stream.End();
00225 }  
00226 
00227 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines