cmtkDataGridMorphologicalOperators.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: 2464 $
00026 //
00027 //  $LastChangedDate: 2010-10-19 09:54:33 -0700 (Tue, 19 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torsten_at_home $
00030 //
00031 */
00032 
00033 #include "cmtkDataGridMorphologicalOperators.h"
00034 
00035 #include <Base/cmtkTemplateArray.h>
00036 #include <System/cmtkException.h>
00037 
00038 #include <vector>
00039 
00040 namespace
00041 cmtk
00042 {
00043 
00044 DataGridMorphologicalOperators
00045 ::DataGridMorphologicalOperators( const DataGrid::SmartConstPtr& dataGrid ) 
00046   : m_DataGrid( dataGrid ) 
00047 {
00048   if ( !this->m_DataGrid->GetData() )
00049     throw Exception( "ERROR: DataGrid object given to DataGridMorphologicalOperators constructor does not have a data array" );
00050 }
00051 
00052 bool
00053 DataGridMorphologicalOperators::EliminatePaddingVoting( const int iterations )
00054 {
00055   bool changed = false;
00056   for ( int it = 0; (it < iterations) && changed; ++it )
00057     {
00058     const TypedArray* data = this->m_DataGrid->GetData();
00059     TypedArray::SmartPtr result = data->Clone();
00060     
00061     if ( !data->GetPaddingFlag() ) return changed;
00062     const Types::DataItem dataPadding = data->GetPaddingValue();
00063     
00064     short valueMap[256];  
00065     size_t offset = 0;
00066     for ( int z = 0; z < this->m_DataGrid->m_Dims[2]; ++z ) 
00067       {
00068       const int dzFrom = z ? z-1 : z, dzTo = (z<this->m_DataGrid->m_Dims[2]-1) ? z+1 : z;
00069       for ( int y = 0; y < this->m_DataGrid->m_Dims[1]; ++y ) 
00070         {
00071         const int dyFrom = y ? y-1 : y, dyTo = (y<this->m_DataGrid->m_Dims[1]-1) ? y+1 : y;
00072         for ( int x = 0; x < this->m_DataGrid->m_Dims[0]; ++x, ++offset ) 
00073           {
00074           // is there Padding here?
00075           if ( data->PaddingDataAt( offset ) )
00076             {
00077             // determine frequencies of values among neighbors
00078             memset( valueMap, 0, sizeof( valueMap ) );
00079             const int dxFrom = x ? x-1 : x, dxTo = (x<this->m_DataGrid->m_Dims[0]-1) ? x+1 : x;
00080             for ( int dz = dzFrom; (dz <= dzTo); ++dz )
00081               for ( int dy = dyFrom; (dy <= dyTo); ++dy )
00082                 for ( int dx = dxFrom; (dx <= dxTo); ++dx )
00083                   {
00084                   Types::DataItem value;
00085                   if ( this->m_DataGrid->GetDataAt( value, dx, dy, dz ) )
00086                     {
00087                     ++valueMap[static_cast<byte>( value )];
00088                     }
00089                   }
00090             
00091             // find most frequent value among neighbors
00092             char maxCount = 0;
00093             Types::DataItem maxValue = 0;
00094             
00095             for ( int it = 0; it < 256; ++it )
00096               {
00097               if ( valueMap[it] > maxCount )
00098                 {
00099                 maxCount = valueMap[it];
00100                 maxValue = it;
00101                 }
00102               else
00103                 if ( valueMap[it] == maxCount )
00104                   {
00105                   maxValue = dataPadding;
00106                   }
00107               }
00108             
00109             if ( maxValue != dataPadding )
00110               {
00111               changed = true;
00112               result->Set( maxValue, offset );
00113               }
00114             } // if PaddingDataAt()
00115           } // for x
00116         } // for y
00117       } // for z
00118     }
00119   
00120   return changed;
00121 }
00122 
00123 TypedArray::SmartPtr
00124 DataGridMorphologicalOperators::GetEroded( const int iterations ) const
00125 {
00126   TypedArray::SmartPtr dataArray = this->m_DataGrid->GetData();
00127   if ( dataArray->GetType() != TYPE_BYTE ) 
00128     {
00129     throw Exception( "ERROR: convert data to byte before calling DataGridMorphologicalOperators::GetDataErode()" );
00130     }
00131 
00132   const byte* data = static_cast<const byte*>( dataArray->GetDataPtr() );
00133   std::vector<byte> tmp(  dataArray->GetDataSize()  );
00134 
00135   ByteArray::SmartPtr erodedArray = ByteArray::Create( dataArray->GetDataSize() );
00136   byte* eroded = erodedArray->GetDataPtrConcrete();
00137   
00138   memcpy( eroded, data, erodedArray->GetDataSizeBytes() );
00139   
00140   for ( int i = 0; i < iterations; ++i ) 
00141     {
00142     size_t offset = 0;
00143     for ( int z = 0; z < this->m_DataGrid->m_Dims[2]; ++z ) 
00144       {
00145       int dzFrom = z ? -1 : 0, dzTo = (z<this->m_DataGrid->m_Dims[2]-1) ? 1 : 0;
00146       for ( int y = 0; y < this->m_DataGrid->m_Dims[1]; ++y ) 
00147         {
00148         int dyFrom = y ? -1 : 0, dyTo = (y<this->m_DataGrid->m_Dims[1]-1) ? 1 : 0;
00149         for ( int x = 0; x < this->m_DataGrid->m_Dims[0]; ++x, ++offset ) 
00150           {
00151           int dxFrom = x ? -1 : 0, dxTo = (x<this->m_DataGrid->m_Dims[0]-1) ? 1 : 0;
00152           if ( eroded[offset] ) 
00153             {
00154             bool erodePixel = false;
00155             for ( int dz = dzFrom; (dz <= dzTo) && !erodePixel; ++dz )
00156               for ( int dy = dyFrom; (dy <= dyTo) && !erodePixel; ++dy )
00157                 for ( int dx = dxFrom; (dx <= dxTo) && !erodePixel; ++dx )
00158                   if ( dx || dy || dz )
00159                     if ( ! eroded[offset+this->m_DataGrid->GetOffsetFromIndex( dx, dy, dz )] )
00160                       erodePixel = true;
00161             if ( erodePixel )
00162               tmp[offset] = 0;
00163             else
00164               tmp[offset] = eroded[offset];
00165             } 
00166           else
00167             { // if data
00168             tmp[offset] = 0;
00169             } // if data
00170           } // for x
00171         } // for y
00172       } // for z
00173     
00174     memcpy( eroded, &(tmp[0]), erodedArray->GetDataSizeBytes() );
00175     } // for i
00176   
00177   return erodedArray;
00178 }
00179 
00180 TypedArray::SmartPtr
00181 DataGridMorphologicalOperators::GetDilated( const int iterations ) const
00182 {
00183   TypedArray::SmartPtr dataArray = this->m_DataGrid->GetData();
00184   if ( dataArray->GetType() != TYPE_BYTE ) 
00185     {
00186     throw Exception( "ERROR: convert data to byte before calling DataGridMorphologicalOperators::GetDataDilate()" );
00187     }
00188   
00189   const byte* data = static_cast<const byte*>( dataArray->GetDataPtr() );
00190   std::vector<byte> tmp(  dataArray->GetDataSize()  );
00191   
00192   ByteArray::SmartPtr dilatedArray = ByteArray::Create( dataArray->GetDataSize() );
00193   byte* dilated = dilatedArray->GetDataPtrConcrete();
00194   
00195   memcpy( dilated, data, dilatedArray->GetDataSizeBytes() );
00196   
00197   for ( int i = 0; i < iterations; ++i ) 
00198     {
00199     size_t offset = 0;
00200     for ( int z = 0; z < this->m_DataGrid->m_Dims[2]; ++z ) 
00201       {
00202       int dzFrom = z ? -1 : 0, dzTo = (z<this->m_DataGrid->m_Dims[2]-1) ? 1 : 0;
00203       for ( int y = 0; y < this->m_DataGrid->m_Dims[1]; ++y ) 
00204         {
00205         int dyFrom = y ? -1 : 0, dyTo = (y<this->m_DataGrid->m_Dims[1]-1) ? 1 : 0;
00206         for ( int x = 0; x < this->m_DataGrid->m_Dims[0]; ++x, ++offset ) 
00207           {
00208           int dxFrom = x ? -1 : 0, dxTo = (x<this->m_DataGrid->m_Dims[0]-1) ? 1 : 0;
00209           if ( ! dilated[offset] ) 
00210             {
00211             byte dilatePixel = 0;
00212             for ( int dz = dzFrom; (dz <= dzTo) && !dilatePixel; ++dz )
00213               for ( int dy = dyFrom; (dy <= dyTo) && !dilatePixel; ++dy )
00214                 for ( int dx = dxFrom; (dx <= dxTo) && !dilatePixel; ++dx )
00215                   if ( dx || dy || dz )
00216                     dilatePixel = dilated[offset+this->m_DataGrid->GetOffsetFromIndex(dx,dy,dz)];
00217             if ( dilatePixel )
00218               tmp[offset] = dilatePixel;
00219             else
00220               tmp[offset] = 0;
00221             } 
00222           else
00223             { // !data
00224             tmp[offset] = dilated[offset];
00225             } // else !data
00226           } // for x
00227         } // for y
00228       } // for z
00229     
00230     memcpy( dilated, &(tmp[0]), dilatedArray->GetDataSizeBytes() );
00231     } // for i
00232   
00233   return dilatedArray;
00234 }
00235 
00236 TypedArray::SmartPtr 
00237 DataGridMorphologicalOperators::GetBoundaryMap( const bool multiValued ) const
00238 {
00239   TypedArray::SmartPtr dataArray = this->m_DataGrid->GetData();
00240   ShortArray::SmartPtr boundaryArray = ShortArray::Create( dataArray->GetDataSize() );
00241   short* boundary = boundaryArray->GetDataPtrConcrete();
00242 
00243 #pragma omp parallel for
00244   for ( int z = 0; z < this->m_DataGrid->m_Dims[2]; ++z ) 
00245     {
00246     size_t offset = z * this->m_DataGrid->m_Dims[0] * this->m_DataGrid->m_Dims[1];
00247 
00248     Types::DataItem value, neighbor;
00249     const int dzFrom = z ? -1 : 0, dzTo = (z<this->m_DataGrid->m_Dims[2]-1) ? 1 : 0;
00250     for ( int y = 0; y < this->m_DataGrid->m_Dims[1]; ++y ) 
00251       {
00252       const int dyFrom = y ? -1 : 0, dyTo = (y<this->m_DataGrid->m_Dims[1]-1) ? 1 : 0;
00253       for ( int x = 0; x < this->m_DataGrid->m_Dims[0]; ++x, ++offset ) 
00254         {
00255         const int dxFrom = x ? -1 : 0, dxTo = (x<this->m_DataGrid->m_Dims[0]-1) ? 1 : 0;
00256         bool bp = false;
00257         if ( dataArray->Get( value, offset ) ) 
00258           {
00259           for ( int dz = dzFrom; (dz <= dzTo) && !bp; ++dz )
00260             for ( int dy = dyFrom; (dy <= dyTo) && !bp; ++dy )
00261               for ( int dx = dxFrom; (dx <= dxTo) && !bp; ++dx )
00262                 if ( dx || dy || dz )
00263                   if ( dataArray->Get( neighbor, offset+this->m_DataGrid->GetOffsetFromIndex(dx,dy,dz) ) )
00264                     bp = (value != neighbor);
00265           }
00266         else
00267           {
00268           value = 0;
00269           }
00270 
00271         if ( bp )
00272           {
00273           if ( multiValued )
00274             boundary[offset] = static_cast<short>( value );
00275           else
00276             boundary[offset] = 1;
00277           }
00278         else
00279           boundary[offset] = 0;
00280         
00281         } // for x
00282       } // for y
00283     } // for z
00284   
00285   return boundaryArray;
00286 }
00287 
00288 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines