cmtkOverlapMeasures.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 <Segmentation/cmtkOverlapMeasures.h>
00034 
00035 #include <System/cmtkProgress.h>
00036 
00037 #ifdef _OPENMP
00038 #  include <omp.h>
00039 #endif
00040 
00041 namespace
00042 cmtk
00043 {
00044 
00047 
00048 OverlapMeasures::OverlapMeasures( const std::vector<TypedArray::SmartPtr>& dataArrays )
00049 {
00050   this->m_DataArrays = dataArrays;
00051   this->m_MaxLabelValue = 0;
00052   for ( size_t i = 0; i < this->m_DataArrays.size(); ++i )
00053     {
00054     const Types::DataItemRange range = this->m_DataArrays[i]->GetRange();
00055     this->m_MaxLabelValue = std::max<unsigned int>( this->m_MaxLabelValue, static_cast<unsigned int>( range.m_UpperBound ) );
00056     }
00057   
00058   // set size limits
00059   this->m_NumberOfImages = this->m_DataArrays.size();
00060 
00061   this->m_NumberOfPixels = this->m_DataArrays[0]->GetDataSize();
00062   for ( size_t i = 1; i < this->m_NumberOfImages; ++i )
00063     {
00064     this->m_NumberOfPixels = std::min( this->m_NumberOfPixels, this->m_DataArrays[i]->GetDataSize() );
00065     }
00066 }
00067 
00068 size_t
00069 OverlapMeasures::ComputeGroupwiseOverlap
00070 ( const int firstLabel, const int numberOfLabels, double& overlapEqualWeighted, double& overlapVolumeWeighted, double& overlapInverseWeighted ) const
00071 {
00072   // compute label volumes per image
00073   std::vector< std::vector< unsigned int > > volumeTable( numberOfLabels );
00074   for ( int label = 0; label < numberOfLabels; ++label )
00075     {
00076     volumeTable[label].resize( this->m_NumberOfImages, 0 );
00077     }
00078 
00079   std::vector<bool> labelExists( numberOfLabels );
00080   std::fill( labelExists.begin(), labelExists.end(), false );
00081 
00082   for ( size_t i = 0; i < this->m_NumberOfImages; ++i )
00083     {
00084     for ( size_t px = 0; px < this->m_NumberOfPixels; ++px )
00085       {
00086       Types::DataItem l;
00087       if ( this->m_DataArrays[i]->Get( l, px ) )
00088         {
00089         const int thisLabel = static_cast<int>(l) - firstLabel;
00090         if ( (thisLabel >= 0) && (thisLabel < numberOfLabels) )
00091           {
00092           ++volumeTable[thisLabel][i];
00093           labelExists[thisLabel] = true;
00094           }
00095         }
00096       }
00097     }
00098 
00099   size_t numberOfLabelsIncluded = 0;
00100   for ( int label = 0; label < numberOfLabels; ++label )
00101     {
00102     if ( labelExists[label] )
00103       ++numberOfLabelsIncluded;
00104     }
00105   if ( ! numberOfLabelsIncluded )
00106     return numberOfLabelsIncluded;
00107 
00108   // run overlap computation
00109   const size_t progressPixels = 100000;
00110   Progress::Begin( 0, this->m_NumberOfPixels, progressPixels, "Overlap computation" );
00111 
00112 #ifdef _OPENMP
00113   const size_t numberOfThreads = omp_get_max_threads();
00114 #else
00115   const size_t numberOfThreads = 1;
00116 #endif
00117 
00118   std::vector<int> labelsPerPixel( numberOfThreads * this->m_NumberOfImages );
00119   
00120   const size_t sumsPerThread = numberOfLabels * this->m_NumberOfImages * (this->m_NumberOfImages-1) / 2;
00121   std::vector<double> sumsMin( numberOfThreads * sumsPerThread, 0.0 );
00122   std::vector<double> sumsMax( numberOfThreads * sumsPerThread, 0.0 );
00123 
00124 #pragma omp parallel for  
00125   for ( size_t px = 0; px < this->m_NumberOfPixels; ++px )
00126     {
00127     if ( (px % progressPixels) == 0 )
00128 #ifdef _OPENMP
00129       if ( !omp_get_thread_num() )
00130 #endif
00131         Progress::SetProgress( px );
00132 
00133 #ifdef _OPENMP
00134     const size_t labelsPerPixelOfs = this->m_NumberOfImages * omp_get_thread_num();
00135 #else
00136     const size_t labelsPerPixelOfs = 0;
00137 #endif
00138 
00139     Types::DataItem l;
00140     for ( size_t i = 0; i < this->m_NumberOfImages; ++i )
00141       {
00142       labelsPerPixel[labelsPerPixelOfs+i] = -1;
00143       if ( this->m_DataArrays[i]->Get( l, px ) ) 
00144         {
00145         const int thisLabel = static_cast<int>(l) - firstLabel;
00146         if ( (thisLabel >= 0) && (thisLabel < numberOfLabels) )
00147           labelsPerPixel[labelsPerPixelOfs+i] = thisLabel;
00148         }
00149       }
00150     
00151 #ifdef _OPENMP
00152     size_t ofs = sumsPerThread * omp_get_thread_num();
00153 #else
00154     size_t ofs = 0;
00155 #endif
00156     for ( int label = 0; label < numberOfLabels; ++label )
00157       {
00158       if ( labelExists[label] )
00159         {
00160         for ( size_t i = 0; i < this->m_NumberOfImages; ++i )
00161           {
00162           const int wi = (labelsPerPixel[labelsPerPixelOfs+i] == label)?1:0;
00163           for ( size_t j = 0; j < i; ++j, ++ofs )
00164             {
00165             const int wj = (labelsPerPixel[labelsPerPixelOfs+j] == label)?1:0;
00166             
00167             sumsMin[ofs] += std::min( wi, wj );
00168             sumsMax[ofs] += std::max( wi, wj );
00169             }
00170           }
00171         }
00172       }
00173     }
00174   
00175 #ifdef _OPENMP
00176   size_t dstOfs = sumsPerThread;
00177   for ( size_t thread = 1; thread < numberOfThreads; ++thread )
00178     {
00179     size_t thrOfs = 0;
00180     for ( size_t i = 0; i < sumsPerThread; ++i, ++thrOfs, ++dstOfs )
00181       {
00182       sumsMin[thrOfs] += sumsMin[dstOfs];
00183       sumsMax[thrOfs] += sumsMax[dstOfs];
00184       }
00185     }
00186 #endif
00187   
00188   Progress::Done(); // rest should go fast
00189   
00190   double overlap_min_equal = 0, overlap_max_equal = 0;
00191   double overlap_min_volume = 0, overlap_max_volume = 0;
00192   double overlap_min_inverse = 0, overlap_max_inverse = 0;
00193 
00194   size_t ofs = 0;
00195   for ( int label = 0; label < numberOfLabels; ++label )
00196     {
00197     if ( labelExists[label] )
00198       {
00199       for ( size_t i = 0; i < this->m_NumberOfImages; ++i )
00200         {
00201         const unsigned int vi = volumeTable[label][i];
00202         for ( size_t j = 0; j < i; ++j, ++ofs )
00203           {
00204           overlap_min_volume += sumsMin[ofs];
00205           overlap_max_volume += sumsMax[ofs];
00206           
00207           const unsigned int vij = vi + volumeTable[label][j];
00208           if ( vij )
00209             {
00210             overlap_min_equal += sumsMin[ofs] / vij;
00211             overlap_max_equal += sumsMax[ofs] / vij;
00212             
00213             overlap_min_inverse += (sumsMin[ofs] / vij) / vij;
00214             overlap_max_inverse += (sumsMax[ofs] / vij) / vij;
00215             }
00216           }
00217         }
00218       }
00219     }
00220   
00221   if ( overlap_max_equal )
00222     overlapEqualWeighted = overlap_min_equal / overlap_max_equal;
00223   if ( overlap_max_volume )
00224     overlapVolumeWeighted = overlap_min_volume / overlap_max_volume;
00225   if ( overlap_max_inverse )
00226     overlapInverseWeighted = overlap_min_inverse / overlap_max_inverse;
00227 
00228   return numberOfLabelsIncluded;
00229 }
00230 
00231 double
00232 OverlapMeasures::ComputePairwiseOverlapMinMax
00233 ( double& overlap_min, double& overlap_max, const TypedArray::SmartPtr& data0, const TypedArray::SmartPtr& data1, const int label ) const
00234 {
00235   overlap_min = overlap_max = 0;
00236   for ( size_t i = 0; i < this->m_NumberOfPixels; ++i )
00237     {
00238     Types::DataItem l0, l1;
00239     if ( ! data0->Get( l0, i ) ) l0 = -1;
00240     if ( ! data1->Get( l1, i ) ) l1 = -1;
00241 
00242     const int w0 = (l0 == label)?1:0;
00243     const int w1 = (l1 == label)?1:0;
00244 
00245     overlap_min += std::min( w0, w1 );
00246     overlap_max += std::max( w0, w1 );
00247     }
00248   return 0;
00249 }
00250 
00251 } // namespace cmtk
00252 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines