cmtkImagePairRegistrationImagePreprocessor.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 "cmtkImagePairRegistration.h"
00034 
00035 #include <System/cmtkCommandLine.h>
00036 #include <Base/cmtkTypedArrayFunctionHistogramEqualization.h>
00037 #include <Base/cmtkDataGridFilter.h>
00038 
00039 namespace
00040 cmtk
00041 {
00042 
00043 ImagePairRegistration::ImagePreprocessor::ImagePreprocessor( const char* name, const char* key )
00044   : m_DataClassString( NULL ),
00045     m_DataClass( DATACLASS_GREY ),
00046     m_PaddingFlag( false ),
00047     m_PaddingValue( 0 ),
00048     m_LowerThresholdActive( false ),
00049     m_LowerThresholdValue( -CMTK_ITEM_MAX ),
00050     m_UpperThresholdActive( false ),
00051     m_UpperThresholdValue( CMTK_ITEM_MAX ),
00052     m_UsePruneHistogramBins( false ),
00053     m_PruneHistogramBins( 0 ),
00054     m_HistogramEqualization( false ),
00055     m_MedianFilterRadius( 0 ),
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 ImagePairRegistration::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.AddOption( CommandLine::Key( strcat( strcpy( buffer, "median-filter-radius-" ), this->m_Key ) ), &this->m_MedianFilterRadius, "Apply median filter with given radius" );
00082   cl.AddSwitch( CommandLine::Key( strcat( strcpy( buffer, "sobel-filter-" ), this->m_Key ) ), &this->m_SobelFilter, true, "Apply Sobel edge detection filter" );
00083   
00084   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]" );
00085   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]" );
00086   cl.AddOption( CommandLine::Key( strcat( strcpy( buffer, "crop-thresh-" ), this->m_Key ) ), &this->m_AutoCropLevel, "Automatic cropping based on threshold", &this->m_AutoCropFlag );
00087   
00088   cl.EndGroup();
00089 }
00090 
00091 UniformVolume::SmartPtr
00092 ImagePairRegistration::ImagePreprocessor::GetProcessedImage( const UniformVolume* original )
00093 {
00094   UniformVolume::SmartPtr volume( original->Clone() );
00095   TypedArray::SmartPtr data = volume->GetData();
00096 
00097   if ( this->m_DataClassString )
00098     {
00099     this->m_DataClass = StringToDataClass( this->m_DataClassString );
00100     data->SetDataClass( this->m_DataClass );
00101     }
00102 
00103   if ( this->m_PaddingFlag ) 
00104     {
00105     data->SetPaddingValue( this->m_PaddingValue );
00106     }
00107 
00108   if ( this->m_LowerThresholdActive || this->m_UpperThresholdActive )
00109     {
00110     data->Threshold( Types::DataItemRange( this->m_LowerThresholdValue, this->m_UpperThresholdValue ) );
00111     }
00112 
00113   if ( this->m_PruneHistogramBins )
00114     {
00115     data->PruneHistogram( true /*pruneHi*/, false /*pruneLo*/, this->m_PruneHistogramBins );
00116     }
00117   
00118   if ( this->m_HistogramEqualization ) 
00119     {
00120     data->ApplyFunctionObject( TypedArrayFunctionHistogramEqualization( *data ) );
00121     }
00122 
00123   if ( this->m_MedianFilterRadius ) 
00124     {
00125     volume->SetData( DataGridFilter( volume ).GetDataMedianFiltered( this->m_MedianFilterRadius ) );
00126     }
00127   
00128   if ( this->m_SobelFilter ) 
00129     {
00130     volume->SetData( DataGridFilter( volume ).GetDataSobelFiltered() );
00131     }
00132 
00133   if ( this->m_CropIndex )
00134     {
00135     int cropFrom[3], cropTo[3];
00136     if ( 6 != sscanf( this->m_CropIndex, "%d,%d,%d,%d,%d,%d", cropFrom, cropFrom+1, cropFrom+2, cropTo, cropTo+1, cropTo+2 ) ) 
00137       {
00138       StdErr << "Option index coordinate cropping expects six integer parameters but got '" << this->m_CropIndex << "'\n";
00139       exit( 1 );
00140       }
00141     
00142     for ( int dim=0; dim<3; ++dim ) 
00143       {
00144       if ( cropTo[dim] < 0 ) 
00145         {
00146         cropTo[dim] = volume->GetDims()[dim] + cropTo[dim] + 1;
00147         }
00148       }
00149     volume->CropRegion() = DataGrid::RegionType( DataGrid::IndexType( cropFrom ), DataGrid::IndexType( cropTo ) );
00150     }
00151   
00152   if ( this->m_CropWorld )
00153     {
00154     float crop[6];
00155     if ( 6 != sscanf( this->m_CropWorld, "%f,%f,%f,%f,%f,%f", crop, crop+1, crop+2, crop+3, crop+4, crop+5 ) ) 
00156       {
00157       StdErr << "Option world coordinate cropping expects six floating-point parameters but got '" << this->m_CropWorld << "'\n";
00158       exit( 1 );
00159       }
00160     
00161     Types::Coordinate realCropFrom[3], realCropTo[3];
00162     for ( int dim=0; dim<3; ++dim ) 
00163       {
00164       realCropFrom[dim] = crop[dim];
00165       if ( crop[3+dim] < 0 ) 
00166         {
00167         realCropTo[dim] = volume->Size[dim] + crop[3+dim];
00168         }
00169       else
00170         {
00171         realCropTo[dim] = crop[3+dim];
00172         }
00173       }
00174     volume->SetHighResCropRegion( UniformVolume::CoordinateRegionType( UniformVolume::CoordinateRegionType::IndexType( realCropFrom ), UniformVolume::CoordinateRegionType::IndexType( realCropTo ) ) );
00175     }
00176   
00177   if ( this->m_AutoCropFlag )
00178     {
00179     volume->AutoCrop( this->m_AutoCropLevel, true /*recrop*/ );
00180     }
00181 
00182   return volume;
00183 }
00184 
00185 void 
00186 ImagePairRegistration::ImagePreprocessor::WriteSettings
00187 ( ClassStream& stream ) const
00188 {
00189   char buffer[64];
00190   stream.Begin( strcat( strcpy( buffer, "preprocessing_" ), this->m_Key ) );
00191   switch ( this->m_DataClass ) 
00192     {
00193     case DATACLASS_GREY:
00194       stream.WriteString( "dataclass", "GreyLevel" );
00195       break;
00196     case DATACLASS_LABEL:
00197       stream.WriteString( "dataclass", "LabelField" );
00198       break;
00199     default:
00200       stream.WriteString( "dataclass", "Unknown" );
00201       break;
00202     }
00203 
00204   if ( this->m_PaddingFlag )
00205     stream.WriteDouble( "padding_value", this->m_PaddingValue );
00206 
00207   if ( this->m_LowerThresholdActive )
00208     stream.WriteDouble( "thresh_lower", this->m_LowerThresholdValue );    
00209     
00210   if ( this->m_UpperThresholdActive )
00211     stream.WriteDouble( "thresh_upper", this->m_UpperThresholdValue );    
00212     
00213   if ( this->m_PruneHistogramBins )
00214     stream.WriteInt( "prune_histogram_bins", this->m_PruneHistogramBins );
00215 
00216   if ( this->m_HistogramEqualization ) 
00217     stream.WriteBool( "histogram_equalization", true );
00218 
00219   if ( this->m_SobelFilter ) 
00220     stream.WriteBool( "sobel_filter", true );
00221 
00222   if ( this->m_CropIndex )
00223     stream.WriteString( "crop_index", this->m_CropIndex );
00224 
00225   if ( this->m_CropWorld )
00226     stream.WriteString( "crop_world", this->m_CropWorld );
00227 
00228   if ( this->m_AutoCropFlag )
00229     stream.WriteDouble( "auto_crop_level", this->m_AutoCropLevel );
00230 
00231   stream.End();
00232 }  
00233 
00234 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines