cmtkDataGrid_Crop.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: 2580 $
00026 //
00027 //  $LastChangedDate: 2010-12-01 16:20:46 -0800 (Wed, 01 Dec 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkDataGrid.h"
00034 
00035 namespace
00036 cmtk
00037 {
00038 
00039 void
00040 DataGrid::SetCropRegion( const Self::RegionType& region ) 
00041 {
00042   this->m_CropRegion = region;
00043   for ( int dim = 0; dim < 3; ++dim )
00044     {
00045     // for negative crop region index values, go from upper, rather than lower, grid boundary
00046     if ( this->m_CropRegion.From()[dim] < 0 )
00047       this->m_CropRegion.From()[dim] = this->m_Dims[dim] + this->m_CropRegion.From()[dim];
00048 
00049     if ( this->m_CropRegion.To()[dim] < 0 )
00050       this->m_CropRegion.To()[dim] = this->m_Dims[dim] + this->m_CropRegion.To()[dim];
00051 
00052     // check whether all cropping index values are within the valid range and truncate if necessary
00053     this->m_CropRegion.To()[dim] = std::min( this->m_Dims[dim], std::max( 0, this->m_CropRegion.To()[dim] ) );
00054     this->m_CropRegion.From()[dim] = std::min( this->m_Dims[dim], std::max( 0, this->m_CropRegion.From()[dim] ) );
00055     }
00056 }
00057 
00058 const DataGrid::IndexType
00059 DataGrid::GetCropRegionIncrements
00060 () const
00061 {
00062   DataGrid::IndexType increments;
00063 
00064   increments[0] = this->m_CropRegion.From()[0] + this->m_Dims[0] * ( this->m_CropRegion.From()[1] + this->m_Dims[1] * this->m_CropRegion.From()[2] );
00065   increments[1] = this->m_CropRegion.From()[0] + (this->m_Dims[0] - this->m_CropRegion.To()[0]);
00066   increments[2] = this->m_Dims[0] * ( this->m_CropRegion.From()[1] + ( this->m_Dims[1] - this->m_CropRegion.To()[1]) );
00067   
00068   return increments;
00069 }
00070 
00071 int
00072 DataGrid::GetCropRegionNumVoxels() const 
00073 {
00074   return (this->m_CropRegion.To()[0] - this->m_CropRegion.From()[0]) * (this->m_CropRegion.To()[1] - this->m_CropRegion.From()[1]) * (this->m_CropRegion.To()[2] - this->m_CropRegion.From()[2]);
00075 }
00076 
00077 void
00078 DataGrid::AutoCrop
00079 ( const Types::DataItem threshold, const bool recrop, const int margin )
00080 {
00081   const TypedArray* data = this->GetData();
00082   
00083   Self::IndexType cropFrom = this->CropRegion().From(), cropTo = this->CropRegion().To();
00084   
00085   if ( ! recrop ) 
00086     {
00087     for ( int dim = 0; dim < 3; ++dim ) 
00088       {
00089       cropFrom[dim] = 0;
00090       cropTo[dim] = this->m_Dims[dim];
00091       }
00092     }
00093   
00094   const size_t nextRow = this->m_Dims[0] - cropTo[0] + this->m_CropRegion.From()[0];
00095   const size_t nextPlane = this->m_Dims[0] * (this->m_Dims[1] - cropTo[1] + this->m_CropRegion.From()[1]);
00096   
00097   size_t offset = cropFrom[0] + this->m_Dims[0] * ( cropFrom[1] + this->m_Dims[1] * cropFrom[2] );
00098 
00099   Self::IndexType newCropFrom = cropTo, newCropTo = cropFrom;
00100   Self::IndexType xyz;
00101   for ( xyz[2] = cropFrom[2]; xyz[2] < cropTo[2]; ++xyz[2], offset += nextPlane )
00102     for ( xyz[1] = cropFrom[1]; xyz[1] < cropTo[1]; ++xyz[1], offset += nextRow )
00103       for ( xyz[0] = cropFrom[0]; xyz[0] < cropTo[0]; ++xyz[0], ++offset ) 
00104         {
00105         Types::DataItem value = 0;
00106         if ( ! data->Get( value, offset ) || (value < threshold) ) continue;
00107         
00108         for ( int i = 0; i < 3; ++i )
00109           {
00110           newCropFrom[i] = std::min( newCropFrom[i], xyz[i] );
00111           newCropTo[i] = std::max( newCropTo[i], xyz[i] );
00112           }
00113         }
00114   
00115   for ( int dim = 0; dim < 3; ++dim ) 
00116     {
00117     ++newCropTo[dim];
00118     }
00119   
00120   if ( margin ) 
00121     {
00122     for ( int dim = 0; dim < 3; ++dim ) 
00123       {
00124       newCropFrom[dim] = std::max<int>( 0, newCropFrom[dim] - margin );
00125       newCropTo[dim] = std::min<int>( this->m_Dims[dim], newCropTo[dim] + margin );
00126       }
00127     }
00128   
00129   this->m_CropRegion = Self::RegionType( newCropFrom, newCropTo );
00130 }
00131 
00132 void
00133 DataGrid::FillCropBackground( const Types::DataItem value )
00134 {
00135   const size_t planeSize = this->m_Dims[0] * this->m_Dims[1];
00136 
00137   size_t offset = this->m_CropRegion.From()[2] * planeSize;
00138   this->m_Data->BlockSet( value, 0, offset );
00139 
00140   for ( int z = this->m_CropRegion.From()[2]; z < this->m_CropRegion.To()[2]; ++z ) 
00141     {
00142     size_t planeOffset = offset + this->m_CropRegion.From()[1] * this->m_Dims[0];
00143     this->m_Data->BlockSet( value, offset, planeOffset );
00144 
00145     offset = planeOffset;
00146     for ( int y = this->m_CropRegion.From()[1]; y < this->m_CropRegion.To()[1]; ++y, offset += this->m_Dims[0] ) 
00147       {
00148       this->m_Data->BlockSet( value, offset, offset+this->m_CropRegion.From()[0] );
00149       this->m_Data->BlockSet( value, offset+this->m_CropRegion.To()[0], offset+this->m_Dims[0] );
00150       }
00151     
00152     planeOffset = offset + (this->m_Dims[1]-this->m_CropRegion.To()[1]) * this->m_Dims[0];
00153     this->m_Data->BlockSet( value, offset, planeOffset );
00154     offset = planeOffset;
00155     }
00156   
00157   this->m_Data->BlockSet( value, this->m_CropRegion.To()[2] * planeSize, this->m_Dims[2] * planeSize );
00158 }
00159 
00160 TypedArray::SmartPtr
00161 DataGrid::GetCroppedData() const
00162 {
00163   const TypedArray* srcData = this->GetData();
00164   if ( ! srcData ) 
00165     throw( Exception( "No input data in DataGrid::GetCroppedData()" ) );
00166 
00167   TypedArray::SmartPtr cropData = TypedArray::Create( srcData->GetType(), this->GetCropRegionNumVoxels() );
00168   
00169   const size_t lineLength = this->m_CropRegion.To()[0] - this->m_CropRegion.From()[0];
00170   const size_t nextPlane = this->m_Dims[0] * (this->m_Dims[1] - (this->m_CropRegion.To()[1] - this->m_CropRegion.From()[1]));
00171   
00172   size_t toOffset = 0;
00173   size_t fromOffset = this->m_CropRegion.From()[0] + this->m_Dims[0] * ( this->m_CropRegion.From()[1] + this->m_Dims[1] * this->m_CropRegion.From()[2] );
00174 
00175   for ( int z = this->m_CropRegion.From()[2]; z < this->m_CropRegion.To()[2]; ++z, fromOffset += nextPlane )
00176     for ( int y = this->m_CropRegion.From()[1]; y < this->m_CropRegion.To()[1]; ++y, fromOffset += this->m_Dims[0] ) 
00177       {
00178       srcData->BlockCopy( *cropData, toOffset, fromOffset, lineLength );
00179       toOffset += lineLength;
00180       }
00181   
00182   return cropData;
00183 }
00184 
00185 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines