MorphoGraphX  2.0-1-227
Curvature.hpp
Go to the documentation of this file.
1 //
2 // This file is part of MorphoGraphX - http://www.MorphoGraphX.org
3 // Copyright (C) 2012-2015 Richard S. Smith and collaborators.
4 //
5 // If you use MorphoGraphX in your work, please cite:
6 // http://dx.doi.org/10.7554/eLife.05864
7 //
8 // MorphoGraphX is free software, and is licensed under under the terms of the
9 // GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
10 //
11 #ifndef CURVATURE_H
12 #define CURVATURE_H
13 
14 #include <Config.hpp>
15 
16 #include <Geometry.hpp>
17 #include <Information.hpp>
18 
19 #include <QtCore/QtCore>
20 #include <math.h>
21 #include <string>
22 #include <vector>
23 #include <CImg.h>
24 
25 #define CIMat cimg_library::CImg<float>
26 #define CIMatL cimg_library::CImgList<float>
27 
28 namespace mgx
29 {
31  {
32  public:
33  virtual ~CurvatureMeasure() {
34  }
35  virtual float measure(float ev1, float ev2) = 0;
36  virtual std::string get_type() = 0;
37  virtual CurvatureMeasure* copy() = 0;
38  };
39 
41  public:
42  float measure(float ev1, float ev2) {
43  return ev1 * ev2;
44  }
45  std::string get_type() {
46  return "gaussian";
47  }
48  virtual CurvatureMeasure* copy() {
49  return new GaussianCurvature();
50  }
51  };
52 
54  public:
55  float measure(float ev1, float ev2) {
56  return (ev1 * ev1) + (ev2 * ev2);
57  }
58  std::string get_type() {
59  return "sumsquare";
60  }
61  virtual CurvatureMeasure* copy() {
62  return new SumSquareCurvature();
63  }
64  };
65 
67  public:
68  float measure(float ev1, float ev2) {
69  return sqrt((ev1 * ev1) + (ev2 * ev2));
70  }
71  std::string get_type() {
72  return "rootsumsquare";
73  }
74  virtual CurvatureMeasure* copy() {
75  return new RootSumSquareCurvature();
76  }
77  };
78 
80  public:
81  float measure(float ev1, float ev2) {
82  return (ev1 + ev2) / 2;
83  }
84  std::string get_type() {
85  return "average";
86  }
87  virtual CurvatureMeasure* copy() {
88  return new AverageCurvature();
89  }
90  };
91 
93  public:
94  float measure(float ev1, float ev2) {
95  return std::min(ev1, ev2);
96  }
97  std::string get_type() {
98  return "minimal";
99  }
100  virtual CurvatureMeasure* copy() {
101  return new MinimalCurvature();
102  }
103  };
104 
106  public:
107  float measure(float ev1, float ev2) {
108  return std::max(ev1, ev2);
109  }
110  std::string get_type() {
111  return "maximal";
112  }
113  virtual CurvatureMeasure* copy() {
114  return new MaximalCurvature();
115  }
116  };
117 
119  public:
120  float measure(float ev1, float ev2) {
121  return std::min(ev1, ev2);
122  }
123  std::string get_type() {
124  return "minimal";
125  }
126  virtual CurvatureMeasure* copy() {
127  return new MinimalAbsCurvature();
128  }
129  };
130 
132  public:
133  float measure(float ev1, float ev2) {
134  return std::max(ev1, ev2);
135  }
136  std::string get_type() {
137  return "maximal";
138  }
139  virtual CurvatureMeasure* copy() {
140  return new MaximalAbsCurvature();
141  }
142  };
144  public:
145  float measure(float ev1, float ev2) {
146  return ev1 / ev2;
147  }
148  std::string get_type() {
149  return "anisotropy";
150  }
151  virtual CurvatureMeasure* copy() {
152  return new AnisotropyCurvature();
153  }
154  };
155 
157  public:
158  float measure(float ev1, float ev2) {
159  return (ev1 * ev2 < 0 ? -1.0f : 1.0f) * (fabs(ev1) + fabs(ev2)) / 2.0f;
160  }
161  std::string get_type() {
162  return "signedaverageabs";
163  }
164  virtual CurvatureMeasure* copy() {
165  return new SignedAverageAbsCurvature();
166  }
167  };
168 
169  class Curvature {
170  public:
171  // default constructor
172  Curvature() : W(2, 2), ev1(0), ev2(0)
173  {
174  cM = new AverageCurvature();
175  }
176 
177  // convenience constructor
178  Curvature(std::string s) : W(2, 2), ev1(0), ev2(0)
179  {
180  if(s == "gaussian")
181  cM = new GaussianCurvature();
182  else if(s == "average")
183  cM = new AverageCurvature();
184  else if(s == "minimal")
185  cM = new MinimalCurvature();
186  else if(s == "maximal")
187  cM = new MaximalCurvature();
188  else if(s == "sumsquare")
189  cM = new SumSquareCurvature();
190  else if(s == "rootsumsquare")
191  cM = new RootSumSquareCurvature();
192  else if(s == "signedaverageabs")
193  cM = new SignedAverageAbsCurvature();
194  else if(s == "anisotropy")
195  cM = new AnisotropyCurvature();
196  else
197  cM = new AverageCurvature();
198  }
199 
200  Curvature(const Curvature& copy)
201  : W(copy.W), b1(copy.b1), b2(copy.b2), b3(copy.b3), ed1(copy.ed1), ed2(copy.ed2), ev1(copy.ev1), ev2(copy.ev2), cM(0)
202  {
203  if(copy.cM)
204  cM = copy.cM->copy();
205  }
206 
208  delete cM;
209  }
210 
211  // update the curvature object, first entry of pos and norm must be the position, surface normal of the point of
212  // interest
213  void update(const std::vector<Point3f>& pos, const std::vector<Point3f>& nrml)
214  {
215 
216  try {
217  if(nrml.size() > 0 && nrml.size() == pos.size()) {
218 
219  // Calculate local Coordinate system
220  update_local_Basis(nrml[0]);
221 
222  // Set up Least Square Problem
223  int cnt = pos.size();
224  CIMat X = CIMat(7, 3 * (cnt - 1));
225  CIMat b = CIMat(1, 3 * (cnt - 1));
226  Point3f vpos = pos[0];
227  int id = 0;
228 
229  for(int i = 1; i < cnt; i++) {
230  // Transform into local coordinates
231  Point3f vw = pos[i] - vpos;
232  float w1 = vw * b1;
233  float w2 = vw * b2;
234  float w3 = vw * b3;
235 
236  // Transform into local coordinates
237  float n1, n2, n3;
238  n1 = nrml[i] * b1;
239  n2 = nrml[i] * b2;
240  n3 = nrml[i] * b3;
241 
242  X(0, id) = 0.5 * w1 * w1;
243  X(1, id) = w1 * w2;
244  X(2, id) = 0.5 * w2 * w2;
245  X(3, id) = w1 * w1 * w1;
246  X(4, id) = w1 * w1 * w2;
247  X(5, id) = w1 * w2 * w2;
248  X(6, id) = w2 * w2 * w2;
249  b(id) = w3;
250  id++;
251 
252  X(0, id) = w1;
253  X(1, id) = w2;
254  X(2, id) = 0;
255  X(3, id) = 3 * w1 * w1;
256  X(4, id) = 2 * w1 * w2;
257  X(5, id) = w2 * w2;
258  X(6, id) = 0;
259  b(id) = -n1 / n3;
260  id++;
261 
262  X(0, id) = 0;
263  X(1, id) = w1;
264  X(2, id) = w2;
265  X(3, id) = 0;
266  X(4, id) = w1 * w1;
267  X(5, id) = 2 * w1 * w2;
268  X(6, id) = 3 * w2 * w2;
269  b(id) = -n2 / n3;
270  id++;
271  }
272  CIMat Xt = X.get_transpose();
273 
274  CIMat Q = Xt * X;
275 
276  b = Xt * b;
277 
278  float det = Q.det();
279  if(!isNan(det) && !(det == 0)) {
280  // solve least-squares problem
281  b.solve(Q);
282 
283  // update Weingarten-matrix
284  W(0, 0) = b[0];
285  W(1, 0) = W(0, 1) = b[1];
286  W(1, 1) = b[2];
287 
288  // calculate eigenvalues and eigenvectors
289  CIMatL bL = W.get_symmetric_eigen();
290  ev1 = - bL(0)(0, 0);// ALR: bulges in direction of increasing Z should be positive
291  ev2 = - bL(0)(1, 0);// Sorry Pierre, it makes more sense this way!
292  ed1 = - bL(1)(0, 0) * b1 - bL(1)(0, 1) * b2;
293  ed2 = - bL(1)(1, 0) * b1 - bL(1)(1, 1) * b2;
294  if(ev1 < ev2) {
295  using std::swap;
296  swap(ev1, ev2);
297  swap(ed1, ed2);
298  }
299  }
300  }
301  return;
302  }
303  catch(...) {
304  Information::out << "Error calculating curvature" << endl;
305  }
306  }
307 
308  // get principal directions of curvature
309  void get_eigenVectors(Point3f& evec1, Point3f& evec2)
310  {
311  evec1 = ed1;
312  evec2 = ed2;
313  return;
314  }
315 
316  // get principal directions of curvature
317  void get_eigenValues(float& eval1, float& eval2)
318  {
319  eval1 = ev1;
320  eval2 = ev2;
321  return;
322  }
323 
324  // calculate a single-valued measure of curvature (for example "gaussian")
325  float get_curvature() {
326  return cM->measure(ev1, ev2);
327  }
328 
329  // get the name of the curvature measure (for example "gaussian")
330  std::string get_type() {
331  return cM->get_type();
332  }
333 
334  // set the curvature measure
336  {
337  if(cM)
338  delete cM;
339  cM = _cM;
340  return;
341  }
342 
343  private:
344  // calculate local basis with b1,b2, in-plane and b3 out-of-plane basis vectors
345  void update_local_Basis(Point3f nrml)
346  {
347  nrml = nrml / nrml.norm();
348  do {
349  b1 = Point3f(cimg_library::cimg::rand(), cimg_library::cimg::rand(), cimg_library::cimg::rand());
350  b1 = b1 / b1.norm();
351  } while(fabs(b1 * nrml) == 1);
352  b1 = b1 - (b1 * nrml) * nrml;
353  b1 = b1 / b1.norm();
354  b2 = b1.cross(nrml);
355  b3 = nrml;
356 
357  return;
358  }
359 
360  // Weingarten Matrix
361  CIMat W;
362 
363  // Local Basis Vectors
364  Point3f b1;
365  Point3f b2;
366  Point3f b3;
367 
368  // Principal directions of curvature
369  Point3f ed1;
370  Point3f ed2;
371 
372  // Principal values of curvature
373  float ev1;
374  float ev2;
375 
376  CurvatureMeasure* cM;
377  };
378 }
379 #endif
mgx::GaussianCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:42
mgx::MinimalCurvature
Definition: Curvature.hpp:92
mgx::AnisotropyCurvature
Definition: Curvature.hpp:143
mgx::CurvatureMeasure
Definition: Curvature.hpp:30
mgx::AverageCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:87
mgx::MaximalAbsCurvature
Definition: Curvature.hpp:131
mgx::MaximalCurvature
Definition: Curvature.hpp:105
mgx::MinimalAbsCurvature
Definition: Curvature.hpp:118
Information.hpp
mgx::RootSumSquareCurvature
Definition: Curvature.hpp:66
mgx::AnisotropyCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:151
mgx::AnisotropyCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:145
mgx::GaussianCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:48
mgx::GaussianCurvature
Definition: Curvature.hpp:40
mgx::Vector::norm
CU_HOST_DEVICE T norm() const
Euclidean norm of the vector.
Definition: Vector.hpp:591
mgx::SumSquareCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:61
CIMat
#define CIMat
Definition: Curvature.hpp:25
mgx::MinimalAbsCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:126
CIMatL
#define CIMatL
Definition: Curvature.hpp:26
mgx::MinimalAbsCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:120
mgx::Curvature::get_type
std::string get_type()
Definition: Curvature.hpp:330
mgx::MaximalCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:107
mgx::Curvature::update
void update(const std::vector< Point3f > &pos, const std::vector< Point3f > &nrml)
Definition: Curvature.hpp:213
Geometry.hpp
mgx::MinimalCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:97
mgx
Distributed matrix library.
Definition: Assert.hpp:26
mgx::Curvature
Definition: Curvature.hpp:169
mgx::swap
void swap(multiset_vector< Key, Compare, Allocator > &v1, multiset_vector< Key, Compare, Allocator > &v2)
Definition: SetVector.hpp:543
mgx::AverageCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:84
mgx::MaximalAbsCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:136
mgx::RootSumSquareCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:71
mgx::Curvature::~Curvature
~Curvature()
Definition: Curvature.hpp:207
mgx::max
T CU_HOST_DEVICE max(const T a, const T b)
Definition: Util.hpp:34
mgx::Point3f
Vector< 3, float > Point3f
Definition: CuttingSurface.hpp:25
mgx::nrml
nrml
Definition: Geometry.hpp:240
mgx::MinimalCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:100
mgx::Curvature::set_Measure
void set_Measure(CurvatureMeasure *_cM)
Definition: Curvature.hpp:335
mgx::RootSumSquareCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:74
mgx::GaussianCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:45
mgx::Vector::cross
CU_HOST_DEVICE Vector cross(const Vector &other) const
Compute the cross product as this x other.
Definition: Vector.hpp:711
mgx::MaximalAbsCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:139
mgx::det
CU_HOST_DEVICE T det(const Matrix< 1, 1, T > &mat)
Definition: Matrix.hpp:946
mgx::Curvature::get_eigenVectors
void get_eigenVectors(Point3f &evec1, Point3f &evec2)
Definition: Curvature.hpp:309
mgx::CurvatureMeasure::measure
virtual float measure(float ev1, float ev2)=0
mgx::Curvature::get_eigenValues
void get_eigenValues(float &eval1, float &eval2)
Definition: Curvature.hpp:317
mgx::SignedAverageAbsCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:164
mgx::MaximalAbsCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:133
mgx::CurvatureMeasure::copy
virtual CurvatureMeasure * copy()=0
mgx::MaximalCurvature::copy
virtual CurvatureMeasure * copy()
Definition: Curvature.hpp:113
mgx::SignedAverageAbsCurvature
Definition: Curvature.hpp:156
mgx::Curvature::Curvature
Curvature(const Curvature &copy)
Definition: Curvature.hpp:200
mgx::X
@ X
Definition: Cuda.hpp:71
mgx::Information::out
mgx_EXPORT QTextStream out
mgx::MinimalAbsCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:123
mgx::SumSquareCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:55
mgx::Vector< 3, float >
mgx::CurvatureMeasure::~CurvatureMeasure
virtual ~CurvatureMeasure()
Definition: Curvature.hpp:33
mgx::SignedAverageAbsCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:161
mgx::min
CU_HOST_DEVICE T min(const T a, const T b)
Definition: Util.hpp:26
mgx::MinimalCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:94
mgx::Curvature::Curvature
Curvature(std::string s)
Definition: Curvature.hpp:178
mgx::SumSquareCurvature
Definition: Curvature.hpp:53
mgx::MaximalCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:110
mgx::SignedAverageAbsCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:158
mgx::Curvature::get_curvature
float get_curvature()
Definition: Curvature.hpp:325
mgx::SumSquareCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:58
mgx::AverageCurvature
Definition: Curvature.hpp:79
mgx::AverageCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:81
mgx::CurvatureMeasure::get_type
virtual std::string get_type()=0
mgx::Curvature::Curvature
Curvature()
Definition: Curvature.hpp:172
mgx::isNan
CU_HOST_DEVICE bool isNan(float s)
Definition: Geometry.hpp:148
mgx::AnisotropyCurvature::get_type
std::string get_type()
Definition: Curvature.hpp:148
mgx::RootSumSquareCurvature::measure
float measure(float ev1, float ev2)
Definition: Curvature.hpp:68