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

Switch to unified view

a b/src/reorientImage.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 <exception>
11
#include <vector>
12
#include <string>
13
14
#include "itkAffineTransform.h"
15
#include "itkImage.h"
16
#include "itkImageFileWriter.h"
17
#include "itkImageMomentsCalculator.h"
18
#include "itkResampleImageFilter.h"
19
#include "itkTransformFileWriter.h"
20
#include "vnl/vnl_inverse.h"
21
22
#include "antsImage.h"
23
24
namespace nb = nanobind;
25
using namespace nb::literals;
26
27
/*
28
template< unsigned int ImageDimension >
29
int antsReoHelper(
30
  typename itk::Image< float , ImageDimension >::Pointer image1,
31
  std::string txfn, std::vector<int> axis , std::vector<int> axis2,
32
  std::vector<int> doReflection, std::vector<int> doScale )
33
{
34
  typedef double RealType;
35
  typedef itk::Image< float , ImageDimension > ImageType;
36
37
  typedef typename itk::ImageMomentsCalculator<ImageType> ImageCalculatorType;
38
  typedef itk::AffineTransform<RealType, ImageDimension> AffineType;
39
  typedef typename ImageCalculatorType::MatrixType       MatrixType;
40
  typedef itk::Vector<float, ImageDimension>  VectorType;
41
  VectorType ccg1;
42
  VectorType cpm1;
43
  MatrixType cpa1;
44
  VectorType ccg2;
45
  VectorType cpm2;
46
  MatrixType cpa2;
47
  typename ImageCalculatorType::Pointer calculator1 =
48
    ImageCalculatorType::New();
49
  calculator1->SetImage(  image1 );
50
  typename ImageCalculatorType::VectorType fixed_center;
51
  fixed_center.Fill(0);
52
53
  // was a try-catch block around this in ANTsR
54
  calculator1->Compute();
55
  fixed_center = calculator1->GetCenterOfGravity();
56
  ccg1 = calculator1->GetCenterOfGravity();
57
  cpm1 = calculator1->GetPrincipalMoments();
58
  cpa1 = calculator1->GetPrincipalAxes();
59
60
  unsigned int eigind1 = 1;
61
  unsigned int eigind2 = 1;
62
  typedef vnl_vector<RealType> EVectorType;
63
  typedef vnl_matrix<RealType> EMatrixType;
64
  EVectorType evec1_2ndary = cpa1.GetVnlMatrix().get_row( eigind2 );
65
  EVectorType evec1_primary = cpa1.GetVnlMatrix().get_row( eigind1 );
66
  EVectorType evec2_2ndary;
67
  evec2_2ndary.set_size( ImageDimension );
68
  evec2_2ndary.fill(0);
69
  EVectorType evec2_primary;
70
  evec2_primary.set_size( ImageDimension );
71
  evec2_primary.fill(0);
72
  for ( unsigned int i = 0; i < ImageDimension; i++ )
73
    evec2_primary[i] = axis[i];
74
  // Solve Wahba's problem http://en.wikipedia.org/wiki/Wahba%27s_problem
75
  EMatrixType B = outer_product( evec2_primary, evec1_primary );
76
  if( ImageDimension == 3 )
77
    {
78
    for ( unsigned int i = 0; i < ImageDimension; i++ )
79
        evec2_primary[i] = axis2[i];
80
    B = outer_product( evec2_2ndary, evec1_2ndary )
81
      + outer_product( evec2_primary, evec1_primary );
82
    }
83
    vnl_svd<RealType>    wahba( B );
84
    vnl_matrix<RealType> A_solution = wahba.V() * wahba.U().transpose();
85
    A_solution = vnl_inverse( A_solution );
86
    RealType det = vnl_determinant( A_solution  );
87
    if( det < 0 )
88
      {
89
      vnl_matrix<RealType> id( A_solution );
90
      id.set_identity();
91
      for( unsigned int i = 0; i < ImageDimension; i++ )
92
        {
93
        if( A_solution( i, i ) < 0 )
94
          {
95
          id( i, i ) = -1.0;
96
          }
97
        }
98
        A_solution =  A_solution * id.transpose();
99
      }
100
    if ( doReflection[0] == 1 ||  doReflection[0] == 3 )
101
      {
102
      vnl_matrix<RealType> id( A_solution );
103
      id.set_identity();
104
      id = id - 2.0 * outer_product( evec2_primary , evec2_primary  );
105
      A_solution = A_solution * id;
106
      }
107
    if ( doReflection[0] > 1 )
108
      {
109
      vnl_matrix<RealType> id( A_solution );
110
      id.set_identity();
111
      id = id - 2.0 * outer_product( evec1_primary , evec1_primary  );
112
      A_solution = A_solution * id;
113
      }
114
    if ( doScale[0] > 0 )
115
      {
116
      vnl_matrix<RealType> id( A_solution );
117
      id.set_identity();
118
      id = id * doScale[0];
119
      A_solution = A_solution * id;
120
      }
121
    det = vnl_determinant( A_solution  );
122
    std::cout << " det " << det << std::endl;
123
    std::cout << " A_solution " << std::endl;
124
    std::cout << A_solution << std::endl;
125
    typename AffineType::Pointer affine1 = AffineType::New();
126
    typename AffineType::OffsetType trans = affine1->GetOffset();
127
    itk::Point<RealType, ImageDimension> trans2;
128
    trans2.Fill(0);
129
    for( unsigned int i = 0; i < ImageDimension; i++ )
130
      {
131
      trans2[i] =  fixed_center[i] * ( 1 );
132
      }
133
    affine1->SetIdentity();
134
    affine1->SetOffset( trans );
135
    affine1->SetMatrix( A_solution );
136
    affine1->SetCenter( trans2 );
137
    // write tx
138
    typedef itk::TransformFileWriter TransformWriterType;
139
    typename TransformWriterType::Pointer transformWriter = TransformWriterType::New();
140
    transformWriter->SetInput( affine1 );
141
    transformWriter->SetFileName( txfn.c_str() );
142
    transformWriter->Update();
143
144
  return 0;
145
146
}
147
148
template <typename ImageType, unsigned int Dimension>
149
int reorientImage(  py::capsule in_image, std::string txfn,
150
                      std::vector<int> axis1, std::vector<int> axis2,
151
                      std::vector<int> rrfl, std::vector<int> rscl )
152
{
153
  typedef typename ImageType::Pointer ImagePointerType;
154
  ImagePointerType itk_image = as<ImageType>( in_image );
155
  antsReoHelper<Dimension>( itk_image, txfn, axis1, axis2, rrfl, rscl );
156
157
  return 0;
158
}
159
160
*/
161
162
163
template <typename ImageType, unsigned int Dimension>
164
std::vector<double> centerOfMass( AntsImage<ImageType> & image  )
165
{
166
  typedef typename ImageType::Pointer ImagePointerType;
167
  ImagePointerType itkimage = image.ptr;
168
169
  typedef typename itk::ImageMomentsCalculator<ImageType> ImageCalculatorType;
170
  typename ImageCalculatorType::VectorType com( Dimension );
171
  com.Fill( 0 );
172
173
  std::vector<double> myCoM( Dimension );
174
175
  typename ImageCalculatorType::Pointer calculator1 = ImageCalculatorType::New();
176
  calculator1->SetImage( itkimage );
177
  calculator1->Compute();
178
  com = calculator1->GetCenterOfGravity();
179
180
  for ( unsigned int k = 0; k < Dimension; k++ )
181
  {
182
    myCoM[ k ] = com[ k ];
183
  }
184
185
  return myCoM;
186
}
187
188
void local_reorientImage(nb::module_ &m)
189
{
190
//  m.def("reorientImageF2", &reorientImage<itk::Image<float, 2>, 2>);
191
//  m.def("reorientImageF3", &reorientImage<itk::Image<float, 3>, 3>);
192
//  m.def("reorientImageF4", &reorientImage<itk::Image<float, 4>, 4>);
193
194
  m.def("centerOfMass", &centerOfMass<itk::Image<float, 2>, 2>);
195
  m.def("centerOfMass", &centerOfMass<itk::Image<float, 3>, 3>);
196
  m.def("centerOfMass", &centerOfMass<itk::Image<float, 4>, 4>);
197
}