aimsalgo 6.0.0
Neuroimaging image processing
projection.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34
35#ifndef AIMS_DISTANCEMAP_PROJECTION_H
36#define AIMS_DISTANCEMAP_PROJECTION_H
37
38#include <cstdlib>
39#include <aims/mesh/texture.h>
40#include <aims/mesh/surface.h>
41#include <cartodata/volume/volume.h>
42#include <aims/connectivity/connectivity.h>
44#include <aims/math/gausslu.h>
45#include <aims/math/eigen.h>
46#include <set>
47#include <list>
48#include <map>
49#include <float.h>
50
51
52class Graph;
53namespace aims
54{
55 namespace meshdistance
56 {
57
58
64 TimeTexture<short>
66 const Texture<float> & curvtex,
67 const carto::rc_ptr<carto::Volume<short> > & bottom_vol,
68 const carto::rc_ptr<carto::Volume<short> > & surface_vol,
69 float alpha, float dmin,
70 int MINCC,
71 const std::map <short,std::string> & trans,
72 const std::set<std::string> & labels,
73 float maxdil,float maxdil_mesh,float alpha_reg,
74 bool connexity,
75 const std::vector<std::list<unsigned> > & neigho);
79 const carto::rc_ptr<carto::Volume<short> > & bottom_vol,
80 const carto::rc_ptr<carto::Volume<short> > & surface_vol,
81 const Point3df & CA,
82 float demin,float dpmin,
83 int MINCC,
84 const std::map <short,std::string> & trans,
85 const std::set<std::string> & labels,
86 float maxdil,float maxdil_mesh,float alpha_reg,
87 bool connexity,
88 const std::vector<std::list<unsigned> > & neigho);
89
90
94 const carto::rc_ptr<carto::Volume<short> > &sulcvol,
95 const AimsSurface<3,Void> & mesh,
96 std::set<short> &cc_sulci_labels,
97 std::map<short,short > &tri_sulci,
98 std::map<unsigned, Point3dfSet > &cc_sulci_coord,
99 std::map<Point3df, Point3df,
100 Point3dfCompare > &initend,
101 const Texture<float> &curvtex,
102 float alpha,float dmin);
103
106 ( const carto::rc_ptr<carto::Volume<short> > &ccvol,
107 const carto::rc_ptr<carto::Volume<short> > &sulcvol,
108 const AimsSurface<3,Void> & mesh,
109 std::set<short> &cc_sulci_labels,
110 std::map<short,short > &tri_sulci,
111 const std::map<Point3df, Point3dfSet,
112 Point3dfCompare > &neigh,
113 std::map<unsigned, Point3dfSet > &cc_sulci_coord,
114 std::map<Point3df, Point3df, Point3dfCompare > &initend,
115 float demin, float dpmin,
116 short label_insula_left,short label_insula_right,
117 const Point3df & CA );
118
119 void
121 const AimsSurface<3,Void> & mesh,
122 const std::map<Point3df, Point3df, Point3dfCompare >
123 &initend,
124 const Point3dfSet &setpointi,
125 short label,
126 float dmin,float alpha_reg );
127
129 const carto::rc_ptr<carto::Volume<short> > &initVol,
130 const Texture<short> &tex,
131 const AimsSurface<3,Void> & mesh,
132 short val_domain,
133 short back);
134
137 const carto::rc_ptr<carto::Volume<short> > &initVol,
138 const AimsSurface<3,Void> & mesh,
139 short back);
140
143 void
144 NeighbourInCC( std::map<Point3df, Point3dfSet, Point3dfCompare > &neigh,
145 const carto::rc_ptr<carto::Volume<short> > & bvol,
146 const carto::rc_ptr<carto::Volume<short> > & svol,
147 Connectivity::Type connectivity,
148 short label, const unsigned size_neigh,
149 unsigned max_points = 50);
150
151
152
153 //inline functions
154
155 //first : barycenter of the input pt
156 //second : normal vector
157
158 inline std::pair<Point3df,Point3df> NormalFromPoints( const Point3dfSet & init_point )
159 {
160 std::pair<Point3df,Point3df> output;
161 unsigned inc = 0, i=0,j=0,n = init_point.size();
162 Point3df mean = Point3df(0,0,0),temp;
163 Point3dfSet norm_point;
164 carto::VolumeRef<float> cov( 3, 3, 1, 1,
165 carto::AllocatorContext::fast() );
166 Point3dfSet::const_iterator is,es;
167
168 for (is = init_point.begin(), es = init_point.end(); is != es; ++is)
169 mean += *is;
170
171 mean = mean / (float)n;
172
173 for (is = init_point.begin(), es = init_point.end(); is != es; ++is,
174 ++inc)
175 norm_point.insert(*is - mean);
176
177 cov = 0;
178 for (is = norm_point.begin(), es = norm_point.end(); is != es; ++is,
179 ++inc)
180 {
181 temp = *is;
182 for (i=0; i<3; ++i)
183 for (j=0; j<3; ++j)
184 cov(i,j) += temp[i] * temp[j];
185 }
186 AimsEigen< float > eigen;
187 carto::VolumeRef< float > value = eigen.doit( cov );
188
189 eigen.sort(cov,value);
190
191 temp[0] = cov(0,2);
192 temp[1] = cov(1,2);
193 temp[2] = cov(2,2);
194
195 temp.normalize();
196 output.second = temp;
197 output.first = mean;
198
199 return(output);
200 }
201
202 //Point3df : normal vector to the plane passing through pt
204 const Point3dfSet & init_point )
205 {
206 unsigned inc = 0, i=0,j=0;
207 Point3df temp;
208 Point3dfSet norm_point;
209 carto::VolumeRef<float> cov( 3, 3, 1, 1,
210 carto::AllocatorContext::fast() );
211 Point3dfSet::const_iterator is,es;
212
213 for( is = init_point.begin(), es = init_point.end(); is != es;
214 ++is, ++inc)
215 norm_point.insert(*is - pt);
216
217 cov = 0;
218 for( is = norm_point.begin(), es = norm_point.end(); is != es;
219 ++is, ++inc)
220 {
221 temp = *is;
222 for (i=0; i<3; ++i)
223 for (j=0; j<3; ++j)
224 cov(i,j) += temp[i] * temp[j];
225 }
226 AimsEigen< float > eigen;
227 carto::VolumeRef< float > value = eigen.doit( cov );
228
229 eigen.sort(cov,value);
230
231 temp[0] = cov(0,2);
232 temp[1] = cov(1,2);
233 temp[2] = cov(2,2);
234
235 temp.normalize();
236
237
238 return(temp);
239 }
240
241 inline Point3df cross(const Point3df &A, const Point3df &B)
242 {
243 Point3df C;
244 C[0] = A[1] * B[2] - A[2] * B[1];
245 C[1] = A[2] * B[0] - A[0] * B[2];
246 C[2] = A[0] * B[1] - A[1] * B[0];
247 return (C);
248
249 }
250
251
252 //Give the point of intersection
253 //between a line
254 //(defined by a point 'pt'
255 //and a direction 'direction_line' )
256 // and a plane
257 //(defined by 3 points s1, s2, s3)
259 const Point3df &s1,const Point3df &s2, const Point3df &s3,
260 const Point3df & direction_line, const Point3df & pt )
261 {
262 float a0, b0, c0;
263 float xb,yb,zb;
264 float a,b,c;
265 float xm,ym,zm;
266 Point3df pt_intersection, normal_tri;
267
268
269 ASSERT(direction_line != Point3df(0,0,0));
270 normal_tri = cross(s1 - s2,s1 - s3);
271 normal_tri.normalize();
272
273 //mesh triangle normal
274 a0 = normal_tri[0];
275 b0 = normal_tri[1];
276 c0 = normal_tri[2];
277
278 //one node of the triangle
279 xb = s1[0];
280 yb = s1[1];
281 zb = s1[2];
282
283 //direction of the line
284 a = direction_line[0];
285 b = direction_line[1];
286 c = direction_line[2];
287
288 //coord of the pt defining the line
289 xm = pt[0];
290 ym = pt[1];
291 zm = pt[2];
292
293 pt_intersection[0] = (c * c0 * xm +
294 a * c0 * zb -
295 a * b0 * ym +
296 a * a0 * xb +
297 a * b0 * yb +
298 b0 * b * xm -
299 c0 * a * zm) /
300 ( c * c0 + a * a0 + b0 * b);
301
302
303 pt_intersection[1] = ( b * c0 * zb +
304 b * a0 * xb +
305 b * b0 * yb -
306 b * xm * a0 +
307 c * ym * c0 +
308 ym * a * a0 -
309 b * zm * c0 ) /
310 (c * c0 + a * a0 + b0 * b);
311
312 pt_intersection[2] = ( c * c0 * zb
313 - b0 * c * ym
314 + c * a0 * xb
315 + c * b0 * yb
316 + a * zm * a0
317 + b0 * b * zm
318 - c * xm * a0 ) /
319 (c * c0 + a * a0 + b0 * b);
320
321 return (pt_intersection);
322 }
323
324
325 /* Distance from a point (A) to the plane defined by
326 one of its point : bipoint.first
327 its normal (norm = 1): bipoint.second */
328 inline float DistancePointToPlane(const Point3df &A, const std::pair<Point3df,Point3df> &plane )
329 {
330
331 float d;
332 Point3df temp = plane.first - A;
333 d = fabs( temp.dot(plane.second) );
334
335 return(d);
336 }
337
338
339 /* Distance from a point (A) to a line defined by
340 one of its point : bipoint.first
341 its direction vector (norm = 1): bipoint.second */
342 inline float DistancePointToLine(const Point3df &A, const std::pair<Point3df,Point3df> &line )
343 {
344
345 float d;
346 Point3df temp = A - line.first;
347 d = cross(temp,line.second).norm();
348
349 return(d);
350 }
351
352 //Compute the mean normal n0 of the cc
353 // n1 fix the sens of each normal
354 // Only pt with a least MIN_NEIGH neighbours are taken into account
355 // It avoid considering extremal points whose normal estimation is bad
356 // The normal of these pt can be seen as outliers
357 inline Point3df meanNormalofCC(const std::vector<Point3df> &cc,
358 const Point3dfNeigh & neigh,
359 unsigned MIN_NEIGH)
360 {
361 Point3df PtR,n0 = Point3df(0,0,0),n1= Point3df(0,0,0),normal_plan;
362 Point3dfNeigh::const_iterator is,es = neigh.end();
363 std::vector<Point3df>::const_iterator icc,ecc = cc.end();
364 bool ok1 = false;
365 //Fix an arbitrary orientation (n1) for the normals of each pt of the cc
366 icc = cc.begin();
367 while (!ok1 && icc != ecc)
368 {
369 PtR = *icc;
370 is = neigh.find(PtR);
371 if (is != es)
372 {
373 if (is->second.size() > MIN_NEIGH)
374 {
375 ok1 = false;
376 normal_plan = NormalFromPoints(is->first,is->second);
377 }
378 }
379 else
380 std::cerr << "Pb1: cannot find the neighbours of the point "
381 << PtR <<"\n";
382 ++icc;
383 }
384 n1 = normal_plan;
385
386 for(icc = cc.begin(); icc != ecc; ++icc)
387 {
388 PtR = *icc;
389 is = neigh.find(PtR);
390 if (is != es)
391 {
392 if (is->second.size() > MIN_NEIGH)
393 normal_plan = NormalFromPoints(is->first,is->second);
394 }
395 else
396 std::cerr << "Pb2: cannot find the neighbours of the point "
397 << PtR <<"\n";
398 normal_plan *= normal_plan.dot(n1);
399 normal_plan.normalize();
400 n0 += normal_plan ;
401 }
402
403 n0.normalize();
404 std::cout << "CC mean normal : "<< n0 << std::endl;
405
406 return (n0);
407 }
408
409
410
412 extern const short MESHDISTANCE_FORBIDDEN;
413 extern const short MESHDISTANCE_UNREACHED;
414
415 }
416}
417
418
419#endif
#define ASSERT(EX)
void sort(carto::VolumeRef< T > eigenvectors, carto::VolumeRef< T > eigenvalues, carto::VolumeRef< T > *wi=NULL)
Sort the eigenvectors and eigenvalues in decreasing order.
carto::VolumeRef< T > doit(carto::VolumeRef< T >, carto::VolumeRef< T > *wi=NULL)
Eigen system resolution function.
AimsVector< T, D > & normalize()
T dot(const AimsVector< T, D > &other) const
float norm() const
Texture< short > VolumeParcellation2MeshParcellation(const carto::rc_ptr< carto::Volume< short > > &initVol, const AimsSurface< 3, Void > &mesh, short back)
float DistancePointToLine(const Point3df &A, const std::pair< Point3df, Point3df > &line)
Definition projection.h:342
const short MESHDISTANCE_UNREACHED
Definition meshvoronoi.h:85
Texture< short > FirstSulciProjectionWithCurvatureMap(const carto::rc_ptr< carto::Volume< short > > &ccvol, const carto::rc_ptr< carto::Volume< short > > &sulcvol, const AimsSurface< 3, Void > &mesh, std::set< short > &cc_sulci_labels, std::map< short, short > &tri_sulci, std::map< unsigned, Point3dfSet > &cc_sulci_coord, std::map< Point3df, Point3df, Point3dfCompare > &initend, const Texture< float > &curvtex, float alpha, float dmin)
carto::VolumeRef< short > MeshParcellation2Volume(const carto::rc_ptr< carto::Volume< short > > &initVol, const Texture< short > &tex, const AimsSurface< 3, Void > &mesh, short val_domain, short back)
Texture< short > FirstSulciProjectionWithInterpolationPlane(const carto::rc_ptr< carto::Volume< short > > &ccvol, const carto::rc_ptr< carto::Volume< short > > &sulcvol, const AimsSurface< 3, Void > &mesh, std::set< short > &cc_sulci_labels, std::map< short, short > &tri_sulci, const std::map< Point3df, Point3dfSet, Point3dfCompare > &neigh, std::map< unsigned, Point3dfSet > &cc_sulci_coord, std::map< Point3df, Point3df, Point3dfCompare > &initend, float demin, float dpmin, short label_insula_left, short label_insula_right, const Point3df &CA)
TimeTexture< short > SulcusVolume2Texture(const AimsSurface< 3, Void > &mesh, const Texture< float > &curvtex, const carto::rc_ptr< carto::Volume< short > > &bottom_vol, const carto::rc_ptr< carto::Volume< short > > &surface_vol, float alpha, float dmin, int MINCC, const std::map< short, std::string > &trans, const std::set< std::string > &labels, float maxdil, float maxdil_mesh, float alpha_reg, bool connexity, const std::vector< std::list< unsigned > > &neigho)
Projection of the voxels relative to the bottom of the sulci to the edges of a triangulation.
Point3df IntersectionPointOfPlanAndLine(const Point3df &s1, const Point3df &s2, const Point3df &s3, const Point3df &direction_line, const Point3df &pt)
Definition projection.h:258
std::pair< Point3df, Point3df > NormalFromPoints(const Point3dfSet &init_point)
Definition projection.h:158
void NeighbourInCC(std::map< Point3df, Point3dfSet, Point3dfCompare > &neigh, const carto::rc_ptr< carto::Volume< short > > &bvol, const carto::rc_ptr< carto::Volume< short > > &svol, Connectivity::Type connectivity, short label, const unsigned size_neigh, unsigned max_points=50)
Give the neighbours of a point The neighbours have the same label as the point.
Point3df cross(const Point3df &A, const Point3df &B)
Definition projection.h:241
void AffinePointProjection(Texture< short > &tex, const AimsSurface< 3, Void > &mesh, const std::map< Point3df, Point3df, Point3dfCompare > &initend, const Point3dfSet &setpointi, short label, float dmin, float alpha_reg)
float DistancePointToPlane(const Point3df &A, const std::pair< Point3df, Point3df > &plane)
Definition projection.h:328
const short MESHDISTANCE_FORBIDDEN
global variable...
Definition meshvoronoi.h:84
Point3df meanNormalofCC(const std::vector< Point3df > &cc, const Point3dfNeigh &neigh, unsigned MIN_NEIGH)
Definition projection.h:357
std::set< Point3df, Point3dfCompare > Point3dfSet
Definition stlsort.h:118
std::map< Point3df, Point3dfSet, Point3dfCompare > Point3dfNeigh
Definition stlsort.h:119
AimsVector< float, 3 > Point3df