Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
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 }