Diff of /src/labelStats.cxx [000000] .. [5d12a0]

Switch to unified view

a b/src/labelStats.cxx
1
2
#include <nanobind/nanobind.h>
3
#include <nanobind/stl/vector.h>
4
#include <nanobind/stl/string.h>
5
#include <nanobind/stl/tuple.h>
6
#include <nanobind/stl/list.h>
7
#include <nanobind/ndarray.h>
8
#include <nanobind/stl/shared_ptr.h>
9
10
#include "itkImage.h"
11
#include "itkLabelStatisticsImageFilter.h"
12
#include "itkImageRegionIteratorWithIndex.h"
13
14
#include "antsImage.h"
15
16
namespace nb = nanobind;
17
using namespace nb::literals;
18
19
template< unsigned int Dimension >
20
nb::dict labelStatsHelper(
21
  typename itk::Image< float, Dimension >::Pointer image,
22
  typename itk::Image< unsigned int, Dimension>::Pointer labelImage)
23
{
24
  typedef float PixelType;
25
  typedef itk::Image< PixelType, Dimension > ImageType;
26
  typedef unsigned int LabelType;
27
  typedef typename ImageType::PointType PointType;
28
  typedef itk::Image< LabelType, Dimension > LabelImageType;
29
  typedef itk::ImageRegionIteratorWithIndex<LabelImageType>                    Iterator;
30
  typedef itk::LabelStatisticsImageFilter< ImageType, LabelImageType >
31
    LabelStatisticsImageFilterType;
32
  typename LabelStatisticsImageFilterType::Pointer labelStatisticsImageFilter =
33
    LabelStatisticsImageFilterType::New();
34
  labelStatisticsImageFilter->SetInput( image );
35
  labelStatisticsImageFilter->SetLabelInput( labelImage );
36
  labelStatisticsImageFilter->Update();
37
38
  typedef typename LabelStatisticsImageFilterType::ValidLabelValuesContainerType
39
    ValidLabelValuesType;
40
41
  long nlabs = labelStatisticsImageFilter->GetNumberOfLabels();
42
43
  std::vector<double> labelvals(nlabs);
44
  std::vector<double> means(nlabs);
45
  std::vector<double> mins(nlabs);
46
  std::vector<double> maxes(nlabs);
47
  std::vector<double> variances(nlabs);
48
  std::vector<double> counts(nlabs);
49
  std::vector<double> volumes(nlabs);
50
  std::vector<double> x(nlabs);
51
  std::vector<double> y(nlabs);
52
  std::vector<double> z(nlabs);
53
  std::vector<double> t(nlabs);
54
  std::vector<double> mass(nlabs,0.0);
55
56
  typename ImageType::SpacingType spacing = image->GetSpacing();
57
  float voxelVolume = 1.0;
58
  for (unsigned int ii = 0; ii < spacing.Size(); ii++)
59
  {
60
    voxelVolume *= spacing[ii];
61
  }
62
63
  std::map<LabelType, LabelType> RoiList;
64
65
  LabelType ii = 0; // counter for label values
66
  for (typename ValidLabelValuesType::const_iterator
67
         labelIterator  = labelStatisticsImageFilter->GetValidLabelValues().begin();
68
         labelIterator != labelStatisticsImageFilter->GetValidLabelValues().end();
69
         ++labelIterator)
70
  {
71
    if ( labelStatisticsImageFilter->HasLabel(*labelIterator) )
72
    {
73
      LabelType labelValue = *labelIterator;
74
      labelvals[ii] = labelValue;
75
      means[ii]     = labelStatisticsImageFilter->GetMean(labelValue);
76
      mins[ii]      = labelStatisticsImageFilter->GetMinimum(labelValue);
77
      maxes[ii]     = labelStatisticsImageFilter->GetMaximum(labelValue);
78
      variances[ii] = labelStatisticsImageFilter->GetVariance(labelValue);
79
      counts[ii]    = labelStatisticsImageFilter->GetCount(labelValue);
80
      volumes[ii]   = labelStatisticsImageFilter->GetCount(labelValue) * voxelVolume;
81
      RoiList[ labelValue ] = ii;
82
    }
83
    ++ii;
84
  }
85
86
  Iterator It( labelImage, labelImage->GetLargestPossibleRegion() );
87
  std::vector<PointType> comvec;
88
  for ( unsigned int i = 0; i < nlabs; i++ )
89
    {
90
    typename ImageType::PointType myCenterOfMass;
91
    myCenterOfMass.Fill(0);
92
    comvec.push_back( myCenterOfMass );
93
    }
94
  for( It.GoToBegin(); !It.IsAtEnd(); ++It )
95
    {
96
    LabelType label = static_cast<LabelType>( It.Get() );
97
    if(  label > 0  )
98
      {
99
      typename ImageType::PointType point;
100
      image->TransformIndexToPhysicalPoint( It.GetIndex(), point );
101
      for( unsigned int i = 0; i < spacing.Size(); i++ )
102
        {
103
        comvec[  RoiList[ label ] ][i] += point[i];
104
        }
105
      mass[  RoiList[ label ] ] += image->GetPixel( It.GetIndex() );
106
      }
107
    }
108
  for ( unsigned int labelcount = 0; labelcount < comvec.size(); labelcount++ )
109
    {
110
    for ( unsigned int k = 0; k < Dimension; k++ )
111
      {
112
      comvec[ labelcount ][k] = comvec[ labelcount ][k] / counts[labelcount];
113
      }
114
    x[labelcount]=comvec[ labelcount ][0];
115
    y[labelcount]=comvec[ labelcount ][1];
116
    if ( Dimension > 2 ) z[labelcount]=comvec[ labelcount ][2];
117
    if ( Dimension > 3 ) t[labelcount]=comvec[ labelcount ][3];
118
    }
119
120
  nb::dict labelStats;
121
  labelStats["LabelValue"] = labelvals;
122
  labelStats["Mean"] = means;
123
  labelStats["Min"] = mins;
124
  labelStats["Max"] = maxes;
125
  labelStats["Variance"] = variances;
126
  labelStats["Count"] = counts;
127
  labelStats["Volume"] = volumes;
128
  labelStats["Mass"] = mass;
129
  labelStats["x"] = x;
130
  labelStats["y"] = y;
131
  labelStats["z"] = z;
132
  labelStats["t"] = t;
133
134
  return (labelStats);
135
}
136
137
template <unsigned int Dimension>
138
nb::dict labelStats(AntsImage<itk::Image<float, Dimension>> & py_image,
139
                    AntsImage<itk::Image<unsigned int, Dimension>> & py_labelImage)
140
{ 
141
  typedef itk::Image<float, Dimension> FloatImageType;
142
  typedef itk::Image<unsigned int, Dimension> IntImageType;
143
  typedef typename FloatImageType::Pointer FloatImagePointerType;
144
  typedef typename IntImageType::Pointer IntImagePointerType;
145
146
147
  FloatImagePointerType myimage = py_image.ptr;
148
  IntImagePointerType mylabelimage = py_labelImage.ptr;
149
150
  return labelStatsHelper<Dimension>( myimage, mylabelimage );
151
}
152
153
void local_labelStats(nb::module_ &m)
154
{
155
  m.def("labelStats2D", &labelStats<2>);
156
  m.def("labelStats3D", &labelStats<3>);
157
  m.def("labelStats4D", &labelStats<4>);
158
}