forked from ANTsX/ANTs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitkSurfaceCurvatureBase.h
287 lines (216 loc) · 8.27 KB
/
itkSurfaceCurvatureBase.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/*=========================================================================
Program: Advanced Normalization Tools
Module: $RCSfile: itkSurfaceCurvatureBase.h,v $
Language: C++
Date: $Date: 2008/11/15 23:46:06 $
Version: $Revision: 1.12 $
Copyright (c) ConsortiumOfANTS. All rights reserved.
See accompanying COPYING.txt or
http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef _SurfaceCurvatureBase_h
#define _SurfaceCurvatureBase_h
#include <vnl/vnl_matops.h>
#include <vnl/algo/vnl_svd.h>
#include <vnl/algo/vnl_symmetric_eigensystem.h>
#include <vnl/vnl_cross.h>
// #include <vnl/algo/vnl_rpoly_roots.h>
#include "itkObject.h"
#include "itkProcessObject.h"
#include "itkVectorContainer.h"
#include "itkCastImageFilter.h"
namespace itk
{
/** \class SurfaceCurvatureBase
*
* This class takes a surface as input and creates a local
* geometric frame for each surface point.
*
* \note The origin of a neighborhood is always taken to be
* the first point entered into and the
* last point stored in the list.
*/
template <typename TSurface, unsigned int TDimension = 3>
class SurfaceCurvatureBase : public ProcessObject
{
public:
/** Standard class typedefs. */
typedef SurfaceCurvatureBase Self;
typedef ProcessObject Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(SurfaceCurvatureBase, ProcessObject);
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Image types. */
typedef TSurface SurfaceType;
/** Image dimension. */
// itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension);
itkStaticConstMacro(ImageDimension, unsigned int, TDimension);
itkStaticConstMacro(SurfaceDimension, unsigned int, TDimension);
typedef float RealType;
typedef vnl_vector<RealType> VectorType;
typedef vnl_vector_fixed<RealType, itkGetStaticConstMacro(ImageDimension)>
FixedVectorType;
typedef vnl_vector_fixed<RealType, itkGetStaticConstMacro(ImageDimension)>
PointType;
typedef vnl_matrix<double> MatrixType;
typedef std::vector<PointType> PointContainerType;
typedef std::vector<float> FunctionContainerType;
/** Set input parameter file */
itkSetStringMacro( ParameterFileName );
/** Set input parameter file */
itkGetStringMacro( ParameterFileName );
/** Fill the point list with the points neighboring the current origin */
virtual void FindNeighborhood(unsigned int temp = 0);
/** A Euclidean relative of L.D. Griffin's compactness.*/
RealType ComputeMeanEuclideanDistance();
/** */
void ComputeAveragePoint();
void ProjectToTangentPlane(PointType);
void EigenDecomposition(MatrixType D);
/** Estimate the plane tangent to a point using the neighborhood
* of the point. This is, in general, an over-constrained least
* squares fitting problem.
*/
void EstimateTangentPlane(PointType);
void WeightedEstimateTangentPlane(PointType);
void TestEstimateTangentPlane(PointType);
/** This function sets the reference tangent arbitrarily.
* It can be overridden in case there is a better practical approach.
*/
void ChooseReferenceTangent();
/** This function fills the weight and angle vectors for
* a given neighborhood.
*/
virtual void ComputeWeightsAndDirectionalKappaAndAngles(PointType origin);
/** */
void ComputeFrame(PointType origin);
/** */
void ComputeFrameAndKappa(PointType origin);
void ShimshoniFrame(PointType origin);
/** */
void ComputeJoshiFrame(PointType origin);
/** */
void EstimateCurvature(RealType w1 = 3. / 8., RealType w2 = 1. / 8., RealType w3 = 1. / 8., RealType w4 = 3. / 8.);
/** Use the Besl and Jain analytical curvature computation.
* We use a least square polynomial fit to the local neighborhood
* to estimate the mean and gaussian curvature.
*/
void JainMeanAndGaussianCurvature(PointType);
/** This function returns a weight given a distance
* It may be the identity function, a normalization
* or a gaussianization of the input distance. */
virtual RealType GetWeight(PointType, PointType);
/** This function returns the angle between the reference tangent
and the projection onto the tangent plane of the vector between
the neighborhood focus and its neighbor. */
virtual RealType GetTheta(PointType Neighbor, PointType origin);
/** Estimate the directional curvature using Shimshoni's method (eq 6).*/
virtual void EstimateDirectionalCurvature(PointType, PointType);
void PrintFrame();
virtual void ComputeFrameOverDomain(unsigned int which = 3)
{
};
RealType ErrorEstimate(PointType, RealType sign = 1.0 );
unsigned int CharacterizeSurface();
itkSetMacro(Origin, PointType);
itkGetMacro(Origin, PointType);
itkSetMacro(AveragePoint, PointType);
itkGetMacro(AveragePoint, PointType);
itkGetMacro(Normal, FixedVectorType);
itkGetMacro(Sigma, RealType);
itkGetMacro(MeanKappa, RealType);
itkSetMacro(Sigma, RealType);
itkGetMacro(UseGeodesicNeighborhood, bool);
itkSetMacro(UseGeodesicNeighborhood, bool);
/** Set normal estimates a 3D frame from a given normal */
void SetFrameFromNormal(FixedVectorType);
/** We use the cross-product of the tangents times the image spacing
to get the local area. */
RealType ComputeLocalArea(const double* spacing);
/** We estimate the integral as a sum, assuming the local
area (from compute local area) scales the value of the
function at the pixel. See http://mathworld.wolfram.com/SurfaceIntegral.html*/
virtual RealType IntegrateFunctionOverNeighborhood(bool norm = false)
{
return 0;
}
void SwitchNormalSign()
{
m_Normal *= (-1.0);
}
// for conjugate harmonic function
float dstarUestimate();
// get this from the local frame - 1st order vs 2nd order shape operator
void EstimateMetricTensor();
protected:
SurfaceCurvatureBase();
virtual ~SurfaceCurvatureBase()
{
};
/** Holds the value of Pi. */
double m_Pi;
bool m_Debug;
/** Data structures to contain points. */
PointContainerType m_PointList;
/** Data structures to contain function
values associated with points. */
FunctionContainerType m_FunctionValueList;
/** This list contains the projection of the vectors onto
the tangent plane (T_i Shimshoni). */
PointContainerType m_TangentProjectionList;
/** The point that is the origin of the current neighborhood. */
PointType m_Origin;
PointType m_AveragePoint;
PointType m_PlaneVector;
/** Data that represents single vectors */
FixedVectorType m_ArbitraryTangent;
FixedVectorType m_Normal;
FixedVectorType m_Tangent1;
FixedVectorType m_Tangent2;
RealType m_dX; // size in local x dir
RealType m_dY; // size in local y dir
FixedVectorType m_MetricTensor;
VectorType m_ThetaVector;
VectorType m_WeightVector;
VectorType m_DirectionalKappaVector;
/** Data for representing neighborhoods and derived from the vector frames*/
/** Approximate directional curvature */
RealType m_DirectionalKappa;
RealType m_MetricTensorDeterminant;
/** Approximate principal curvature 1*/
RealType m_Kappa1;
/** Approximate principal curvature 2*/
RealType m_Kappa2;
RealType m_GaussianKappa;
RealType m_MeanKappa;
/** Solution weights eq. (7) (8) Shimshoni */
RealType m_A;
RealType m_B;
RealType m_C;
/** True Eigenvector weights */
RealType m_W1;
RealType m_W2;
/** Eigenvalues */
RealType m_Eval0;
RealType m_Eval1;
RealType m_Eval2;
unsigned int m_CurrentNeighborhoodPointIndex;
std::string m_ParameterFileName;
/** We use this to avoid computing the frame in degenerate cases. */
RealType m_TotalDKap;
RealType m_TotalArea;
RealType m_Sigma;
bool m_UseGeodesicNeighborhood;
private:
};
} // namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkSurfaceCurvatureBase.txx"
#endif
#endif