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 #include "cmtkDataGridMorphologicalOperators.h"
00032
00033 #include <Base/cmtkUnionFind.h>
00034
00035 #include <map>
00036 #include <vector>
00037 #include <list>
00038
00039 cmtk::TypedArray::SmartPtr
00040 cmtk::DataGridMorphologicalOperators::GetBinaryConnectedComponents() const
00041 {
00042 const size_t numberOfPixels = this->m_DataGrid->GetNumberOfPixels();
00043
00044
00045
00046 std::vector<int> result( numberOfPixels);
00047
00048 const DataGrid::IndexType& dims = this->m_DataGrid->GetDims();
00049
00050 DataGrid::IndexType relative;
00051 relative[0] = this->m_DataGrid->GetNextI();
00052 relative[1] = this->m_DataGrid->GetNextJ();
00053 relative[2] = this->m_DataGrid->GetNextK();
00054
00055 UnionFind<int> connected;
00056 int nextComponent = 1;
00057
00058 DataGrid::IndexType index;
00059 size_t offset = 0;
00060 for ( index[2] = 0; index[2] < dims[2]; ++index[2] )
00061 {
00062 for ( index[1] = 0; index[1] < dims[1]; ++index[1] )
00063 {
00064 for ( index[0] = 0; index[0] < dims[0]; ++index[0], ++offset )
00065 {
00066
00067 int component = 0;
00068
00069
00070 if ( this->m_DataGrid->GetDataAt( offset ) != 0 )
00071 {
00072
00073 for ( int dim = 2; dim >= 0; --dim )
00074 {
00075
00076 if ( index[dim] )
00077 {
00078
00079 const int existing = result[offset - relative[dim]];
00080
00081 if ( existing )
00082 {
00083
00084 if ( component && (component != existing) )
00085 {
00086
00087 connected.Union( connected.Find( component ), connected.Find( existing ) );
00088 }
00089
00090 component = existing;
00091 }
00092 }
00093 }
00094
00095
00096 if ( !component )
00097 {
00098 component = nextComponent++;
00099 connected.Insert( component );
00100 }
00101 }
00102
00103
00104 result[offset] = component;
00105 }
00106 }
00107 }
00108
00109
00110 std::map<int,int> linkMap;
00111 for ( int component = 1; component < nextComponent; ++component )
00112 {
00113 linkMap[component] = connected.FindKey( component );
00114 }
00115
00116
00117 TypedArray::SmartPtr resultArray( TypedArray::Create( TYPE_INT, numberOfPixels ) );
00118 #pragma omp parallel for
00119 for ( size_t px = 0; px < numberOfPixels; ++px )
00120 {
00121 resultArray->Set( linkMap[result[px]], px );
00122 }
00123
00124 return resultArray;
00125 }
00126
00127 cmtk::TypedArray::SmartPtr
00128 cmtk::DataGridMorphologicalOperators::GetRegionsRenumberedBySize() const
00129 {
00130 const size_t numberOfPixels = this->m_DataGrid->GetNumberOfPixels();
00131
00132
00133 std::map<int,int> regionSizeMap;
00134 for ( size_t px = 0; px < numberOfPixels; ++px )
00135 {
00136 const int value = static_cast<int>( this->m_DataGrid->GetDataAt( px ) );
00137 if ( value )
00138 ++regionSizeMap[value];
00139 }
00140
00141
00142 std::list< std::pair<const int,int> > sortedList;
00143 for ( std::map<int,int>::const_iterator it = regionSizeMap.begin(); it != regionSizeMap.end(); ++it )
00144 {
00145 std::list< std::pair<const int,int> >::iterator ins = sortedList.begin();
00146 while ( (ins != sortedList.end()) && (ins->second >= it->second) )
00147 ++ins;
00148
00149 sortedList.insert( ins, *it );
00150 }
00151
00152
00153 std::map<int,int> renumberMap;
00154 int component = 1;
00155 for ( std::list< std::pair<const int,int> >::iterator it = sortedList.begin(); it != sortedList.end(); ++it )
00156 {
00157 renumberMap[it->first] = component++;
00158 }
00159
00160
00161 TypedArray::SmartPtr resultArray( TypedArray::Create( TYPE_INT, numberOfPixels ) );
00162 for ( size_t px = 0; px < numberOfPixels; ++px )
00163 {
00164 resultArray->Set( renumberMap[static_cast<int>( this->m_DataGrid->GetDataAt( px ) )], px );
00165 }
00166
00167 return resultArray;
00168 }