aimsdata  5.1.2
Neuroimaging data handling
component_d.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  * Connected components
36  */
37 #ifndef AIMS_CONNECTIVITY_COMPONENT_D_H
38 #define AIMS_CONNECTIVITY_COMPONENT_D_H
39 
41 #include <aims/bucket/bucket.h>
43 #include <map>
44 #include <queue>
45 #include <iostream>
46 #include <iomanip>
47 
48 namespace aims
49 {
50 
51 
52  template<typename T, typename O>
53  void ConnectedComponentEngine<carto::VolumeRef<T>,
54  carto::VolumeRef<O> >::filterInFrame(
55  const carto::VolumeRef<T> & cc,
57  std::map<O, size_t>& valids,
58  int t,
59  bool verbose )
60  {
61  int x = 0, y = 0, z = 0;
62 
63  if( verbose )
64  std::cout << "filtering...\n";
65 
66  out->fill( 0 );
67 
68  typename std::map<O, size_t>::iterator is, es = valids.end();
69 
70  carto::const_line_NDIterator<T> it( &cc->at( 0 ), cc->getSize(),
71  cc->getStrides() );
72  carto::line_NDIterator<O> oit( &out->at( 0, 0, 0, t ), out->getSize(),
73  out->getStrides() );
74  const T *p, *pn;
75  O* o;
76 
77  for( ; !it.ended(); ++it, ++oit )
78  {
79  p = &*it;
80  o = &*oit;
81  for( pn=p + it.line_length(); p!=pn;
82  it.inc_line_ptr( p ), oit.inc_line_ptr( o ) )
83  {
84  is = valids.find( (O) *p );
85  if( is != es )
86  *o = (O) is->second; // RISK OF OVERFLOW on char types
87  }
88  }
89  }
90 
91 
92  template<typename T, typename O>
94  carto::VolumeRef<O> >::connectedInFrame(
95  const carto::VolumeRef<T>& data,
97  Connectivity::Type connectivity,
98  std::multimap<size_t, O>& compSizes,
99  int t,
100  const T & backg,
101  bool bin,
102  bool verbose )
103  {
104  int x = 0, y = 0, z = 0, n = 0;
105  std::vector<int> dims = data->getSize();
106  int dimX = dims[0];
107  int dimY = dims[1];
108  int dimZ = dims[2];
109 
110  out->fill( 0 );
111 
112  //
113  // boolean volume to say if a voxel is already used
114  //
115 
116  carto::Volume<byte> flag( dimX, dimY, dimZ );
117 
118  flag.fill( false );
119  carto::line_NDIterator<byte> bit( &flag.at(0), flag.getSize(),
120  flag.getStrides() );
121  carto::const_line_NDIterator<T> it( &data->at( 0, 0, 0, t ),
122  data->getSize(),
123  data->getStrides() );
124 
125  byte *bp, *bpn;
126  const T *p;
127 
128  for( ; !bit.ended(); ++bit, ++it )
129  {
130  bp = &*bit;
131  p = &*it;
132  for( bpn=bp + bit.line_length(); bp!=bpn;
133  bit.inc_line_ptr( bp ), it.inc_line_ptr( p ) )
134  if( *p == backg )
135  *bp = true;
136  }
137 
138  Connectivity cd( data->getStrides()[1], data->getStrides()[2],
139  connectivity );
140 
141  O label = 1;
142  Point3dl pos, newpos;
143  std::queue<Point3dl> que;
144  T val;
145  size_t sz;
146 
147  //
148  // track connected components
149  //
150  for ( z = 0; z < dimZ; ++z )
151  {
152  if( verbose )
153  std::cout << "\rz: " << z << std::flush;
154 
155  for ( y = 0; y < dimY; ++y )
156  for ( x = 0; x < dimX; ++x )
157  if( !flag( x, y, z ) )
158  {
159  val = data( x, y, z, t );
160  que.push( Point3dl( x, y, z ) );
161  flag( x, y, z ) = true;
162  sz = 0;
163  while ( !que.empty() )
164  {
165  pos = que.front();
166  que.pop();
167  out( pos ) = label; // RISK of overflow in char types
168  ++sz;
169  for ( n = 0; n < cd.nbNeighbors(); n++ )
170  {
171  newpos = pos + Point3dl(cd.xyzOffset( n )[0],
172  cd.xyzOffset( n )[1],
173  cd.xyzOffset( n )[2]);
174 
175  if ( newpos[0] >= 0 &&
176  newpos[0] < dimX &&
177  newpos[1] >= 0 &&
178  newpos[1] < dimY &&
179  newpos[2] >= 0 &&
180  newpos[2] < dimZ )
181 
182  if ( !flag( newpos )
183  && ( bin || data( newpos[0], newpos[1], newpos[2], t ) == val ) )
184  {
185  flag( newpos ) = true;
186  que.push( newpos );
187  }
188  }
189  }
190  /* std::cout << "comp. " << label << ", val: " << val << " ("
191  << sz << " voxels)\n"; */
192 
193  compSizes.insert( std::pair<size_t, O>( sz, label ) );
194  ++label;
195  }
196  }
197 
198  if( verbose )
199  {
200  std::cout << std::endl;
201  std::cout << label << " components" << std::endl;
202  }
203  }
204 
205 
206  template<typename T, typename O>
208  carto::VolumeRef<O> >::connected(
209  const carto::VolumeRef<T>& data,
211  Connectivity::Type connectivity,
212  std::map<O, size_t>& valids,
213  const T & backg, bool bin,
214  size_t minSize, size_t maxSize,
215  size_t numMax, bool verbose )
216  {
217  std::multimap<size_t, size_t> compSizes;
218  int t=0;
219  int dimX = data->getSizeX();
220  int dimY = data->getSizeY();
221  int dimZ = data->getSizeZ();
222  int dimT = data->getSizeT() ;
223 
224  for( t = 0 ; t < dimT ; ++t )
225  {
226  // Get Volume of size_t to avoid risk of overflow in char types
227  // before filtering
228  carto::VolumeRef<size_t> cc( dimX, dimY, dimZ );
229 
231  ::connectedInFrame( data,
232  cc,
233  connectivity,
234  compSizes,
235  t,
236  backg,
237  bin,
238  verbose );
239 
240  // Filter small comps
241  std::multimap<size_t, size_t>::reverse_iterator
242  im, em = compSizes.rend();
243 
244  O label = 1;
245 
246  for( im = compSizes.rbegin();
247  im != em && ( numMax == 0 || static_cast<size_t>(label) <= numMax ); ++im )
248  {
249  if ((minSize ==0 || im->first >= minSize) && (maxSize == 0 || im->first <= maxSize))
250  {
251  if( verbose )
252  std::cout << "component " << std::setw( 4 ) << im->second
253  << " : " << std::setw( 8 ) << im->first
254  << " points" << std::endl;
255  valids[ im->second ] = static_cast<size_t>( label++ );
256  }
257  }
258 
260  ::filterInFrame( cc, out, valids, t, verbose );
261 
262  if( verbose )
263  std::cout << "after filtering: " << valids.size() << " components\n";
264 
265  }
266  }
267 
268  template <typename T>
270  const carto::VolumeRef<T>& data,
271  Connectivity::Type connectivity,
272  const T & backgrnd, bool bin,
273  size_t minsize, size_t maxsize,
274  size_t maxcomp, bool verbose )
275  {
276  AimsBucket<Void> *cbk;
277  std::unique_ptr<AimsBucket<Void> > abk;
278  if( minsize == 0 && maxsize == 0 && maxcomp == 0 )
279  cbk = &components;
280  else
281  {
282 
283  abk.reset( new AimsBucket<Void> );
284  cbk = abk.get();
285  }
286  AimsBucket<Void> & component = *cbk;
287 
288  int x=0, y=0, z=0, t=0, n=0;
289 
290  int dimX = data->getSizeX();
291  int dimY = data->getSizeY();
292  int dimZ = data->getSizeZ();
293  int dimT = data->getSizeT();
294 
295 
296  //
297  // boolean volume to say if a voxel is already used
298  //
299 
300  for( t = 0 ; t < dimT ; ++t )
301  {
302  carto::VolumeRef<byte> flag( dimX, dimY, dimZ );
303  flag->fill( false );
304  carto::line_NDIterator<byte> bit( &flag->at( 0 ), flag->getSize(),
305  flag->getStrides() );
306  carto::const_line_NDIterator<T> it( &data->at( 0, 0, 0, t ),
307  data->getSize(),
308  data->getStrides() );
309  byte *bp;
310  const T *p, *pn;
311 
312  for( ; !bit.ended(); ++bit, ++it )
313  {
314  p = &*it;
315  bp = &*bit;
316  for( pn=p + it.line_length(); p!=pn;
317  it.inc_line_ptr( p ), bit.inc_line_ptr( bp ) )
318  if( *p == backgrnd )
319  *bp = true;
320  }
321 
322  Connectivity cd( data->getStrides()[1], data->getStrides()[2],
323  connectivity );
324  //Connectivity cf( flag.oLine(), flag.oSlice(), connectivity );
325  size_t label = 1;
326  AimsBucketItem<Void> item,newItem;
327  std::queue< AimsBucketItem< Void > > que;
328  T val;
329 
330 
331  //
332  // track connected components
333  //
334  for ( z = 0; z < dimZ; ++z )
335  {
336  if( verbose )
337  std::cout << "\rz: " << z << std::flush;
338  for ( y = 0; y < dimY; ++y )
339  for ( x = 0; x < dimX; ++x )
340  {
341  if( !flag( x, y, z ) )
342  {
343 
344  val = data( x, y, z );
345  item.location() = Point3d( x, y, z );
346  que.push( item );
347  flag( x, y, z ) = true;
348  std::list<AimsBucketItem<Void> > & bk = component[ label ];
349  while ( !que.empty() )
350  {
351  item.location() = que.front().location();
352  que.pop();
353  bk.push_back( item );
354  for ( n = 0; n < cd.nbNeighbors(); n++ )
355  {
356  newItem.location() = item.location()
357  + cd.xyzOffset( n );
358  if ( newItem.location().item( 0 ) >= 0 &&
359  newItem.location().item( 0 ) < dimX &&
360  newItem.location().item( 1 ) >= 0 &&
361  newItem.location().item( 1 ) < dimY &&
362  newItem.location().item( 2 ) >= 0 &&
363  newItem.location().item( 2 ) < dimZ )
364 
365  if ( flag( newItem.location() ) == false
366  && ( bin || data( newItem.location() )
367  == val ) )
368  {
369  flag( newItem.location() ) = true;
370  que.push( newItem );
371  }
372  }
373  }
374  ++label;
375  }
376  }
377  }
378  if( verbose )
379  std::cout << std::endl;
380 
381  // filtering
382  if( minsize == 0 && maxsize == 0 && maxcomp == 0 )
383  return;
384 
385  AimsBucket<Void>::iterator i, e = component.end();
386  std::multimap<unsigned, std::list<AimsBucketItem<Void> > *> comps;
387  for( i=component.begin(); i!=e; ++i )
388  if(( minsize == 0 || i->second.size() >= minsize ) && ( maxsize == 0 || i->second.size() <= maxsize ))
389  comps.insert( std::pair<unsigned, std::list<AimsBucketItem<Void> > *>
390  ( i->second.size(),&i->second ) );
391  std::multimap<unsigned,
392  std::list<AimsBucketItem<Void> > *>::reverse_iterator
393  im, em = comps.rend();
394  label = 0;
395  for( im=comps.rbegin(); im!=em && label < maxcomp; ++im )
396  components[ label++ ] = *im->second;
397  }
398  }
399 
400  namespace internal
401  {
402 
403  template <typename T> inline
404  bool _nulltesttemplate_iseq( const T & x, const T & val )
405  {
406  return x == val;
407  }
408 
409  template<> inline
410  bool _nulltesttemplate_iseq( const Void &, const Void & )
411  {
412  return false;
413  }
414 
415  }
416 
417 
418  template <typename T>
420  const BucketMap<T>& data,
421  Connectivity::Type connectivity,
422  const T & backg, bool bin,
423  size_t minsize, size_t maxsize,
424  size_t maxcomp, bool )
425  {
426  AimsBucket<Void> *cbk;
427  std::unique_ptr<AimsBucket<Void> > abk;
428  if( minsize == 0 && maxsize == 0 && maxcomp == 0 )
429  cbk = &components;
430  else
431  {
432  abk.reset( new AimsBucket<Void> );
433  cbk = abk.get();
434  }
435  AimsBucket<Void> & component = *cbk;
436 
437 
438  //
439  // boolean bucket to say if a voxel is already used
440  //
441  BucketMap<byte> flags;
442  BucketMap<byte>::Bucket & flag = flags[0];
443  BucketMap<byte>::Bucket::iterator ifl, efl = flag.end();
444  const typename BucketMap<T>::Bucket & b = data.begin()->second;
445  typename BucketMap<T>::Bucket::const_iterator ib, eb = b.end();
446  int n;
447 
448  for( ib=b.begin(); ib!=eb; ++ib )
449  flag[ ib->first ]
450  = internal::_nulltesttemplate_iseq( ib->second, backg );
451 
452  Connectivity cd( 0, 0, connectivity );
453  //Connectivity cf( flag.oLine(), flag.oSlice(), connectivity );
454  size_t label = 1;
455  AimsBucketItem<Void> item,newItem;
456  std::queue< AimsBucketItem< Void > > que;
457  T val;
458 
459  //
460  // track connected components
461  //
462  for( ib=b.begin(); ib!=eb; ++ib )
463  {
464  ifl = flag.find( ib->first );
465  if( !ifl->second )
466  {
467  val = ib->second;
468  item.location() = ib->first;
469  que.push( item );
470  ifl->second = true;
471 // cout << "comp. " << label << ", val: " << val << std::endl;
472  std::list<AimsBucketItem<Void> > & bk = component[ label ];
473  while ( !que.empty() )
474  {
475  item.location() = que.front().location();
476  que.pop();
477  bk.push_back( item );
478  for ( n = 0; n < cd.nbNeighbors(); n++ )
479  {
480  newItem.location() = item.location() + cd.xyzOffset( n );
481  ifl = flag.find( newItem.location() );
482  if( ifl != efl && ifl->second == false
483  && ( bin
484  || b.find( newItem.location() )->second == val ) )
485  {
486  ifl->second = true;
487  que.push( newItem );
488  }
489  }
490  }
491  //std::cout << "(" << bk.size() << " voxels)\n";
492  ++label;
493  }
494  }
495 
496  // filtering
497  if( minsize == 0 && maxcomp == 0 )
498  return;
499 
500  AimsBucket<Void>::iterator i, e = component.end();
501  std::multimap<unsigned, std::list<AimsBucketItem<Void> > *> comps;
502  for( i=component.begin(); i!=e; ++i )
503  if(( minsize == 0 || i->second.size() >= minsize ) && ( maxsize == 0 || i->second.size() <= maxsize ))
504  comps.insert( std::pair<unsigned, std::list<AimsBucketItem<Void> > *>
505  ( i->second.size(),&i->second ) );
506  std::multimap<unsigned,
507  std::list<AimsBucketItem<Void> > *>::reverse_iterator
508  im, em = comps.rend();
509  label = 0;
510  for( im=comps.rbegin(); im!=em && label<maxcomp; ++im )
511  components[ label++ ] = *im->second;
512  }
513 
514 
515  template <typename T>
517  Connectivity::Type connectivity,
518  const T & backgrnd, bool bin,
519  size_t minsize, size_t maxsize,
520  size_t maxcomp,
521  bool verbose )
522  {
523  AimsBucket<Void> comps;
524  AimsConnectedComponent( comps, data, connectivity, backgrnd, bin, minsize, maxsize,
525  maxcomp, verbose );
526  AimsBucket<Void>::iterator i, e = comps.end();
527  std::list<AimsBucketItem<Void> >::iterator ic, ec;
528  typename BucketMap<T>::iterator ib, eb = data.end();
529  typename BucketMap<T>::Bucket::iterator ibb, ebb;
530 
531  // clear input bucket
532  for( ib=data.begin(); ib!=eb; ++ib )
533  for( ibb=ib->second.begin(), ebb=ib->second.end(); ibb!=ebb; ++ibb )
534  ibb->second = 0;
535  // fill it
536  typename BucketMap<T>::Bucket & bk = data.begin()->second;
537  for( i=comps.begin(); i!=e; ++i )
538  for( ic=i->second.begin(), ec=i->second.end(); ic!=ec; ++ic )
539  bk[ ic->location() ] = i->first + 1;
540  }
541 
542 
543  template <typename T>
545  AimsBucket<Void>& components,
546  const carto::VolumeRef<T>& data,
547  Connectivity::Type connectivity,
548  const T & backgrnd, bool bin,
549  size_t minsize, size_t maxsize,
550  size_t maxcomp, bool verbose )
551  {
552  AimsBucket<Void> *cbk;
553  // added to return the labels image
554  carto::VolumeRef<int16_t> labelImage( data->getSizeX(), data->getSizeY(),
555  data->getSizeZ(), data->getSizeT() );
556  labelImage->fill( 0 );
557  std::unique_ptr<AimsBucket<Void> > abk;
558  if( minsize == 0 && maxsize == 0 && maxcomp == 0 )
559  cbk = &components;
560  else
561  {
562 
563  abk.reset( new AimsBucket<Void> );
564  cbk = abk.get();
565  }
566  AimsBucket<Void> & component = *cbk;
567 
568  int x=0, y=0, z=0, t=0, n=0;
569 
570  int dimX = data->getSizeX();
571  int dimY = data->getSizeY();
572  int dimZ = data->getSizeZ();
573  int dimT = data->getSizeT();
574 
575 
576  // boolean volume to say if a voxel is already used
577 
578 
579  for( t = 0 ; t < dimT ; ++t )
580  {
581  carto::VolumeRef<byte> flag( dimX, dimY, dimZ );
582  flag->fill( false );
583  carto::line_NDIterator<byte> bit( &flag->at( 0 ), flag->getSize(),
584  flag->getStrides() );
585  carto::const_line_NDIterator<T> it( &data->at( 0, 0, 0, t ),
586  data->getSize(),
587  data->getStrides() );
588  byte *bp;
589  const T *p, *pn;
590  for( ; !bit.ended(); ++it, ++bit )
591  {
592  p = &*it;
593  bp = &*bit;
594  for( pn=p + it.line_length(); p!=pn;
595  it.inc_line_ptr( p ), bit.inc_line_ptr( bp ) )
596  if( *p == backgrnd )
597  *bp = true;
598  }
599 
600  Connectivity cd( data->getStrides()[1], data->getStrides()[2],
601  connectivity );
602  Connectivity cf( flag->getStrides()[1], flag->getStrides()[2],
603  connectivity );
604  size_t label = 1;
605  AimsBucketItem<Void> item,newItem;
606  std::queue< AimsBucketItem< Void > > que;
607  T val;
608 
609 
610 // track connected components
611 
612  for ( z = 0; z < dimZ; ++z )
613  {
614  if( verbose )
615  std::cout << "\rz: " << z << std::flush;
616  for ( y = 0; y < dimY; ++y )
617  for ( x = 0; x < dimX; ++x )
618  {
619 
620  if( !flag( x, y, z ) )
621  {
622 
623  val = data( x, y, z );
624  item.location() = Point3d( x, y, z );
625 
626  labelImage (x, y, z) = label;
627  que.push( item );
628  flag( x, y, z ) = true;
629 // std::cout << "comp. " << lcbkabel << ", val: " << val
630 // << std::endl;
631  std::list<AimsBucketItem<Void> > & bk = component[ label ];
632  while ( !que.empty() )
633  {
634  item.location() = que.front().location();
635  que.pop();
636  bk.push_back( item );
637  labelImage (item.location()) =label;
638  for ( n = 0; n < cd.nbNeighbors(); n++ )
639  {
640  newItem.location() = item.location()
641  + cd.xyzOffset( n );
642  if ( newItem.location().item( 0 ) >= 0 &&
643  newItem.location().item( 0 ) < dimX &&
644  newItem.location().item( 1 ) >= 0 &&
645  newItem.location().item( 1 ) < dimY &&
646  newItem.location().item( 2 ) >= 0 &&
647  newItem.location().item( 2 ) < dimZ )
648 
649  if ( flag( newItem.location() ) == false
650  && ( bin || data( newItem.location() )
651  == val ) )
652  {
653  flag( newItem.location() ) = true;
654  que.push( newItem );
655  labelImage (newItem.location()) = label;
656  }
657  }
658  }
659 // std::cout << "(" << bk.size() << " voxels)\n";
660  ++label;
661  }
662  }
663  }
664  if( verbose )
665  std::cout << std::endl;
666 
667 // filtering probleme filtrage
668  if( minsize == 0 && maxsize == 0 && maxcomp == 0 )
669  return labelImage;
670 
671  AimsBucket<Void>::iterator i, e = component.end();
672  std::multimap<unsigned, std::list<AimsBucketItem<Void> > *> comps;
673  for( i=component.begin(); i!=e; ++i )
674  if(( minsize == 0 || i->second.size() >= minsize ) && (maxsize == 0 || i->second.size() <= maxsize ))
675  comps.insert( std::pair<unsigned, std::list<AimsBucketItem<Void> > *>
676  ( i->second.size(),&i->second ) );
677 
678  std::multimap<unsigned,
679  std::list<AimsBucketItem<Void> > *>::reverse_iterator
680  im, em = comps.rend();
681  label = 0;
682  labelImage = 0;
683  for( im=comps.rbegin(); im!=em && (label < maxcomp || maxcomp == 0); ++im ){
684  std::list<AimsBucketItem<Void> > bucket = *im->second;
685  std::list<AimsBucketItem<Void> >::iterator ite, iteend = bucket.end();
686  for (ite = bucket.begin(); ite != iteend ; ite ++ ) {
687  labelImage ((*ite).location()) = label;
688  }
689  components[ label++ ] = *im->second;
690  }
691  }
692  return labelImage;
693  }
694 
695 }
696 
697 #endif
698 
The template base class for all types of bucket items.
Definition: item.h:63
const AimsVector< short, 3 > & location() const
Get a const reference to the location of the bucket item.
Definition: item.h:92
The bucket base class to manage packages of points associated to their value during time.
Definition: bucket.h:70
std::map< int, std::list< AimsBucketItem< T > > >::iterator iterator
Definition: bucket.h:73
const T & item(int d) const
An alternate, ordered, representation for buckets (voxels lists).
Definition: bucketMap.h:99
std::map< int, Bucket >::iterator iterator
Definition: bucketMap.h:103
std::map< Point3d, T, BucketMapLess > Bucket
Definition: bucketMap.h:102
Topology of a data container.
Definition: connectivity.h:51
const Point3d & xyzOffset(int n) const
Get the X/Y/Z offsets of the nth element.
Definition: connectivity.h:104
int nbNeighbors() const
Get the number of neighbors for that connectivity.
Definition: connectivity.h:100
Type
The different kinds of connectivity.
Definition: connectivity.h:55
std::vector< int > getSize() const
int getSizeZ() const
int getSizeT() const
iterator end()
std::vector< int > getSize() const
const T & at(long x, long y=0, long z=0, long t=0) const
int getSizeY() const
void fill(const T &value)
int getSizeX() const
std::vector< size_t > getStrides() const
std::vector< size_t > getStrides() const
void fill(const T &value)
const T & at(long x, long y=0, long z=0, long t=0) const
void inc_line_ptr(const T *&p) const
long line_length() const
void inc_line_ptr(T *&p) const
bool _nulltesttemplate_iseq(const T &x, const T &val)
Definition: component_d.h:404
The class for EcatSino data write operation.
Definition: borderfiller.h:13
carto::VolumeRef< int16_t > AimsLabeledConnectedComponent(AimsBucket< Void > &component, const carto::VolumeRef< T > &data, aims::Connectivity::Type connectivity, const T &backgrnd=0, bool bin=true, size_t minsize=0, size_t maxSize=0, size_t maxcomp=0, bool verbose=true)
Definition: component_d.h:544
void AimsConnectedComponent(carto::VolumeRef< T > data, aims::Connectivity::Type connectivity, std::map< T, size_t > &valids, const T &backgrnd=0, bool bin=true, size_t minSize=0, size_t maxSize=0, size_t numMax=0, bool verbose=true)
Definition: component.h:125
std::vector< int > minSize(const std::vector< int > &s1, const std::vector< int > &s2)
std::vector< int > maxSize(const std::vector< int > &s1, const std::vector< int > &s2)
int verbose