12 #ifndef AIMS_REGISTRATION_DISPLACEMENT_FIELD_D_H 13 #define AIMS_REGISTRATION_DISPLACEMENT_FIELD_D_H 39 template<
class T>
inline 40 static void meanVar(
const AimsData<T>& im,
const AimsData<int>& offset,
int i,
int j,
int k,
double &m,
double &s,
const T <h,
const T &hth)
51 for(oit =offset.
begin(); oit != eoit; oit++ )
56 if( (*pt<lth) || (*pt>hth) ) {s=0; m=0;
break;}
91 if ( ( i < image.
dimX() - _nx) && (j < image.
dimY() - _ny) && (k < image.
dimZ() - _nz23d) )
93 meanVar( image, _offset, i, j, k, m, s, _lthr, _hthr);
97 _sel.insert(std::pair<float, Point3d>(s,
Point3d(i,j, k) ) );
98 _moy.insert(std::pair<float, double>(s, m ) );
103 _selThresh = _sel.size() * cV;
123 _nz23d=( _nz == 1 ? 0 : _nz );
143 Pref->setLevel( _level );
145 _pyrRef = Pref->item( _level ).clone();
165 _offset(i, j, k) = i + j * _pyrRef.oLine() + k * _pyrRef.oSlice() ;
170 selectBlock( _pyrRef, scaleControl.
getcutVar());
180 _baryref[0] = _baryref[1] = _baryref[2] = 0.;
181 _barytest[0] = _barytest[1] =_barytest[2] = 0.;
184 double mLocalTest = 0, sLocalTest = 0;
196 Ptest->setLevel( _level );
198 _pyrTest = Ptest->item( _level ).clone();
211 _offset2(i, j, k) = i + j * _pyrTest.oLine() + k * _pyrTest.oSlice() ;
222 field.
setSizeXYZT( _pyrRef.sizeX(), _pyrRef.sizeY(), _pyrRef.sizeZ(), _pyrRef.sizeT() );
226 std::multimap<float, Point3d>::reverse_iterator it = _sel.rbegin();
227 std::multimap<float, double>::reverse_iterator itm = _moy.rbegin();
229 std::vector<Point3df> pointstest, pointsref;
232 double norm_fctr = _offset.
dimX() * _offset.dimY() * _offset.dimZ() * _offset.dimX() * _offset.dimY() * _offset.dimZ();
235 float puis_level = float(pow((
double) 2, (
double) _level));
238 int realPointNumber = 0 ;
239 int entLimit = int(_selThresh + .5);
261 int rank = COMM_WORLD.Get_rank();
262 int size = COMM_WORLD.Get_size();
263 int nbBlock = entLimit/size;
264 int nbBlockLeft = entLimit%size;
265 if(rank < nbBlockLeft) {
266 for(j = 0;j < rank * (nbBlock + 1);j++) {
270 entLimit = nbBlock + 1;
273 for(j = 0;j < nbBlockLeft + rank * nbBlock;j++) {
281 int recvCounts[size];
288 for(
int n = 0; n < entLimit; ++n, ++it, ++itm)
291 double mo = itm->second;
292 double sd = itm->first;
294 double n4_by_sd = norm_fctr * sd;
295 bool badPoint =
true;
297 double correlMax = 0;
310 (p[0]+k+_nx < _pyrTest.dimX() ) &&
311 (p[1]+l+_ny < _pyrTest.dimY() ) &&
312 (p[2]+m+ _nz23d < _pyrTest.dimZ() ) )
314 T *pRef = _pyrRef.begin() + _pyrRef.oFirstPoint() + p[0] + p[1]*_pyrRef.oLine() + p[2]*_pyrRef.oSlice() ;
315 T *pTest = _pyrTest.
begin() + _pyrTest.oFirstPoint() + (p[0]+k) + (p[1]+l)*_pyrTest.oLine() + (p[2]+m)*_pyrTest.oSlice() ;
317 meanVar( _pyrTest, _offset2, p[0]+k, p[1]+l, p[2]+m, mLocalTest, sLocalTest, _ltht, _htht);
325 for(oit = _offset.
begin(), oit2 = _offset2.
begin(); oit != oitend; oit++, oit2++ )
327 correl += ( *(pRef + *oit) - mo ) * ( *(pTest + *oit2 ) - mLocalTest);
333 correl /= (n4_by_sd * sLocalTest);
337 if(correl) badPoint =
false;
340 if ( (correl == correlMax ) && (!badPoint) )
343 field( p[0] + _nx/2, p[1] + _ny/2, p[2] + _nz23d/2) =
Point3d(0,0,0);
345 else if ( (correl > correlMax ) && (!badPoint) )
349 field( p[0] + _nx/2, p[1] + _ny/2, p[2] + _nz23d/2) =
Point3d(k*(int16_t)puis_level, l*(int16_t)puis_level, m*(int16_t)puis_level);
359 curRef[0] = ( (float)p[0] +
float(_nx)/2.0 ) * puis_level;
360 curRef[1] = ( (float)p[1] +
float(_ny)/2.0 ) * puis_level;
361 curRef[2] = ( (float)p[2] +
float(_nz23d)/2.0 ) * puis_level;
363 curTest[0] = curRef[0] + float( field( p[0] + _nx/2, p[1] + _ny/2, p[2] + _nz23d/2)[0] );
364 curTest[1] = curRef[1] + float( field( p[0] + _nx/2, p[1] + _ny/2, p[2] + _nz23d/2)[1] );
365 curTest[2] = curRef[2] + float( field( p[0] + _nx/2, p[1] + _ny/2, p[2] + _nz23d/2)[2] );
377 if ( (!badPoint) && ( correlMax > _seuilCorrel ) && (one_max) )
380 pointsref.push_back( curRef );
381 pointstest.push_back( curTest );
384 _baryref[0] += curRef[0]; _baryref[1] += curRef[1]; _baryref[2] += curRef[2];
385 _barytest[0] += curTest[0]; _barytest[1] += curTest[1]; _barytest[2] += curTest[2];
391 field( p[0] + _nx/2, p[1] + _ny/2, p[2] + _nz23d/2) =
Point3d(0,0,0);
395 _pointstest = pointstest;
396 _pointsref = pointsref;
401 recvCounts[rank] = 6*realPointNumber;
402 COMM_WORLD.Allgather(IN_PLACE, 0, INT, recvCounts, 1, INT);
403 COMM_WORLD.Barrier();
406 for(i = 1; i < size; i++) {
407 dspls[i] = dspls[i-1] + recvCounts[i-1];
410 int totalNumFloats = dspls[size-1] + recvCounts[size-1];
411 pointsRecv =
new float[totalNumFloats];
412 for(i = 0; i < realPointNumber; i++) {
413 for(
int j = 0; j < 3; j++) {
414 pointsRecv[dspls[rank] + i*6 + j] = (_pointsref[i])[j];
415 pointsRecv[dspls[rank] + i*6 + 3 + j] = (_pointstest[i])[j];
418 _pointsref.clear();_pointstest.clear();
419 COMM_WORLD.Allgatherv(IN_PLACE, 0, INT, pointsRecv, recvCounts, dspls, FLOAT);
420 COMM_WORLD.Barrier();
421 for(
int i = 0; i < totalNumFloats; i += 6) {
422 _pointsref.push_back(
Point3df(pointsRecv[i],pointsRecv[i+1],pointsRecv[i+2]));
423 _pointstest.push_back(
Point3df(pointsRecv[i+3],pointsRecv[i+4],pointsRecv[i+5]));
428 realPointNumber = totalNumFloats/6;
429 COMM_WORLD.Allreduce(IN_PLACE, _baryref, 3, DOUBLE, SUM);
430 COMM_WORLD.Allreduce(IN_PLACE, _barytest, 3, DOUBLE, SUM);
444 _baryref[0] /= realPointNumber;
445 _baryref[1] /= realPointNumber;
446 _baryref[2] /= realPointNumber;
447 _barytest[0] /= realPointNumber;
448 _barytest[1] /= realPointNumber;
449 _barytest[2] /= realPointNumber;
464 Ptesttrans->setRef(testtrans);
465 Ptesttrans->setLevel( level );
467 AimsData<T> pyrTrans = Ptesttrans->item( level ).clone();
480 Pref->setLevel( level );
486 delete pyramidfunc2 ;
492 _offset = tmp.
clone();
493 _offset2 = tmp.
clone();
497 _offset(i, j, k) = i + j * pyrRef.
oLine() + k * pyrRef.
oSlice() ;
498 _offset2(i, j, k) = i + j * pyrTrans.
oLine() + k * pyrTrans.
oSlice() ;
506 double mRef = 0, sRef = 0, mTest = 0, sTest = 0;
518 double norm = _offset.dimX() * _offset.dimY() * _offset.dimZ() * _offset.dimX() * _offset.dimY() * _offset.dimZ();
538 if( (i + _nx < pyrTrans.
dimX() ) && (j + _ny < pyrTrans.
dimY() ) && (k + _nz23d*_nz < pyrTrans.
dimZ() ) )
542 if( (pyrTrans(i + _nx/2,j + _ny/2, k + _nz23d*_nz/2) < thresh) )
548 meanVar( pyrTrans, _offset2, i, j , k, mTest, sTest, _ltht, _htht);
549 meanVar( pyrRef, _offset, i, j , k, mRef, sRef, _lthr, _hthr);
550 double normS = norm * (sRef*sTest);
559 for(oit = _offset.
begin(), oit2 = _offset2.
begin(); oit != eoit; oit++, oit2++ )
561 correl += ( *(pRef + *oit) - mRef ) * ( *(pTest + *oit2 ) - mTest);
565 correl = sqrt(correl);
577 else pyrQuality(i + _nx/2,j + _ny/2, k + _nz23d*_nz/2) = 0;
AimsData< Point3d > getField(AimsData< T > &test)
#define ForEach3d(thing, x, y, z)
AimsData< T > getQuality(AimsData< T > &testtrans, AimsData< T > &ref, int level, T thresh=std::numeric_limits< T >::max())
AimsData< T > clone() const
void setSizeXYZT(float sizex=1.0f, float sizey=1.0f, float sizez=1.0f, float sizet=1.0f)
AIMSDATA_API float norm(const Tensor &thing)
void init(AimsData< T > &ref, ScaleControl &scaleControl, T *seuils)