brainrat-private  5.1.2
channelextractor.h
Go to the documentation of this file.
1 /* Copyright (C) 2000-2016 CEA
2  *
3  * This software and supporting documentation were developed by
4  * bioPICSEL
5  * CEA/DSV/I²BM/MIRCen/LMN, Batiment 61,
6  * 18, route du Panorama
7  * 92265 Fontenay-aux-Roses
8  * France
9  */
10 
11 #ifndef BRAINRAT_UTILITY_CHANNELEXTRACTOR_H
12 #define BRAINRAT_UTILITY_CHANNELEXTRACTOR_H
13 
14 //============================================================================
15 // CHANNEL EXTRACTOR
16 //============================================================================
17 
18 //--- aims -------------------------------------------------------------------
19 #include <aims/rgb/rgb.h> // AimsRGB
20 #include <aims/io/io_g.h> // For debugging purpose
21 //--- cartodata --------------------------------------------------------------
22 #include <cartodata/volume/volume.h> // Volume
23 #include <cartodata/volume/volumeutil.h> // VolumeUtil
24 //--- cartobase --------------------------------------------------------------
25 #include <cartobase/type/datatypetraits.h> // DataTypeTraits
26 #include <cartobase/type/types.h> // DataTypeCode
27 //--- std --------------------------------------------------------------------
28 #include <limits> // numeric_limits
29 #include <exception> // exception
30 #include <cmath> // atan2
31 //----------------------------------------------------------------------------
32 
33 namespace bio {
34 
35  //--------------------------------------------------------------------------
36  // RESCALER
37  //--------------------------------------------------------------------------
42  class Rescaler
43  {
44  //------------------------------------------------------------------------
45  // constructor / destructor
46  //------------------------------------------------------------------------
47  public:
49  _rescale( false ),
50  _imin(0.0),
51  _imax(0.0),
52  _omin(0.0),
53  _omax(0.0),
54  _iminset(false),
55  _imaxset(false),
56  _ominset(false),
57  _omaxset(false),
58  _dynlimits(true),
59  _a(0.0),
60  _b(0.0),
61  _abset(false)
62  {}
63  virtual ~Rescaler() {}
64 
65  //------------------------------------------------------------------------
66  // exception
67  //------------------------------------------------------------------------
68  public:
69  class bad_options_exception: public std::exception
70  {
71  public:
73  virtual ~bad_options_exception() throw() {};
74  virtual const char * what() const throw()
75  {
76  return "Resampler: Bad options";
77  }
78  };
79 
80  //------------------------------------------------------------------------
81  // execution
82  //------------------------------------------------------------------------
83  public:
84  template <typename T, typename C>
85  C rescale( T val )
86  {
87  if( !_rescale )
88  return (C) val;
89  else if( !_abset )
90  throw bad_options_exception();
91  else
92  return (C) ( _a * (double) val + _b );
93  }
94 
95  //------------------------------------------------------------------------
96  // options setting
97  //------------------------------------------------------------------------
98  public:
99  void setRescale( bool val = true ) { _rescale = val; }
100  void setInputMin( double val ) { _imin = val; _iminset = true; AB(); }
101  void setInputMax( double val ) { _imax = val; _imaxset = true; AB(); }
102  void setOutputMin( double val ) { _omin = val; _ominset = true; AB(); }
103  void setOutputMax( double val ) { _omax = val; _omaxset = true; AB(); }
104  void resetInputMin() { _iminset = false; }
105  void resetInputMax() { _imaxset = false; }
106  void resetOutputMin() { _ominset = false; }
107  void resetOutputMax() { _omaxset = false; }
108  void setInputDynMinMax( bool val = true ) { _dynlimits = val; }
109  template <typename T>
110  void setInputDynMinMax( carto::VolumeRef<T> in )
111  {
112  computeInputDynMin( in );
113  computeInputDynMax( in );
114  _iminset = true;
115  _imaxset = true;
116  AB();
117  }
118  void reset()
119  {
120  _rescale = false;
121  _iminset = false;
122  _imaxset = false;
123  _ominset = false;
124  _omaxset = false;
125  _dynlimits = true;
126  _abset = false;
127  }
128 
129  //------------------------------------------------------------------------
130  // private helpers
131  //------------------------------------------------------------------------
132  protected:
133  template <typename T>
134  void computeInputDynMin( carto::VolumeRef<T> in, int ch = 0 )
135  {
136  _imin = (double) carto::VolumeUtil<T>::min( in );
137  }
138  template <typename T>
139  void computeInputDynMax( carto::VolumeRef<T> in, int ch = 0 )
140  {
141  _imax = (double) carto::VolumeUtil<T>::max( in );
142  }
143  template <typename T>
145  {
146  _imin = (double) std::numeric_limits<T>::min();
147  }
148  template <typename T>
150  {
151  _imax = (double) std::numeric_limits<T>::max();
152  }
153  template <typename C>
155  {
156  _omin = (double) std::numeric_limits<C>::min();
157  }
158  template <typename C>
160  {
161  _omax = (double) std::numeric_limits<C>::max();
162  }
163  void AB()
164  {
165  if( ( _imax != _imin ) && ( _omax != _omin ) ) {
166  _a = ( _omax - _omin ) / ( _imax - _imin );
167  _b = _omin - _a * _imin;
168  _abset = true;
169  } else
170  _abset = false;
171  }
172  template <typename T, typename C>
173  void computeRuntimeMinMax( carto::VolumeRef<T> in, int ch = 0 )
174  {
175  if( _rescale )
176  {
177  if( _dynlimits )
178  {
179  if( !_iminset )
180  computeInputDynMax( in, ch );
181  if( !_imaxset )
182  computeInputDynMax( in, ch );
183  }
184  else
185  {
186  if( !_iminset )
187  computeInputTypeMax<T>();
188  if( !_imaxset )
189  computeInputTypeMax<T>();
190  }
191  if( !_ominset )
192  computeOutputMin<C>();
193  if( !_omaxset )
194  computeOutputMax<C>();
195  AB();
196  }
197  }
198 
199  //------------------------------------------------------------------------
200  // members
201  //------------------------------------------------------------------------
202  protected:
203  bool _rescale;
204  double _imin;
205  double _imax;
206  double _omin;
207  double _omax;
208  bool _iminset;
209  bool _imaxset;
210  bool _ominset;
211  bool _omaxset;
213  double _a;
214  double _b;
215  bool _abset;
216  };
217 
218  //--- spec RGB -------------------------------------------------------------
219  template <>
220  void Rescaler::computeInputDynMin<AimsRGB>( carto::VolumeRef<AimsRGB> in, int ch )
221  {
222  carto::VolumeRef<AimsRGB>::const_iterator i, ie = in.end();
223  _imin = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGB>::ChannelType>::max();
224  for( i = in.begin(); i != ie; ++i )
225  {
226  if( _imin > (double) (*i)[ch] )
227  _imin = (double) (*i)[ch];
228  }
229  }
230 
231  template <>
232  void Rescaler::computeInputDynMax<AimsRGB>( carto::VolumeRef<AimsRGB> in, int ch )
233  {
234  carto::VolumeRef<AimsRGB>::const_iterator i, ie = in.end();
235  _imax = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGB>::ChannelType>::min();
236  for( i = in.begin(); i != ie; ++i )
237  {
238  if( _imax > (double) (*i)[ch] )
239  _imax = (double) (*i)[ch];
240  }
241  }
242 
243  template <>
244  void Rescaler::computeInputTypeMin<AimsRGB>()
245  {
246  _imin = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGB>::ChannelType>::min();
247  }
248 
249  template <>
250  void Rescaler::computeInputTypeMax<AimsRGB>()
251  {
252  _imax = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGB>::ChannelType>::max();
253  }
254 
255  //--- spec RGBA -------------------------------------------------------------
256  template <>
257  void Rescaler::computeInputDynMin<AimsRGBA>( carto::VolumeRef<AimsRGBA> in, int ch )
258  {
259  carto::VolumeRef<AimsRGBA>::const_iterator i, ie = in.end();
260  _imin = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGBA>::ChannelType>::max();
261  for( i = in.begin(); i != ie; ++i )
262  {
263  if( _imin > (double) (*i)[ch] )
264  _imin = (double) (*i)[ch];
265  }
266  }
267 
268  template <>
269  void Rescaler::computeInputDynMax<AimsRGBA>( carto::VolumeRef<AimsRGBA> in, int ch )
270  {
271  carto::VolumeRef<AimsRGBA>::const_iterator i, ie = in.end();
272  _imax = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGBA>::ChannelType>::min();
273  for( i = in.begin(); i != ie; ++i )
274  {
275  if( _imax > (double) (*i)[ch] )
276  _imax = (double) (*i)[ch];
277  }
278  }
279 
280  template <>
281  void Rescaler::computeInputTypeMin<AimsRGBA>()
282  {
283  _imin = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGBA>::ChannelType>::min();
284  }
285 
286  template <>
287  void Rescaler::computeInputTypeMax<AimsRGBA>()
288  {
289  _imax = (double) std::numeric_limits<carto::DataTypeTraits<AimsRGBA>::ChannelType>::max();
290  }
291 
292  //--- spec HSV -------------------------------------------------------------
293  template <>
294  void Rescaler::computeInputDynMin<AimsHSV>( carto::VolumeRef<AimsHSV> in, int ch )
295  {
296  carto::VolumeRef<AimsHSV>::const_iterator i, ie = in.end();
297  _imin = (double) std::numeric_limits<carto::DataTypeTraits<AimsHSV>::ChannelType>::max();
298  for( i = in.begin(); i != ie; ++i )
299  {
300  if( _imin > (double) (*i)[ch] )
301  _imin = (double) (*i)[ch];
302  }
303  }
304 
305  template <>
306  void Rescaler::computeInputDynMax<AimsHSV>( carto::VolumeRef<AimsHSV> in, int ch )
307  {
308  carto::VolumeRef<AimsHSV>::const_iterator i, ie = in.end();
309  _imax = (double) std::numeric_limits<carto::DataTypeTraits<AimsHSV>::ChannelType>::min();
310  for( i = in.begin(); i != ie; ++i )
311  {
312  if( _imax > (double) (*i)[ch] )
313  _imax = (double) (*i)[ch];
314  }
315  }
316 
317  template <>
318  void Rescaler::computeInputTypeMin<AimsHSV>()
319  {
320  _imin = (double) std::numeric_limits<carto::DataTypeTraits<AimsHSV>::ChannelType>::min();
321  }
322 
323  template <>
324  void Rescaler::computeInputTypeMax<AimsHSV>()
325  {
326  _imax = (double) std::numeric_limits<carto::DataTypeTraits<AimsHSV>::ChannelType>::max();
327  }
328 
329  //--------------------------------------------------------------------------
330  // CHANNEL EXTRACTOR
331  //--------------------------------------------------------------------------
332  template <typename T, typename C>
334  {
335  public:
337  Rescaler()
338  {}
339  virtual ~ChannelExtractor() {}
340 
341  public:
342  class not_impl_exception: public std::exception
343  {
344  public:
346  virtual ~not_impl_exception() throw() {};
347  virtual const char * what() const throw()
348  {
349  return ("ChannelExtractor: type " + carto::DataTypeCode<T>::name() + " not implemented").c_str();
350  }
351  };
352 
353  public:
354  // write in allocated volume (need specialization)
355  void getChannelR( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
356  void getChannelG( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
357  void getChannelB( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
358  void getChannelRGBNorm( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
359  void getChannelYl( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
360  void getChannelCb( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
361  void getChannelCr( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
362  void getChannelH( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
363  void getChannelS( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
364  void getChannelV( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
365  void getChannelX( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
366  void getChannelY( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
367  void getChannelZ( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
368  void getChannelL( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
369  void getChannela( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
370  void getChannelb( carto::VolumeRef<T>, carto::VolumeRef<C> ) { throw not_impl_exception(); }
371 
372  // allocate and write volume
373  carto::VolumeRef<C> getChannelR( carto::VolumeRef<T> in )
374  {
375  carto::VolumeRef<C> out = allocateVolume( in );
376  getChannelR( in, out );
377  return out;
378  }
379  carto::VolumeRef<C> getChannelG( carto::VolumeRef<T> in )
380  {
381  carto::VolumeRef<C> out = allocateVolume( in );
382  getChannelG( in, out );
383  return out;
384  }
385  carto::VolumeRef<C> getChannelB( carto::VolumeRef<T> in )
386  {
387  carto::VolumeRef<C> out = allocateVolume( in );
388  getChannelB( in, out );
389  return out;
390  }
391  carto::VolumeRef<C> getChannelRGBNorm( carto::VolumeRef<T> in )
392  {
393  carto::VolumeRef<C> out = allocateVolume( in );
394  getChannelRGBNorm( in, out );
395  return out;
396  }
397  carto::VolumeRef<C> getChannelYl( carto::VolumeRef<T> in )
398  {
399  carto::VolumeRef<C> out = allocateVolume( in );
400  getChannelYl( in, out );
401  return out;
402  }
403  carto::VolumeRef<C> getChannelCb( carto::VolumeRef<T> in )
404  {
405  carto::VolumeRef<C> out = allocateVolume( in );
406  getChannelCb( in, out );
407  return out;
408  }
409  carto::VolumeRef<C> getChannelCr( carto::VolumeRef<T> in )
410  {
411  carto::VolumeRef<C> out = allocateVolume( in );
412  getChannelCr( in, out );
413  return out;
414  }
415  carto::VolumeRef<C> getChannelH( carto::VolumeRef<T> in )
416  {
417  carto::VolumeRef<C> out = allocateVolume( in );
418  getChannelH( in, out );
419  return out;
420  }
421  carto::VolumeRef<C> getChannelS( carto::VolumeRef<T> in )
422  {
423  carto::VolumeRef<C> out = allocateVolume( in );
424  getChannelS( in, out );
425  return out;
426  }
427  carto::VolumeRef<C> getChannelV( carto::VolumeRef<T> in )
428  {
429  carto::VolumeRef<C> out = allocateVolume( in );
430  getChannelV( in, out );
431  return out;
432  }
433  carto::VolumeRef<C> getChannelX( carto::VolumeRef<T> in )
434  {
435  carto::VolumeRef<C> out = allocateVolume( in );
436  getChannelX( in, out );
437  return out;
438  }
439  carto::VolumeRef<C> getChannelY( carto::VolumeRef<T> in )
440  {
441  carto::VolumeRef<C> out = allocateVolume( in );
442  getChannelY( in, out );
443  return out;
444  }
445  carto::VolumeRef<C> getChannelZ( carto::VolumeRef<T> in )
446  {
447  carto::VolumeRef<C> out = allocateVolume( in );
448  getChannelZ( in, out );
449  return out;
450  }
451  carto::VolumeRef<C> getChannelL( carto::VolumeRef<T> in )
452  {
453  carto::VolumeRef<C> out = allocateVolume( in );
454  getChannelL( in, out );
455  return out;
456  }
457  carto::VolumeRef<C> getChannela( carto::VolumeRef<T> in )
458  {
459  carto::VolumeRef<C> out = allocateVolume( in );
460  getChannela( in, out );
461  return out;
462  }
463  carto::VolumeRef<C> getChannelb( carto::VolumeRef<T> in )
464  {
465  carto::VolumeRef<C> out = allocateVolume( in );
466  getChannelb( in, out );
467  return out;
468  }
469 
470  public:
471  // helper
472  carto::VolumeRef<C> allocateVolume( carto::VolumeRef<T> in )
473  {
474  carto::VolumeRef<C> out( in.getSizeX(), in.getSizeY(),
475  in.getSizeZ(), in.getSizeT() );
476  out->copyHeaderFrom( in.header() );
477  return out;
478  }
479  };
480 
481 
482  //--- spec RGB -------------------------------------------------------------
483  template <typename C>
484  class ChannelExtractor<AimsRGB,C>: public Rescaler
485  {
486  public:
488  Rescaler()
489  {}
490  virtual ~ChannelExtractor() {}
491 
492  // write in allocated volume
493  void getChannelR( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
494  void getChannelG( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
495  void getChannelB( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
496  void getChannelRGBNorm( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
497  void getChannelYl( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
498  void getChannelCb( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
499  void getChannelCr( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
500  void getChannelH( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
501  void getChannelS( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
502  void getChannelV( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
503  void getChannelX( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
504  void getChannelY( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
505  void getChannelZ( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
506  void getChannelL( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
507  void getChannela( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
508  void getChannelb( carto::VolumeRef<AimsRGB>, carto::VolumeRef<C> );
509 
510  // allocate and write volume
511  carto::VolumeRef<C> getChannelR( carto::VolumeRef<AimsRGB> in )
512  {
513  carto::VolumeRef<C> out = allocateVolume( in );
514  getChannelR( in, out );
515  return out;
516  }
517  carto::VolumeRef<C> getChannelG( carto::VolumeRef<AimsRGB> in )
518  {
519  carto::VolumeRef<C> out = allocateVolume( in );
520  getChannelG( in, out );
521  return out;
522  }
523  carto::VolumeRef<C> getChannelB( carto::VolumeRef<AimsRGB> in )
524  {
525  carto::VolumeRef<C> out = allocateVolume( in );
526  getChannelB( in, out );
527  return out;
528  }
529  carto::VolumeRef<C> getChannelRGBNorm( carto::VolumeRef<AimsRGB> in )
530  {
531  carto::VolumeRef<C> out = allocateVolume( in );
532  getChannelRGBNorm( in, out );
533  return out;
534  }
535  carto::VolumeRef<C> getChannelYl( carto::VolumeRef<AimsRGB> in )
536  {
537  carto::VolumeRef<C> out = allocateVolume( in );
538  getChannelYl( in, out );
539  return out;
540  }
541  carto::VolumeRef<C> getChannelCb( carto::VolumeRef<AimsRGB> in )
542  {
543  carto::VolumeRef<C> out = allocateVolume( in );
544  getChannelCb( in, out );
545  return out;
546  }
547  carto::VolumeRef<C> getChannelCr( carto::VolumeRef<AimsRGB> in )
548  {
549  carto::VolumeRef<C> out = allocateVolume( in );
550  getChannelCr( in, out );
551  return out;
552  }
553  carto::VolumeRef<C> getChannelH( carto::VolumeRef<AimsRGB> in )
554  {
555  carto::VolumeRef<C> out = allocateVolume( in );
556  getChannelH( in, out );
557  return out;
558  }
559  carto::VolumeRef<C> getChannelS( carto::VolumeRef<AimsRGB> in )
560  {
561  carto::VolumeRef<C> out = allocateVolume( in );
562  getChannelS( in, out );
563  return out;
564  }
565  carto::VolumeRef<C> getChannelV( carto::VolumeRef<AimsRGB> in )
566  {
567  carto::VolumeRef<C> out = allocateVolume( in );
568  getChannelV( in, out );
569  return out;
570  }
571  carto::VolumeRef<C> getChannelX( carto::VolumeRef<AimsRGB> in )
572  {
573  carto::VolumeRef<C> out = allocateVolume( in );
574  getChannelX( in, out );
575  return out;
576  }
577  carto::VolumeRef<C> getChannelY( carto::VolumeRef<AimsRGB> in )
578  {
579  carto::VolumeRef<C> out = allocateVolume( in );
580  getChannelY( in, out );
581  return out;
582  }
583  carto::VolumeRef<C> getChannelZ( carto::VolumeRef<AimsRGB> in )
584  {
585  carto::VolumeRef<C> out = allocateVolume( in );
586  getChannelZ( in, out );
587  return out;
588  }
589  carto::VolumeRef<C> getChannelL( carto::VolumeRef<AimsRGB> in )
590  {
591  carto::VolumeRef<C> out = allocateVolume( in );
592  getChannelL( in, out );
593  return out;
594  }
595  carto::VolumeRef<C> getChannela( carto::VolumeRef<AimsRGB> in )
596  {
597  carto::VolumeRef<C> out = allocateVolume( in );
598  getChannela( in, out );
599  return out;
600  }
601  carto::VolumeRef<C> getChannelb( carto::VolumeRef<AimsRGB> in )
602  {
603  carto::VolumeRef<C> out = allocateVolume( in );
604  getChannelb( in, out );
605  return out;
606  }
607 
608  protected:
609  // helper
610  carto::VolumeRef<C> allocateVolume( carto::VolumeRef<AimsRGB> in )
611  {
612  carto::VolumeRef<C> out( in.getSizeX(), in.getSizeY(),
613  in.getSizeZ(), in.getSizeT() );
614  out->copyHeaderFrom( in.header() );
615  return out;
616  }
617  };
618 
619  template <typename C>
620  void ChannelExtractor<AimsRGB,C>::getChannelR( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
621  {
622  computeRuntimeMinMax<AimsRGB,C>( in, 0 );
623 
624  long dimx = in.getSizeX(),
625  dimy = in.getSizeY(),
626  dimz = in.getSizeZ(),
627  dimt = in.getSizeT();
628  for( long t=0; t< dimt; ++t )
629  for( long z=0; z< dimz; ++z )
630  for( long y=0; y< dimy; ++y )
631  for( long x=0; x< dimx; ++x )
632  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsRGB>::ChannelType,C>( in( x, y, z, t ).red() );
633  }
634 
635  template <typename C>
636  void ChannelExtractor<AimsRGB,C>::getChannelG( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
637  {
638  computeRuntimeMinMax<AimsRGB,C>( in, 1 );
639 
640  long dimx = in.getSizeX(),
641  dimy = in.getSizeY(),
642  dimz = in.getSizeZ(),
643  dimt = in.getSizeT();
644  for( long t=0; t< dimt; ++t )
645  for( long z=0; z< dimz; ++z )
646  for( long y=0; y< dimy; ++y )
647  for( long x=0; x< dimx; ++x )
648  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsRGB>::ChannelType,C>( in( x, y, z, t ).green() );
649  }
650 
651  template <typename C>
652  void ChannelExtractor<AimsRGB,C>::getChannelB( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
653  {
654  computeRuntimeMinMax<AimsRGB,C>( in, 2 );
655 
656  long dimx = in.getSizeX(),
657  dimy = in.getSizeY(),
658  dimz = in.getSizeZ(),
659  dimt = in.getSizeT();
660  for( long t=0; t< dimt; ++t )
661  for( long z=0; z< dimz; ++z )
662  for( long y=0; y< dimy; ++y )
663  for( long x=0; x< dimx; ++x )
664  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsRGB>::ChannelType,C>( in( x, y, z, t ).blue() );
665  }
666 
667  template <typename C>
668  void ChannelExtractor<AimsRGB,C>::getChannelRGBNorm( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
669  {
670  computeRuntimeMinMax<AimsRGB,C>( in );
671 
672  double val;
673  long dimx = in.getSizeX(),
674  dimy = in.getSizeY(),
675  dimz = in.getSizeZ(),
676  dimt = in.getSizeT();
677  for( long t=0; t< dimt; ++t )
678  for( long z=0; z< dimz; ++z )
679  for( long y=0; y< dimy; ++y )
680  for( long x=0; x< dimx; ++x )
681  {
682  val = (double) in( x, y, z, t ).red()
683  + (double) in( x, y, z, t ).green()
684  + (double) in( x, y, z, t ).blue();
685  val /= 3;
686  out( x, y, z, t ) = rescale<double,C>( val );
687  }
688  }
689 
690  template <typename C>
691  void ChannelExtractor<AimsRGB,C>::getChannelYl( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
692  {
693  computeRuntimeMinMax<AimsRGB,C>( in );
694 
695  double val;
696  long dimx = in.getSizeX(),
697  dimy = in.getSizeY(),
698  dimz = in.getSizeZ(),
699  dimt = in.getSizeT();
700  for( long t=0; t< dimt; ++t )
701  for( long z=0; z< dimz; ++z )
702  for( long y=0; y< dimy; ++y )
703  for( long x=0; x< dimx; ++x )
704  {
705  val = 0.299 * (double) in( x, y, z, t ).red()
706  + 0.587 * (double) in( x, y, z, t ).green()
707  + 0.114 * (double) in( x, y, z, t ).blue();
708  out( x, y, z, t ) = rescale<double,C>( val );
709  }
710  }
711 
712  template <typename C>
713  void ChannelExtractor<AimsRGB,C>::getChannelCb( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
714  {
715  computeRuntimeMinMax<AimsRGB,C>( in );
716 
717  double val;
718  long dimx = in.getSizeX(),
719  dimy = in.getSizeY(),
720  dimz = in.getSizeZ(),
721  dimt = in.getSizeT();
722  for( long t=0; t< dimt; ++t )
723  for( long z=0; z< dimz; ++z )
724  for( long y=0; y< dimy; ++y )
725  for( long x=0; x< dimx; ++x )
726  {
727  val = - 0.1687 * (double) in( x, y, z, t ).red()
728  - 0.3313 * (double) in( x, y, z, t ).green()
729  + 0.5 * (double) in( x, y, z, t ).blue()
730  + 128;
731  out( x, y, z, t ) = rescale<double,C>( val );
732  }
733  }
734 
735  template <typename C>
736  void ChannelExtractor<AimsRGB,C>::getChannelCr( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
737  {
738  computeRuntimeMinMax<AimsRGB,C>( in );
739 
740  double val;
741  long dimx = in.getSizeX(),
742  dimy = in.getSizeY(),
743  dimz = in.getSizeZ(),
744  dimt = in.getSizeT();
745  for( long t=0; t< dimt; ++t )
746  for( long z=0; z< dimz; ++z )
747  for( long y=0; y< dimy; ++y )
748  for( long x=0; x< dimx; ++x )
749  {
750  val = 0.5 * (double) in( x, y, z, t ).red()
751  - 0.4187 * (double) in( x, y, z, t ).green()
752  - 0.0813 * (double) in( x, y, z, t ).blue()
753  + 128;
754  out( x, y, z, t ) = rescale<double,C>( val );
755  }
756  }
757 
758  template <typename C>
759  void ChannelExtractor<AimsRGB,C>::getChannelH( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
760  {
761  computeRuntimeMinMax<AimsRGB,C>( in );
762 
763  double val;
764  long dimx = in.getSizeX(),
765  dimy = in.getSizeY(),
766  dimz = in.getSizeZ(),
767  dimt = in.getSizeT();
768  for( long t=0; t< dimt; ++t )
769  for( long z=0; z< dimz; ++z )
770  for( long y=0; y< dimy; ++y )
771  for( long x=0; x< dimx; ++x )
772  {
773  val = std::atan2( std::sqrt(3) * (
774  (double) in( x, y, z, t ).green() -
775  (double) in( x, y, z, t ).blue() ),
776  (double) 2.0 * (
777  (double) in( x, y, z, t ).red() -
778  (double) in( x, y, z, t ).green() -
779  (double) in( x, y, z, t ).blue() )
780  );
781  out( x, y, z, t ) = rescale<double,C>( val );
782  }
783  }
784 
785  template <typename C>
786  void ChannelExtractor<AimsRGB,C>::getChannelS( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
787  {
788  computeRuntimeMinMax<AimsRGB,C>( in );
789  double val, min, max;
790  long dimx = in.getSizeX(),
791  dimy = in.getSizeY(),
792  dimz = in.getSizeZ(),
793  dimt = in.getSizeT();
794  for( long t=0; t< dimt; ++t )
795  for( long z=0; z< dimz; ++z )
796  for( long y=0; y< dimy; ++y )
797  for( long x=0; x< dimx; ++x )
798  {
799  min = ( in( x, y, z, t ).red() <= in( x, y, z, t ).green()
800  ? (double) in( x, y, z, t ).red()
801  : (double) in( x, y, z, t ).green() );
802  min = ( min <= (double) in( x, y, z, t ).blue()
803  ? min
804  : in( x, y, z, t ).blue() );
805  max = ( in( x, y, z, t ).red() >= in( x, y, z, t ).green()
806  ? (double) in( x, y, z, t ).red()
807  : (double) in( x, y, z, t ).green() );
808  max = ( max >= (double) in( x, y, z, t ).blue()
809  ? max
810  : in( x, y, z, t ).blue() );
811  val = ( max == 0 ? max : 1.0 - min / max );
812  out( x, y, z, t ) = rescale<double,C>( val );
813  }
814  }
815 
816  template <typename C>
817  void ChannelExtractor<AimsRGB,C>::getChannelV( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
818  {
819  computeRuntimeMinMax<AimsRGB,C>( in );
820  double max;
821  long dimx = in.getSizeX(),
822  dimy = in.getSizeY(),
823  dimz = in.getSizeZ(),
824  dimt = in.getSizeT();
825  for( long t=0; t< dimt; ++t )
826  for( long z=0; z< dimz; ++z )
827  for( long y=0; y< dimy; ++y )
828  for( long x=0; x< dimx; ++x )
829  {
830  max = ( in( x, y, z, t ).red() >= in( x, y, z, t ).green()
831  ? (double) in( x, y, z, t ).red()
832  : (double) in( x, y, z, t ).green() );
833  max = ( max >= (double) in( x, y, z, t ).blue()
834  ? max
835  : in( x, y, z, t ).blue() );
836  out( x, y, z, t ) = rescale<double,C>( max );
837  }
838  }
839 
840  template <typename C>
841  void ChannelExtractor<AimsRGB,C>::getChannelX( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
842  {
843  computeRuntimeMinMax<AimsRGB,C>( in );
844  double valin[3];
845  double valout;
846  long dimx = in.getSizeX(),
847  dimy = in.getSizeY(),
848  dimz = in.getSizeZ(),
849  dimt = in.getSizeT();
850  for( long t=0; t< dimt; ++t )
851  for( long z=0; z< dimz; ++z )
852  for( long y=0; y< dimy; ++y )
853  for( long x=0; x< dimx; ++x )
854  {
855  valin[0] = ((double) in( x, y, z, t ).red())/255;
856  valin[1] = ((double) in( x, y, z, t ).green())/255;
857  valin[2] = ((double) in( x, y, z, t ).blue())/255;
858 
859  for( int n=0; n<3; ++n){
860  if( valin[n] > 0.04045 )
861  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
862  else
863  valin[n] = valin[n]/12.92;
864  }
865 
866  valout = 0.412453*valin[0] + 0.357580*valin[1] + 0.180423*valin[2];
867  valout *= 100;
868 
869  out( x, y, z, t ) = rescale<double,C>( valout );
870  }
871  }
872 
873  template <typename C>
874  void ChannelExtractor<AimsRGB,C>::getChannelY( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
875  {
876  computeRuntimeMinMax<AimsRGB,C>( in );
877  double valin[3];
878  double valout;
879  long dimx = in.getSizeX(),
880  dimy = in.getSizeY(),
881  dimz = in.getSizeZ(),
882  dimt = in.getSizeT();
883  for( long t=0; t< dimt; ++t )
884  for( long z=0; z< dimz; ++z )
885  for( long y=0; y< dimy; ++y )
886  for( long x=0; x< dimx; ++x )
887  {
888  valin[0] = ((double) in( x, y, z, t ).red())/255;
889  valin[1] = ((double) in( x, y, z, t ).green())/255;
890  valin[2] = ((double) in( x, y, z, t ).blue())/255;
891 
892  for( int n=0; n<3; ++n){
893  if( valin[n] > 0.04045 )
894  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
895  else
896  valin[n] = valin[n]/12.92;
897  }
898 
899  valout = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
900  valout *= 100;
901 
902  out( x, y, z, t ) = rescale<double,C>( valout );
903  }
904  }
905 
906  template <typename C>
907  void ChannelExtractor<AimsRGB,C>::getChannelZ( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
908  {
909  computeRuntimeMinMax<AimsRGB,C>( in );
910  double valin[3];
911  double valout;
912  long dimx = in.getSizeX(),
913  dimy = in.getSizeY(),
914  dimz = in.getSizeZ(),
915  dimt = in.getSizeT();
916  for( long t=0; t< dimt; ++t )
917  for( long z=0; z< dimz; ++z )
918  for( long y=0; y< dimy; ++y )
919  for( long x=0; x< dimx; ++x )
920  {
921  valin[0] = ((double) in( x, y, z, t ).red())/255;
922  valin[1] = ((double) in( x, y, z, t ).green())/255;
923  valin[2] = ((double) in( x, y, z, t ).blue())/255;
924 
925  for( int n=0; n<3; ++n){
926  if( valin[n] > 0.04045 )
927  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
928  else
929  valin[n] = valin[n]/12.92;
930  }
931 
932  valout = 0.019334*valin[0] + 0.119193*valin[1] + 0.950227*valin[2];
933  valout *= 100;
934 
935  out( x, y, z, t ) = rescale<double,C>( valout );
936  }
937  }
938 
939  template <typename C>
940  void ChannelExtractor<AimsRGB,C>::getChannelL( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
941  {
942  computeRuntimeMinMax<AimsRGB,C>( in );
943  double valin[3];
944  double valX, valY, valZ, valout;
945  long dimx = in.getSizeX(),
946  dimy = in.getSizeY(),
947  dimz = in.getSizeZ(),
948  dimt = in.getSizeT();
949  for( long t=0; t< dimt; ++t )
950  for( long z=0; z< dimz; ++z )
951  for( long y=0; y< dimy; ++y )
952  for( long x=0; x< dimx; ++x )
953  {
954  valin[0] = ((double) in( x, y, z, t ).red())/255;
955  valin[1] = ((double) in( x, y, z, t ).green())/255;
956  valin[2] = ((double) in( x, y, z, t ).blue())/255;
957 
958  for( int n=0; n<3; ++n){
959  if( valin[n] > 0.04045 )
960  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
961  else
962  valin[n] = valin[n]/12.92;
963  }
964 
965  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
966 
967  if( valY > 0.008856 ) {
968  valout = std::pow(valY, 0.333333);
969  } else {
970  valout = 7.787*valY + ((double)16/116);
971  }
972 
973  valout = 116*valout - 16;
974 
975  out( x, y, z, t ) = rescale<double,C>( valout );
976  }
977  }
978 
979  template <typename C>
980  void ChannelExtractor<AimsRGB,C>::getChannela( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
981  {
982  computeRuntimeMinMax<AimsRGB,C>( in );
983  double valin[3];
984  double valX, valY, valZ, valout;
985  long dimx = in.getSizeX(),
986  dimy = in.getSizeY(),
987  dimz = in.getSizeZ(),
988  dimt = in.getSizeT();
989  for( long t=0; t< dimt; ++t )
990  for( long z=0; z< dimz; ++z )
991  for( long y=0; y< dimy; ++y )
992  for( long x=0; x< dimx; ++x )
993  {
994  valin[0] = ((double) in( x, y, z, t ).red())/255;
995  valin[1] = ((double) in( x, y, z, t ).green())/255;
996  valin[2] = ((double) in( x, y, z, t ).blue())/255;
997 
998  for( int n=0; n<3; ++n){
999  if( valin[n] > 0.04045 )
1000  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1001  else
1002  valin[n] = valin[n]/12.92;
1003  }
1004 
1005  valX = (0.412453*valin[0] + 0.357580*valin[1] + 0.180423*valin[2])*((double)100/95.047);
1006  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
1007 
1008  valout = 0.0;
1009  if( valX > 0.008856 ) {
1010  valout += std::pow(valX, 0.333333);
1011  } else {
1012  valout += 7.787*valX + ((double)16/116);
1013  }
1014  if( valY > 0.008856 ) {
1015  valout -= std::pow(valY, 0.333333);
1016  } else {
1017  valout -= 7.787*valY + ((double)16/116);
1018  }
1019  valout *= 500;
1020 
1021  out( x, y, z, t ) = rescale<double,C>( valout );
1022  }
1023  }
1024 
1025  template <typename C>
1026  void ChannelExtractor<AimsRGB,C>::getChannelb( carto::VolumeRef<AimsRGB> in, carto::VolumeRef<C> out )
1027  {
1028  computeRuntimeMinMax<AimsRGB,C>( in );
1029  double valin[3];
1030  double valX, valY, valZ, valout;
1031  long dimx = in.getSizeX(),
1032  dimy = in.getSizeY(),
1033  dimz = in.getSizeZ(),
1034  dimt = in.getSizeT();
1035  for( long t=0; t< dimt; ++t )
1036  for( long z=0; z< dimz; ++z )
1037  for( long y=0; y< dimy; ++y )
1038  for( long x=0; x< dimx; ++x )
1039  {
1040  valin[0] = ((double) in( x, y, z, t ).red())/255;
1041  valin[1] = ((double) in( x, y, z, t ).green())/255;
1042  valin[2] = ((double) in( x, y, z, t ).blue())/255;
1043 
1044  for( int n=0; n<3; ++n){
1045  if( valin[n] > 0.04045 )
1046  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1047  else
1048  valin[n] = valin[n]/12.92;
1049  }
1050 
1051  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
1052  valZ = (0.019334*valin[0] + 0.119193*valin[1] + 0.950227*valin[2])*((double)100/108.883);
1053 
1054  valout = 0.0;
1055  if( valY > 0.008856 ) {
1056  valout += std::pow(valY, 0.333333);
1057  } else {
1058  valout += 7.787*valY + ((double)16/116);
1059  }
1060  if( valZ > 0.008856 ) {
1061  valout -= std::pow(valZ, 0.333333);
1062  } else {
1063  valout -= 7.787*valZ + ((double)16/116);
1064  }
1065  valout *= 200;
1066 
1067  out( x, y, z, t ) = rescale<double,C>( valout );
1068  }
1069  }
1070 
1071  //--- spec RGBA -------------------------------------------------------------
1072  template <typename C>
1073  class ChannelExtractor<AimsRGBA,C>: public Rescaler
1074  {
1075  public:
1077  Rescaler()
1078  {}
1079  virtual ~ChannelExtractor() {}
1080 
1081  // write in allocated volume
1082  void getChannelR( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1083  void getChannelG( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1084  void getChannelB( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1085  void getChannelA( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1086  void getChannelRGBNorm( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1087  void getChannelYl( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1088  void getChannelCb( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1089  void getChannelCr( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1090  void getChannelH( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1091  void getChannelS( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1092  void getChannelV( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1093  void getChannelX( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1094  void getChannelY( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1095  void getChannelZ( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1096  void getChannelL( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1097  void getChannela( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1098  void getChannelb( carto::VolumeRef<AimsRGBA>, carto::VolumeRef<C> );
1099 
1100  // allocate and write volume
1101  carto::VolumeRef<C> getChannelR( carto::VolumeRef<AimsRGBA> in )
1102  {
1103  carto::VolumeRef<C> out = allocateVolume( in );
1104  getChannelR( in, out );
1105  return out;
1106  }
1107  carto::VolumeRef<C> getChannelG( carto::VolumeRef<AimsRGBA> in )
1108  {
1109  carto::VolumeRef<C> out = allocateVolume( in );
1110  getChannelG( in, out );
1111  return out;
1112  }
1113  carto::VolumeRef<C> getChannelB( carto::VolumeRef<AimsRGBA> in )
1114  {
1115  carto::VolumeRef<C> out = allocateVolume( in );
1116  getChannelB( in, out );
1117  return out;
1118  }
1119  carto::VolumeRef<C> getChannelA( carto::VolumeRef<AimsRGBA> in )
1120  {
1121  carto::VolumeRef<C> out = allocateVolume( in );
1122  getChannelA( in, out );
1123  return out;
1124  }
1125  carto::VolumeRef<C> getChannelRGBNorm( carto::VolumeRef<AimsRGBA> in )
1126  {
1127  carto::VolumeRef<C> out = allocateVolume( in );
1128  getChannelRGBNorm( in, out );
1129  return out;
1130  }
1131  carto::VolumeRef<C> getChannelYl( carto::VolumeRef<AimsRGBA> in )
1132  {
1133  carto::VolumeRef<C> out = allocateVolume( in );
1134  getChannelYl( in, out );
1135  return out;
1136  }
1137  carto::VolumeRef<C> getChannelCb( carto::VolumeRef<AimsRGBA> in )
1138  {
1139  carto::VolumeRef<C> out = allocateVolume( in );
1140  getChannelCb( in, out );
1141  return out;
1142  }
1143  carto::VolumeRef<C> getChannelCr( carto::VolumeRef<AimsRGBA> in )
1144  {
1145  carto::VolumeRef<C> out = allocateVolume( in );
1146  getChannelCr( in, out );
1147  return out;
1148  }
1149  carto::VolumeRef<C> getChannelH( carto::VolumeRef<AimsRGBA> in )
1150  {
1151  carto::VolumeRef<C> out = allocateVolume( in );
1152  getChannelH( in, out );
1153  return out;
1154  }
1155  carto::VolumeRef<C> getChannelS( carto::VolumeRef<AimsRGBA> in )
1156  {
1157  carto::VolumeRef<C> out = allocateVolume( in );
1158  getChannelS( in, out );
1159  return out;
1160  }
1161  carto::VolumeRef<C> getChannelV( carto::VolumeRef<AimsRGBA> in )
1162  {
1163  carto::VolumeRef<C> out = allocateVolume( in );
1164  getChannelV( in, out );
1165  return out;
1166  }
1167  carto::VolumeRef<C> getChannelX( carto::VolumeRef<AimsRGBA> in )
1168  {
1169  carto::VolumeRef<C> out = allocateVolume( in );
1170  getChannelX( in, out );
1171  return out;
1172  }
1173  carto::VolumeRef<C> getChannelY( carto::VolumeRef<AimsRGBA> in )
1174  {
1175  carto::VolumeRef<C> out = allocateVolume( in );
1176  getChannelY( in, out );
1177  return out;
1178  }
1179  carto::VolumeRef<C> getChannelZ( carto::VolumeRef<AimsRGBA> in )
1180  {
1181  carto::VolumeRef<C> out = allocateVolume( in );
1182  getChannelZ( in, out );
1183  return out;
1184  }
1185  carto::VolumeRef<C> getChannelL( carto::VolumeRef<AimsRGBA> in )
1186  {
1187  carto::VolumeRef<C> out = allocateVolume( in );
1188  getChannelL( in, out );
1189  return out;
1190  }
1191  carto::VolumeRef<C> getChannela( carto::VolumeRef<AimsRGBA> in )
1192  {
1193  carto::VolumeRef<C> out = allocateVolume( in );
1194  getChannela( in, out );
1195  return out;
1196  }
1197  carto::VolumeRef<C> getChannelb( carto::VolumeRef<AimsRGBA> in )
1198  {
1199  carto::VolumeRef<C> out = allocateVolume( in );
1200  getChannelb( in, out );
1201  return out;
1202  }
1203 
1204  protected:
1205  // helper
1206  carto::VolumeRef<C> allocateVolume( carto::VolumeRef<AimsRGBA> in )
1207  {
1208  carto::VolumeRef<C> out( in.getSizeX(), in.getSizeY(),
1209  in.getSizeZ(), in.getSizeT() );
1210  out->copyHeaderFrom( in.header() );
1211  return out;
1212  }
1213  };
1214 
1215  template <typename C>
1216  void ChannelExtractor<AimsRGBA,C>::getChannelR( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1217  {
1218  computeRuntimeMinMax<AimsRGBA,C>( in, 0 );
1219 
1220  long dimx = in.getSizeX(),
1221  dimy = in.getSizeY(),
1222  dimz = in.getSizeZ(),
1223  dimt = in.getSizeT();
1224  for( long t=0; t< dimt; ++t )
1225  for( long z=0; z< dimz; ++z )
1226  for( long y=0; y< dimy; ++y )
1227  for( long x=0; x< dimx; ++x )
1228  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsRGBA>::ChannelType,C>( in( x, y, z, t ).red() );
1229  }
1230 
1231  template <typename C>
1232  void ChannelExtractor<AimsRGBA,C>::getChannelG( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1233  {
1234  computeRuntimeMinMax<AimsRGBA,C>( in, 1 );
1235 
1236  long dimx = in.getSizeX(),
1237  dimy = in.getSizeY(),
1238  dimz = in.getSizeZ(),
1239  dimt = in.getSizeT();
1240  for( long t=0; t< dimt; ++t )
1241  for( long z=0; z< dimz; ++z )
1242  for( long y=0; y< dimy; ++y )
1243  for( long x=0; x< dimx; ++x )
1244  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsRGBA>::ChannelType,C>( in( x, y, z, t ).green() );
1245  }
1246 
1247  template <typename C>
1248  void ChannelExtractor<AimsRGBA,C>::getChannelB( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1249  {
1250  computeRuntimeMinMax<AimsRGBA,C>( in, 2 );
1251 
1252  long dimx = in.getSizeX(),
1253  dimy = in.getSizeY(),
1254  dimz = in.getSizeZ(),
1255  dimt = in.getSizeT();
1256  for( long t=0; t< dimt; ++t )
1257  for( long z=0; z< dimz; ++z )
1258  for( long y=0; y< dimy; ++y )
1259  for( long x=0; x< dimx; ++x )
1260  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsRGBA>::ChannelType,C>( in( x, y, z, t ).blue() );
1261  }
1262 
1263  template <typename C>
1264  void ChannelExtractor<AimsRGBA,C>::getChannelA( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1265  {
1266  computeRuntimeMinMax<AimsRGBA,C>( in, 3 );
1267 
1268  long dimx = in.getSizeX(),
1269  dimy = in.getSizeY(),
1270  dimz = in.getSizeZ(),
1271  dimt = in.getSizeT();
1272  for( long t=0; t< dimt; ++t )
1273  for( long z=0; z< dimz; ++z )
1274  for( long y=0; y< dimy; ++y )
1275  for( long x=0; x< dimx; ++x )
1276  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsRGBA>::ChannelType,C>( in( x, y, z, t ).alpha() );
1277  }
1278 
1279  template <typename C>
1281  carto::VolumeRef<AimsRGBA> in,
1282  carto::VolumeRef<C> out)
1283  {
1284  computeRuntimeMinMax<AimsRGBA,C>( in );
1285 
1286 // std::cout << "==== ChannelExtractor<AimsRGBA,C>::getChannelRGBNorm "
1287 // << "rescale: " << carto::toString(_rescale) << ", "
1288 // << carto::toString(this->_a)
1289 // << "x + " << carto::toString(this->_b) << "]"
1290 // << std::endl << std::flush;
1291 // std::cout << "==== ChannelExtractor<AimsRGBA,C>::getChannelRGBNorm "
1292 // << "input range: ["<< carto::toString(this->_imin)
1293 // << "-" << carto::toString(this->_imax) << "], "
1294 // << "output range: ["<< carto::toString(this->_omin)
1295 // << "-" << carto::toString(this->_omax) << "]"
1296 // << std::endl << std::flush;
1297 
1298  double val;
1299 
1300  long dimx = in.getSizeX(),
1301  dimy = in.getSizeY(),
1302  dimz = in.getSizeZ(),
1303  dimt = in.getSizeT();
1304  for( long t=0; t< dimt; ++t )
1305  for( long z=0; z< dimz; ++z )
1306  for( long y=0; y< dimy; ++y )
1307  for( long x=0; x< dimx; ++x )
1308  {
1309  val = (double) in( x, y, z, t ).red()
1310  + (double) in( x, y, z, t ).green()
1311  + (double) in( x, y, z, t ).blue();
1312  val /= 3;
1313  out( x, y, z, t ) = rescale<double,C>( val );
1314  }
1315  }
1316 
1317  template <typename C>
1318  void ChannelExtractor<AimsRGBA,C>::getChannelYl( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1319  {
1320  computeRuntimeMinMax<AimsRGBA,C>( in );
1321 
1322  double val;
1323  long dimx = in.getSizeX(),
1324  dimy = in.getSizeY(),
1325  dimz = in.getSizeZ(),
1326  dimt = in.getSizeT();
1327  for( long t=0; t< dimt; ++t )
1328  for( long z=0; z< dimz; ++z )
1329  for( long y=0; y< dimy; ++y )
1330  for( long x=0; x< dimx; ++x )
1331  {
1332  val = 0.299 * (double) in( x, y, z, t ).red()
1333  + 0.587 * (double) in( x, y, z, t ).green()
1334  + 0.114 * (double) in( x, y, z, t ).blue();
1335  out( x, y, z, t ) = rescale<double,C>( val );
1336  }
1337  }
1338 
1339  template <typename C>
1340  void ChannelExtractor<AimsRGBA,C>::getChannelCb( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1341  {
1342  computeRuntimeMinMax<AimsRGBA,C>( in );
1343 
1344  double val;
1345  long dimx = in.getSizeX(),
1346  dimy = in.getSizeY(),
1347  dimz = in.getSizeZ(),
1348  dimt = in.getSizeT();
1349  for( long t=0; t< dimt; ++t )
1350  for( long z=0; z< dimz; ++z )
1351  for( long y=0; y< dimy; ++y )
1352  for( long x=0; x< dimx; ++x )
1353  {
1354  val = - 0.1687 * (double) in( x, y, z, t ).red()
1355  - 0.3313 * (double) in( x, y, z, t ).green()
1356  + 0.5 * (double) in( x, y, z, t ).blue()
1357  + 128;
1358  out( x, y, z, t ) = rescale<double,C>( val );
1359  }
1360  }
1361 
1362  template <typename C>
1363  void ChannelExtractor<AimsRGBA,C>::getChannelCr( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1364  {
1365  computeRuntimeMinMax<AimsRGBA,C>( in );
1366 
1367  double val;
1368  long dimx = in.getSizeX(),
1369  dimy = in.getSizeY(),
1370  dimz = in.getSizeZ(),
1371  dimt = in.getSizeT();
1372  for( long t=0; t< dimt; ++t )
1373  for( long z=0; z< dimz; ++z )
1374  for( long y=0; y< dimy; ++y )
1375  for( long x=0; x< dimx; ++x )
1376  {
1377  val = 0.5 * (double) in( x, y, z, t ).red()
1378  - 0.4187 * (double) in( x, y, z, t ).green()
1379  - 0.0813 * (double) in( x, y, z, t ).blue()
1380  + 128;
1381  out( x, y, z, t ) = rescale<double,C>( val );
1382  }
1383  }
1384 
1385  template <typename C>
1386  void ChannelExtractor<AimsRGBA,C>::getChannelH( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1387  {
1388  computeRuntimeMinMax<AimsRGBA,C>( in );
1389 
1390  double val;
1391  long dimx = in.getSizeX(),
1392  dimy = in.getSizeY(),
1393  dimz = in.getSizeZ(),
1394  dimt = in.getSizeT();
1395  for( long t=0; t< dimt; ++t )
1396  for( long z=0; z< dimz; ++z )
1397  for( long y=0; y< dimy; ++y )
1398  for( long x=0; x< dimx; ++x )
1399  {
1400  val = std::atan2( std::sqrt(3) * (
1401  (double) in( x, y, z, t ).green() -
1402  (double) in( x, y, z, t ).blue() ),
1403  (double) 2.0 * (
1404  (double) in( x, y, z, t ).red() -
1405  (double) in( x, y, z, t ).green() -
1406  (double) in( x, y, z, t ).blue() )
1407  );
1408  out( x, y, z, t ) = rescale<double,C>( val );
1409  }
1410  }
1411 
1412  template <typename C>
1413  void ChannelExtractor<AimsRGBA,C>::getChannelS( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1414  {
1415  computeRuntimeMinMax<AimsRGBA,C>( in );
1416  double val, min, max;
1417  long dimx = in.getSizeX(),
1418  dimy = in.getSizeY(),
1419  dimz = in.getSizeZ(),
1420  dimt = in.getSizeT();
1421  for( long t=0; t< dimt; ++t )
1422  for( long z=0; z< dimz; ++z )
1423  for( long y=0; y< dimy; ++y )
1424  for( long x=0; x< dimx; ++x )
1425  {
1426  min = ( in( x, y, z, t ).red() <= in( x, y, z, t ).green()
1427  ? (double) in( x, y, z, t ).red()
1428  : (double) in( x, y, z, t ).green() );
1429  min = ( min <= (double) in( x, y, z, t ).blue()
1430  ? min
1431  : in( x, y, z, t ).blue() );
1432  max = ( in( x, y, z, t ).red() >= in( x, y, z, t ).green()
1433  ? (double) in( x, y, z, t ).red()
1434  : (double) in( x, y, z, t ).green() );
1435  max = ( max >= (double) in( x, y, z, t ).blue()
1436  ? max
1437  : in( x, y, z, t ).blue() );
1438  val = ( max == 0 ? max : 1.0 - min / max );
1439  out( x, y, z, t ) = rescale<double,C>( val );
1440  }
1441  }
1442 
1443  template <typename C>
1444  void ChannelExtractor<AimsRGBA,C>::getChannelV( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1445  {
1446  computeRuntimeMinMax<AimsRGBA,C>( in );
1447  double max;
1448  long dimx = in.getSizeX(),
1449  dimy = in.getSizeY(),
1450  dimz = in.getSizeZ(),
1451  dimt = in.getSizeT();
1452  for( long t=0; t< dimt; ++t )
1453  for( long z=0; z< dimz; ++z )
1454  for( long y=0; y< dimy; ++y )
1455  for( long x=0; x< dimx; ++x )
1456  {
1457  max = ( in( x, y, z, t ).red() >= in( x, y, z, t ).green()
1458  ? (double) in( x, y, z, t ).red()
1459  : (double) in( x, y, z, t ).green() );
1460  max = ( max >= (double) in( x, y, z, t ).blue()
1461  ? max
1462  : in( x, y, z, t ).blue() );
1463  out( x, y, z, t ) = rescale<double,C>( max );
1464  }
1465  }
1466 
1467  template <typename C>
1468  void ChannelExtractor<AimsRGBA,C>::getChannelX( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1469  {
1470  computeRuntimeMinMax<AimsRGBA,C>( in );
1471  double valin[3];
1472  double valout;
1473  long dimx = in.getSizeX(),
1474  dimy = in.getSizeY(),
1475  dimz = in.getSizeZ(),
1476  dimt = in.getSizeT();
1477  for( long t=0; t< dimt; ++t )
1478  for( long z=0; z< dimz; ++z )
1479  for( long y=0; y< dimy; ++y )
1480  for( long x=0; x< dimx; ++x )
1481  {
1482  valin[0] = ((double) in( x, y, z, t ).red())/255;
1483  valin[1] = ((double) in( x, y, z, t ).green())/255;
1484  valin[2] = ((double) in( x, y, z, t ).blue())/255;
1485 
1486  for( int n=0; n<3; ++n){
1487  if( valin[n] > 0.04045 )
1488  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1489  else
1490  valin[n] = valin[n]/12.92;
1491  }
1492 
1493  valout = 0.412453*valin[0] + 0.357580*valin[1] + 0.180423*valin[2];
1494  valout *= 100;
1495 
1496  out( x, y, z, t ) = rescale<double,C>( valout );
1497  }
1498  }
1499 
1500  template <typename C>
1501  void ChannelExtractor<AimsRGBA,C>::getChannelY( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1502  {
1503  computeRuntimeMinMax<AimsRGBA,C>( in );
1504  double valin[3];
1505  double valout;
1506  long dimx = in.getSizeX(),
1507  dimy = in.getSizeY(),
1508  dimz = in.getSizeZ(),
1509  dimt = in.getSizeT();
1510  for( long t=0; t< dimt; ++t )
1511  for( long z=0; z< dimz; ++z )
1512  for( long y=0; y< dimy; ++y )
1513  for( long x=0; x< dimx; ++x )
1514  {
1515  valin[0] = ((double) in( x, y, z, t ).red())/255;
1516  valin[1] = ((double) in( x, y, z, t ).green())/255;
1517  valin[2] = ((double) in( x, y, z, t ).blue())/255;
1518 
1519  for( int n=0; n<3; ++n){
1520  if( valin[n] > 0.04045 )
1521  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1522  else
1523  valin[n] = valin[n]/12.92;
1524  }
1525 
1526  valout = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
1527  valout *= 100;
1528 
1529  out( x, y, z, t ) = rescale<double,C>( valout );
1530  }
1531  }
1532 
1533  template <typename C>
1534  void ChannelExtractor<AimsRGBA,C>::getChannelZ( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1535  {
1536  computeRuntimeMinMax<AimsRGBA,C>( in );
1537  double valin[3];
1538  double valout;
1539  long dimx = in.getSizeX(),
1540  dimy = in.getSizeY(),
1541  dimz = in.getSizeZ(),
1542  dimt = in.getSizeT();
1543  for( long t=0; t< dimt; ++t )
1544  for( long z=0; z< dimz; ++z )
1545  for( long y=0; y< dimy; ++y )
1546  for( long x=0; x< dimx; ++x )
1547  {
1548  valin[0] = ((double) in( x, y, z, t ).red())/255;
1549  valin[1] = ((double) in( x, y, z, t ).green())/255;
1550  valin[2] = ((double) in( x, y, z, t ).blue())/255;
1551 
1552  for( int n=0; n<3; ++n){
1553  if( valin[n] > 0.04045 )
1554  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1555  else
1556  valin[n] = valin[n]/12.92;
1557  }
1558 
1559  valout = 0.019334*valin[0] + 0.119193*valin[1] + 0.950227*valin[2];
1560  valout *= 100;
1561 
1562  out( x, y, z, t ) = rescale<double,C>( valout );
1563  }
1564  }
1565 
1566  template <typename C>
1567  void ChannelExtractor<AimsRGBA,C>::getChannelL( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1568  {
1569  computeRuntimeMinMax<AimsRGBA,C>( in );
1570  double valin[3];
1571  double valX, valY, valZ, valout;
1572  long dimx = in.getSizeX(),
1573  dimy = in.getSizeY(),
1574  dimz = in.getSizeZ(),
1575  dimt = in.getSizeT();
1576  for( long t=0; t< dimt; ++t )
1577  for( long z=0; z< dimz; ++z )
1578  for( long y=0; y< dimy; ++y )
1579  for( long x=0; x< dimx; ++x )
1580  {
1581  valin[0] = ((double) in( x, y, z, t ).red())/255;
1582  valin[1] = ((double) in( x, y, z, t ).green())/255;
1583  valin[2] = ((double) in( x, y, z, t ).blue())/255;
1584 
1585  for( int n=0; n<3; ++n){
1586  if( valin[n] > 0.04045 )
1587  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1588  else
1589  valin[n] = valin[n]/12.92;
1590  }
1591 
1592  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
1593 
1594  if( valY > 0.008856 ) {
1595  valout = std::pow(valY, 0.333333);
1596  } else {
1597  valout = 7.787*valY + ((double)16/116);
1598  }
1599 
1600  valout = 116*valout - 16;
1601 
1602  out( x, y, z, t ) = rescale<double,C>( valout );
1603  }
1604  }
1605 
1606  template <typename C>
1607  void ChannelExtractor<AimsRGBA,C>::getChannela( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1608  {
1609  computeRuntimeMinMax<AimsRGBA,C>( in );
1610  double valin[3];
1611  double valX, valY, valZ, valout;
1612  long dimx = in.getSizeX(),
1613  dimy = in.getSizeY(),
1614  dimz = in.getSizeZ(),
1615  dimt = in.getSizeT();
1616  for( long t=0; t< dimt; ++t )
1617  for( long z=0; z< dimz; ++z )
1618  for( long y=0; y< dimy; ++y )
1619  for( long x=0; x< dimx; ++x )
1620  {
1621  valin[0] = ((double) in( x, y, z, t ).red())/255;
1622  valin[1] = ((double) in( x, y, z, t ).green())/255;
1623  valin[2] = ((double) in( x, y, z, t ).blue())/255;
1624 
1625  for( int n=0; n<3; ++n){
1626  if( valin[n] > 0.04045 )
1627  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1628  else
1629  valin[n] = valin[n]/12.92;
1630  }
1631 
1632  valX = (0.412453*valin[0] + 0.357580*valin[1] + 0.180423*valin[2])*((double)100/95.047);
1633  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
1634 
1635  valout = 0.0;
1636  if( valX > 0.008856 ) {
1637  valout += std::pow(valX, 0.333333);
1638  } else {
1639  valout += 7.787*valX + ((double)16/116);
1640  }
1641  if( valY > 0.008856 ) {
1642  valout -= std::pow(valY, 0.333333);
1643  } else {
1644  valout -= 7.787*valY + ((double)16/116);
1645  }
1646  valout *= 500;
1647 
1648  out( x, y, z, t ) = rescale<double,C>( valout );
1649  }
1650  }
1651 
1652  template <typename C>
1653  void ChannelExtractor<AimsRGBA,C>::getChannelb( carto::VolumeRef<AimsRGBA> in, carto::VolumeRef<C> out )
1654  {
1655  computeRuntimeMinMax<AimsRGBA,C>( in );
1656  double valin[3];
1657  double valX, valY, valZ, valout;
1658  long dimx = in.getSizeX(),
1659  dimy = in.getSizeY(),
1660  dimz = in.getSizeZ(),
1661  dimt = in.getSizeT();
1662  for( long t=0; t< dimt; ++t )
1663  for( long z=0; z< dimz; ++z )
1664  for( long y=0; y< dimy; ++y )
1665  for( long x=0; x< dimx; ++x )
1666  {
1667  valin[0] = ((double) in( x, y, z, t ).red())/255;
1668  valin[1] = ((double) in( x, y, z, t ).green())/255;
1669  valin[2] = ((double) in( x, y, z, t ).blue())/255;
1670 
1671  for( int n=0; n<3; ++n){
1672  if( valin[n] > 0.04045 )
1673  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
1674  else
1675  valin[n] = valin[n]/12.92;
1676  }
1677 
1678  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
1679  valZ = (0.019334*valin[0] + 0.119193*valin[1] + 0.950227*valin[2])*((double)100/108.883);
1680 
1681  valout = 0.0;
1682  if( valY > 0.008856 ) {
1683  valout += std::pow(valY, 0.333333);
1684  } else {
1685  valout += 7.787*valY + ((double)16/116);
1686  }
1687  if( valZ > 0.008856 ) {
1688  valout -= std::pow(valZ, 0.333333);
1689  } else {
1690  valout -= 7.787*valZ + ((double)16/116);
1691  }
1692  valout *= 200;
1693 
1694  out( x, y, z, t ) = rescale<double,C>( valout );
1695  }
1696  }
1697 
1698  //--- spec HSV -------------------------------------------------------------
1699  template <typename C>
1700  class ChannelExtractor<AimsHSV,C>: public Rescaler
1701  {
1702  public:
1704  Rescaler()
1705  {}
1706  virtual ~ChannelExtractor() {}
1707 
1708  // write in allocated volume
1709  void getChannelR( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1710  void getChannelG( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1711  void getChannelB( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1712  void getChannelRGBNorm( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1713  void getChannelYl( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1714  void getChannelCb( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1715  void getChannelCr( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1716  void getChannelH( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1717  void getChannelS( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1718  void getChannelV( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1719  void getChannelX( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1720  void getChannelY( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1721  void getChannelZ( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1722  void getChannelL( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1723  void getChannela( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1724  void getChannelb( carto::VolumeRef<AimsHSV>, carto::VolumeRef<C> );
1725 
1726  // allocate and write volume
1727  carto::VolumeRef<C> getChannelR( carto::VolumeRef<AimsHSV> in )
1728  {
1729  carto::VolumeRef<C> out = allocateVolume( in );
1730  getChannelR( in, out );
1731  return out;
1732  }
1733  carto::VolumeRef<C> getChannelG( carto::VolumeRef<AimsHSV> in )
1734  {
1735  carto::VolumeRef<C> out = allocateVolume( in );
1736  getChannelG( in, out );
1737  return out;
1738  }
1739  carto::VolumeRef<C> getChannelB( carto::VolumeRef<AimsHSV> in )
1740  {
1741  carto::VolumeRef<C> out = allocateVolume( in );
1742  getChannelB( in, out );
1743  return out;
1744  }
1745  carto::VolumeRef<C> getChannelRGBNorm( carto::VolumeRef<AimsHSV> in )
1746  {
1747  carto::VolumeRef<C> out = allocateVolume( in );
1748  getChannelRGBNorm( in, out );
1749  return out;
1750  }
1751  carto::VolumeRef<C> getChannelYl( carto::VolumeRef<AimsHSV> in )
1752  {
1753  carto::VolumeRef<C> out = allocateVolume( in );
1754  getChannelYl( in, out );
1755  return out;
1756  }
1757  carto::VolumeRef<C> getChannelCb( carto::VolumeRef<AimsHSV> in )
1758  {
1759  carto::VolumeRef<C> out = allocateVolume( in );
1760  getChannelCb( in, out );
1761  return out;
1762  }
1763  carto::VolumeRef<C> getChannelCr( carto::VolumeRef<AimsHSV> in )
1764  {
1765  carto::VolumeRef<C> out = allocateVolume( in );
1766  getChannelCr( in, out );
1767  return out;
1768  }
1769  carto::VolumeRef<C> getChannelH( carto::VolumeRef<AimsHSV> in )
1770  {
1771  carto::VolumeRef<C> out = allocateVolume( in );
1772  getChannelH( in, out );
1773  return out;
1774  }
1775  carto::VolumeRef<C> getChannelS( carto::VolumeRef<AimsHSV> in )
1776  {
1777  carto::VolumeRef<C> out = allocateVolume( in );
1778  getChannelS( in, out );
1779  return out;
1780  }
1781  carto::VolumeRef<C> getChannelV( carto::VolumeRef<AimsHSV> in )
1782  {
1783  carto::VolumeRef<C> out = allocateVolume( in );
1784  getChannelV( in, out );
1785  return out;
1786  }
1787  carto::VolumeRef<C> getChannelX( carto::VolumeRef<AimsHSV> in )
1788  {
1789  carto::VolumeRef<C> out = allocateVolume( in );
1790  getChannelX( in, out );
1791  return out;
1792  }
1793  carto::VolumeRef<C> getChannelY( carto::VolumeRef<AimsHSV> in )
1794  {
1795  carto::VolumeRef<C> out = allocateVolume( in );
1796  getChannelY( in, out );
1797  return out;
1798  }
1799  carto::VolumeRef<C> getChannelZ( carto::VolumeRef<AimsHSV> in )
1800  {
1801  carto::VolumeRef<C> out = allocateVolume( in );
1802  getChannelZ( in, out );
1803  return out;
1804  }
1805  carto::VolumeRef<C> getChannelL( carto::VolumeRef<AimsHSV> in )
1806  {
1807  carto::VolumeRef<C> out = allocateVolume( in );
1808  getChannelL( in, out );
1809  return out;
1810  }
1811  carto::VolumeRef<C> getChannela( carto::VolumeRef<AimsHSV> in )
1812  {
1813  carto::VolumeRef<C> out = allocateVolume( in );
1814  getChannela( in, out );
1815  return out;
1816  }
1817  carto::VolumeRef<C> getChannelb( carto::VolumeRef<AimsHSV> in )
1818  {
1819  carto::VolumeRef<C> out = allocateVolume( in );
1820  getChannelb( in, out );
1821  return out;
1822  }
1823 
1824  protected:
1825  // helper
1826  carto::VolumeRef<C> allocateVolume( carto::VolumeRef<AimsHSV> in )
1827  {
1828  carto::VolumeRef<C> out( in.getSizeX(), in.getSizeY(),
1829  in.getSizeZ(), in.getSizeT() );
1830  out->copyHeaderFrom( in.header() );
1831  return out;
1832  }
1833  };
1834 
1835  template <typename C>
1836  void ChannelExtractor<AimsHSV,C>::getChannelR( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
1837  {
1838  computeRuntimeMinMax<AimsHSV,C>( in );
1839  int valH;
1840  double valS, valV, valC, valX, valM, val;
1841  long dimx = in.getSizeX(),
1842  dimy = in.getSizeY(),
1843  dimz = in.getSizeZ(),
1844  dimt = in.getSizeT();
1845  for( long t=0; t< dimt; ++t )
1846  for( long z=0; z< dimz; ++z )
1847  for( long y=0; y< dimy; ++y )
1848  for( long x=0; x< dimx; ++x ){
1849  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
1850  valS = ((double) in( x, y, z, t ).saturation())/255;
1851  valV = ((double) in( x, y, z, t ).value())/255;
1852  valC = valV*valS;
1853  valX = valC*(1-abs((valH/60)%2-1));
1854  valM = valV-valC;
1855 
1856  if (valH<120 || valH>=240){
1857  if(60<=valH<300){
1858  val = valX;
1859  }else{
1860  val = valC;
1861  }
1862  }
1863 
1864  val += valM;
1865  val *= 255;
1866  out( x, y, z, t ) = rescale<double,C>( val );
1867  }
1868  }
1869 
1870  template <typename C>
1871  void ChannelExtractor<AimsHSV,C>::getChannelG( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
1872  {
1873  computeRuntimeMinMax<AimsHSV,C>( in );
1874  int valH;
1875  double valS, valV, valC, valX, valM, val;
1876  long dimx = in.getSizeX(),
1877  dimy = in.getSizeY(),
1878  dimz = in.getSizeZ(),
1879  dimt = in.getSizeT();
1880  for( long t=0; t< dimt; ++t )
1881  for( long z=0; z< dimz; ++z )
1882  for( long y=0; y< dimy; ++y )
1883  for( long x=0; x< dimx; ++x ){
1884  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
1885  valS = ((double) in( x, y, z, t ).saturation())/255;
1886  valV = ((double) in( x, y, z, t ).value())/255;
1887  valC = valV*valS;
1888  valX = valC*(1-abs((valH/60)%2-1));
1889  valM = valV-valC;
1890 
1891  if (valH<240){
1892  if(60<=valH<180){
1893  val = valC;
1894  }else{
1895  val = valX;
1896  }
1897  }
1898 
1899  val += valM;
1900  val *= 255;
1901  out( x, y, z, t ) = rescale<double,C>( val );
1902  }
1903  }
1904 
1905  template <typename C>
1906  void ChannelExtractor<AimsHSV,C>::getChannelB( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
1907  {
1908  computeRuntimeMinMax<AimsHSV,C>( in );
1909  int valH;
1910  double valS, valV, valC, valX, valM, val;
1911  long dimx = in.getSizeX(),
1912  dimy = in.getSizeY(),
1913  dimz = in.getSizeZ(),
1914  dimt = in.getSizeT();
1915  for( long t=0; t< dimt; ++t )
1916  for( long z=0; z< dimz; ++z )
1917  for( long y=0; y< dimy; ++y )
1918  for( long x=0; x< dimx; ++x ){
1919  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
1920  valS = ((double) in( x, y, z, t ).saturation())/255;
1921  valV = ((double) in( x, y, z, t ).value())/255;
1922  valC = valV*valS;
1923  valX = valC*(1-abs((valH/60)%2-1));
1924  valM = valV-valC;
1925 
1926  if (valH>=120){
1927  if(180<=valH<300){
1928  val = valC;
1929  }else{
1930  val = valX;
1931  }
1932  }
1933 
1934  val += valM;
1935  val *= 255;
1936  out( x, y, z, t ) = rescale<double,C>( val );
1937  }
1938  }
1939 
1940  template <typename C>
1941  void ChannelExtractor<AimsHSV,C>::getChannelRGBNorm( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
1942  {
1943  computeRuntimeMinMax<AimsHSV,C>( in );
1944  int valH;
1945  double valS, valV, valC, valX, valM, valR, valG, valB, val;
1946  long dimx = in.getSizeX(),
1947  dimy = in.getSizeY(),
1948  dimz = in.getSizeZ(),
1949  dimt = in.getSizeT();
1950  for( long t=0; t< dimt; ++t )
1951  for( long z=0; z< dimz; ++z )
1952  for( long y=0; y< dimy; ++y )
1953  for( long x=0; x< dimx; ++x ){
1954  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
1955  valS = ((double) in( x, y, z, t ).saturation())/255;
1956  valV = ((double) in( x, y, z, t ).value())/255;
1957  valC = valV*valS;
1958  valX = valC*(1-abs((valH/60)%2-1));
1959  valM = valV-valC;
1960 
1961  if (valH<120 || valH>=240){
1962  if(60<=valH<300){
1963  valR = valX;
1964  }else{
1965  valR = valC;
1966  }
1967  }
1968 
1969  valR += valM;
1970  valR *= 255;
1971 
1972  if (valH<240){
1973  if(60<=valH<180){
1974  valG = valC;
1975  }else{
1976  valG = valX;
1977  }
1978  }
1979 
1980  valG += valM;
1981  valG *= 255;
1982 
1983  if (valH>=120){
1984  if(180<=valH<300){
1985  valB = valC;
1986  }else{
1987  valB = valX;
1988  }
1989  }
1990 
1991  valB += valM;
1992  valB *= 255;
1993 
1994  val = valR + valG + valB;
1995  val /= 3;
1996  out( x, y, z, t ) = rescale<double,C>( val );
1997  }
1998  }
1999 
2000  template <typename C>
2001  void ChannelExtractor<AimsHSV,C>::getChannelYl( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2002  {
2003  computeRuntimeMinMax<AimsHSV,C>( in );
2004  int valH;
2005  double valS, valV, valC, valX, valM, valR, valG, valB, val;
2006  long dimx = in.getSizeX(),
2007  dimy = in.getSizeY(),
2008  dimz = in.getSizeZ(),
2009  dimt = in.getSizeT();
2010  for( long t=0; t< dimt; ++t )
2011  for( long z=0; z< dimz; ++z )
2012  for( long y=0; y< dimy; ++y )
2013  for( long x=0; x< dimx; ++x ){
2014  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2015  valS = ((double) in( x, y, z, t ).saturation())/255;
2016  valV = ((double) in( x, y, z, t ).value())/255;
2017  valC = valV*valS;
2018  valX = valC*(1-abs((valH/60)%2-1));
2019  valM = valV-valC;
2020 
2021  if (valH<120 || valH>=240){
2022  if(60<=valH<300){
2023  valR = valX;
2024  }else{
2025  valR = valC;
2026  }
2027  }
2028 
2029  valR += valM;
2030  valR *= 255;
2031 
2032  if (valH<240){
2033  if(60<=valH<180){
2034  valG = valC;
2035  }else{
2036  valG = valX;
2037  }
2038  }
2039 
2040  valG += valM;
2041  valG *= 255;
2042 
2043  if (valH>=120){
2044  if(180<=valH<300){
2045  valB = valC;
2046  }else{
2047  valB = valX;
2048  }
2049  }
2050 
2051  valB += valM;
2052  valB *= 255;
2053 
2054  val = 0.299 * valR + 0.587 * valG + 0.114 * valB;
2055  out( x, y, z, t ) = rescale<double,C>( val );
2056  }
2057  }
2058 
2059  template <typename C>
2060  void ChannelExtractor<AimsHSV,C>::getChannelCb( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2061  {
2062  computeRuntimeMinMax<AimsHSV,C>( in );
2063  int valH;
2064  double valS, valV, valC, valX, valM, valR, valG, valB, val;
2065  long dimx = in.getSizeX(),
2066  dimy = in.getSizeY(),
2067  dimz = in.getSizeZ(),
2068  dimt = in.getSizeT();
2069  for( long t=0; t< dimt; ++t )
2070  for( long z=0; z< dimz; ++z )
2071  for( long y=0; y< dimy; ++y )
2072  for( long x=0; x< dimx; ++x ){
2073  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2074  valS = ((double) in( x, y, z, t ).saturation())/255;
2075  valV = ((double) in( x, y, z, t ).value())/255;
2076  valC = valV*valS;
2077  valX = valC*(1-abs((valH/60)%2-1));
2078  valM = valV-valC;
2079 
2080  if (valH<120 || valH>=240){
2081  if(60<=valH<300){
2082  valR = valX;
2083  }else{
2084  valR = valC;
2085  }
2086  }
2087 
2088  valR += valM;
2089  valR *= 255;
2090 
2091  if (valH<240){
2092  if(60<=valH<180){
2093  valG = valC;
2094  }else{
2095  valG = valX;
2096  }
2097  }
2098 
2099  valG += valM;
2100  valG *= 255;
2101 
2102  if (valH>=120){
2103  if(180<=valH<300){
2104  valB = valC;
2105  }else{
2106  valB = valX;
2107  }
2108  }
2109 
2110  valB += valM;
2111  valB *= 255;
2112 
2113  val = - 0.1687 * valR - 0.3313 * valG + 0.5 * valB + 128;
2114  out( x, y, z, t ) = rescale<double,C>( val );
2115  }
2116  }
2117 
2118  template <typename C>
2119  void ChannelExtractor<AimsHSV,C>::getChannelCr( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2120  {
2121  computeRuntimeMinMax<AimsHSV,C>( in );
2122  int valH;
2123  double valS, valV, valC, valX, valM, valR, valG, valB, val;
2124  long dimx = in.getSizeX(),
2125  dimy = in.getSizeY(),
2126  dimz = in.getSizeZ(),
2127  dimt = in.getSizeT();
2128  for( long t=0; t< dimt; ++t )
2129  for( long z=0; z< dimz; ++z )
2130  for( long y=0; y< dimy; ++y )
2131  for( long x=0; x< dimx; ++x ){
2132  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2133  valS = ((double) in( x, y, z, t ).saturation())/255;
2134  valV = ((double) in( x, y, z, t ).value())/255;
2135  valC = valV*valS;
2136  valX = valC*(1-abs((valH/60)%2-1));
2137  valM = valV-valC;
2138 
2139  if (valH<120 || valH>=240){
2140  if(60<=valH<300){
2141  valR = valX;
2142  }else{
2143  valR = valC;
2144  }
2145  }
2146 
2147  valR += valM;
2148  valR *= 255;
2149 
2150  if (valH<240){
2151  if(60<=valH<180){
2152  valG = valC;
2153  }else{
2154  valG = valX;
2155  }
2156  }
2157 
2158  valG += valM;
2159  valG *= 255;
2160 
2161  if (valH>=120){
2162  if(180<=valH<300){
2163  valB = valC;
2164  }else{
2165  valB = valX;
2166  }
2167  }
2168 
2169  valB += valM;
2170  valB *= 255;
2171 
2172  val = 0.5 * valR - 0.4187 * valG - 0.0813 * valB + 128;
2173  out( x, y, z, t ) = rescale<double,C>( val );
2174  }
2175  }
2176 
2177  template <typename C>
2178  void ChannelExtractor<AimsHSV,C>::getChannelH( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2179  {
2180  computeRuntimeMinMax<AimsHSV,C>( in, 0 );
2181 
2182  long dimx = in.getSizeX(),
2183  dimy = in.getSizeY(),
2184  dimz = in.getSizeZ(),
2185  dimt = in.getSizeT();
2186  for( long t=0; t< dimt; ++t )
2187  for( long z=0; z< dimz; ++z )
2188  for( long y=0; y< dimy; ++y )
2189  for( long x=0; x< dimx; ++x )
2190  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsHSV>::ChannelType,C>( in( x, y, z, t ).hue() );
2191  }
2192 
2193  template <typename C>
2194  void ChannelExtractor<AimsHSV,C>::getChannelS( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2195  {
2196  computeRuntimeMinMax<AimsHSV,C>( in, 1 );
2197 
2198  long dimx = in.getSizeX(),
2199  dimy = in.getSizeY(),
2200  dimz = in.getSizeZ(),
2201  dimt = in.getSizeT();
2202  for( long t=0; t< dimt; ++t )
2203  for( long z=0; z< dimz; ++z )
2204  for( long y=0; y< dimy; ++y )
2205  for( long x=0; x< dimx; ++x )
2206  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsHSV>::ChannelType,C>( in( x, y, z, t ).saturation() );
2207  }
2208 
2209  template <typename C>
2210  void ChannelExtractor<AimsHSV,C>::getChannelV( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2211  {
2212  computeRuntimeMinMax<AimsHSV,C>( in, 2 );
2213 
2214  long dimx = in.getSizeX(),
2215  dimy = in.getSizeY(),
2216  dimz = in.getSizeZ(),
2217  dimt = in.getSizeT();
2218  for( long t=0; t< dimt; ++t )
2219  for( long z=0; z< dimz; ++z )
2220  for( long y=0; y< dimy; ++y )
2221  for( long x=0; x< dimx; ++x )
2222  out( x, y, z, t ) = rescale<carto::DataTypeTraits<AimsHSV>::ChannelType,C>( in( x, y, z, t ).value() );
2223  }
2224 
2225  template <typename C>
2226  void ChannelExtractor<AimsHSV,C>::getChannelX( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2227  {
2228  computeRuntimeMinMax<AimsHSV,C>( in );
2229  int valH;
2230  double valS, valV, valC, valX, valM, valout;
2231  double valin[3];
2232  long dimx = in.getSizeX(),
2233  dimy = in.getSizeY(),
2234  dimz = in.getSizeZ(),
2235  dimt = in.getSizeT();
2236  for( long t=0; t< dimt; ++t )
2237  for( long z=0; z< dimz; ++z )
2238  for( long y=0; y< dimy; ++y )
2239  for( long x=0; x< dimx; ++x )
2240  {
2241  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2242  valS = ((double) in( x, y, z, t ).saturation())/255;
2243  valV = ((double) in( x, y, z, t ).value())/255;
2244  valC = valV*valS;
2245  valX = valC*(1-abs((valH/60)%2-1));
2246  valM = valV-valC;
2247 
2248  if (valH<120 || valH>=240){
2249  if(60<=valH<300){
2250  valin[0] = valX;
2251  }else{
2252  valin[0] = valC;
2253  }
2254  }
2255 
2256  valin[0] += valM;
2257 
2258  if (valH<240){
2259  if(60<=valH<180){
2260  valin[1] = valC;
2261  }else{
2262  valin[1] = valX;
2263  }
2264  }
2265 
2266  valin[1] += valM;
2267 
2268  if (valH>=120){
2269  if(180<=valH<300){
2270  valin[2] = valC;
2271  }else{
2272  valin[2] = valX;
2273  }
2274  }
2275 
2276  valin[2] += valM;
2277 
2278  valout = 0.412453*valin[0] + 0.357580*valin[1] + 0.180423*valin[1];
2279  valout *= 100;
2280 
2281  out( x, y, z, t ) = rescale<double,C>( valout );
2282  }
2283  }
2284 
2285  template <typename C>
2286  void ChannelExtractor<AimsHSV,C>::getChannelY( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2287  {
2288  computeRuntimeMinMax<AimsHSV,C>( in );
2289  int valH;
2290  double valS, valV, valC, valX, valM, valout;
2291  double valin[3];
2292  long dimx = in.getSizeX(),
2293  dimy = in.getSizeY(),
2294  dimz = in.getSizeZ(),
2295  dimt = in.getSizeT();
2296  for( long t=0; t< dimt; ++t )
2297  for( long z=0; z< dimz; ++z )
2298  for( long y=0; y< dimy; ++y )
2299  for( long x=0; x< dimx; ++x )
2300  {
2301  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2302  valS = ((double) in( x, y, z, t ).saturation())/255;
2303  valV = ((double) in( x, y, z, t ).value())/255;
2304  valC = valV*valS;
2305  valX = valC*(1-abs((valH/60)%2-1));
2306  valM = valV-valC;
2307 
2308  if (valH<120 || valH>=240){
2309  if(60<=valH<300){
2310  valin[0] = valX;
2311  }else{
2312  valin[0] = valC;
2313  }
2314  }
2315 
2316  valin[0] += valM;
2317 
2318  if (valH<240){
2319  if(60<=valH<180){
2320  valin[1] = valC;
2321  }else{
2322  valin[1] = valX;
2323  }
2324  }
2325 
2326  valin[1] += valM;
2327 
2328  if (valH>=120){
2329  if(180<=valH<300){
2330  valin[2] = valC;
2331  }else{
2332  valin[2] = valX;
2333  }
2334  }
2335 
2336  valin[2] += valM;
2337 
2338  valout = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
2339  valout *= 100;
2340 
2341  out( x, y, z, t ) = rescale<double,C>( valout );
2342  }
2343  }
2344 
2345  template <typename C>
2346  void ChannelExtractor<AimsHSV,C>::getChannelZ( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2347  {
2348  computeRuntimeMinMax<AimsHSV,C>( in );
2349  int valH;
2350  double valS, valV, valC, valX, valM, valout;
2351  double valin[3];
2352  long dimx = in.getSizeX(),
2353  dimy = in.getSizeY(),
2354  dimz = in.getSizeZ(),
2355  dimt = in.getSizeT();
2356  for( long t=0; t< dimt; ++t )
2357  for( long z=0; z< dimz; ++z )
2358  for( long y=0; y< dimy; ++y )
2359  for( long x=0; x< dimx; ++x )
2360  {
2361  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2362  valS = ((double) in( x, y, z, t ).saturation())/255;
2363  valV = ((double) in( x, y, z, t ).value())/255;
2364  valC = valV*valS;
2365  valX = valC*(1-abs((valH/60)%2-1));
2366  valM = valV-valC;
2367 
2368  if (valH<120 || valH>=240){
2369  if(60<=valH<300){
2370  valin[0] = valX;
2371  }else{
2372  valin[0] = valC;
2373  }
2374  }
2375 
2376  valin[0] += valM;
2377 
2378  if (valH<240){
2379  if(60<=valH<180){
2380  valin[1] = valC;
2381  }else{
2382  valin[1] = valX;
2383  }
2384  }
2385 
2386  valin[1] += valM;
2387 
2388  if (valH>=120){
2389  if(180<=valH<300){
2390  valin[2] = valC;
2391  }else{
2392  valin[2] = valX;
2393  }
2394  }
2395 
2396  valin[2] += valM;
2397 
2398  valout = 0.019334*valin[0] + 0.119193*valin[1] + 0.950227*valin[2];
2399  valout *= 100;
2400 
2401  out( x, y, z, t ) = rescale<double,C>( valout );
2402  }
2403  }
2404 
2405  template <typename C>
2406  void ChannelExtractor<AimsHSV,C>::getChannelL( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2407  {
2408  computeRuntimeMinMax<AimsHSV,C>( in );
2409  int valH;
2410  double valS, valV, valC, valX, valY, valM, valout;
2411  double valin[3];
2412  long dimx = in.getSizeX(),
2413  dimy = in.getSizeY(),
2414  dimz = in.getSizeZ(),
2415  dimt = in.getSizeT();
2416  for( long t=0; t< dimt; ++t )
2417  for( long z=0; z< dimz; ++z )
2418  for( long y=0; y< dimy; ++y )
2419  for( long x=0; x< dimx; ++x )
2420  {
2421  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2422  valS = ((double) in( x, y, z, t ).saturation())/255;
2423  valV = ((double) in( x, y, z, t ).value())/255;
2424  valC = valV*valS;
2425  valX = valC*(1-abs((valH/60)%2-1));
2426  valM = valV-valC;
2427 
2428  if (valH<120 || valH>=240){
2429  if(60<=valH<300){
2430  valin[0] = valX;
2431  }else{
2432  valin[0] = valC;
2433  }
2434  }
2435 
2436  valin[0] += valM;
2437 
2438  if (valH<240){
2439  if(60<=valH<180){
2440  valin[1] = valC;
2441  }else{
2442  valin[1] = valX;
2443  }
2444  }
2445 
2446  valin[1] += valM;
2447 
2448  if (valH>=120){
2449  if(180<=valH<300){
2450  valin[2] = valC;
2451  }else{
2452  valin[2] = valX;
2453  }
2454  }
2455 
2456  valin[2] += valM;
2457 
2458  for( int n=0; n<3; ++n){
2459  if( valin[n] > 0.04045 )
2460  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
2461  else
2462  valin[n] = valin[n]/12.92;
2463  }
2464 
2465  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
2466 
2467  if( valY > 0.008856 ) {
2468  valout = std::pow(valY, 0.333333);
2469  } else {
2470  valout = 7.787*valY + ((double)16/116);
2471  }
2472 
2473  valout = 116*valout - 16;
2474 
2475  out( x, y, z, t ) = rescale<double,C>( valout );
2476  }
2477  }
2478 
2479  template <typename C>
2480  void ChannelExtractor<AimsHSV,C>::getChannela( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2481  {
2482  computeRuntimeMinMax<AimsHSV,C>( in );
2483  int valH;
2484  double valS, valV, valC, valX, valY, valM, valout;
2485  double valin[3];
2486  long dimx = in.getSizeX(),
2487  dimy = in.getSizeY(),
2488  dimz = in.getSizeZ(),
2489  dimt = in.getSizeT();
2490  for( long t=0; t< dimt; ++t )
2491  for( long z=0; z< dimz; ++z )
2492  for( long y=0; y< dimy; ++y )
2493  for( long x=0; x< dimx; ++x )
2494  {
2495  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2496  valS = ((double) in( x, y, z, t ).saturation())/255;
2497  valV = ((double) in( x, y, z, t ).value())/255;
2498  valC = valV*valS;
2499  valX = valC*(1-abs((valH/60)%2-1));
2500  valM = valV-valC;
2501 
2502  if (valH<120 || valH>=240){
2503  if(60<=valH<300){
2504  valin[0] = valX;
2505  }else{
2506  valin[0] = valC;
2507  }
2508  }
2509 
2510  valin[0] += valM;
2511 
2512  if (valH<240){
2513  if(60<=valH<180){
2514  valin[1] = valC;
2515  }else{
2516  valin[1] = valX;
2517  }
2518  }
2519 
2520  valin[1] += valM;
2521 
2522  if (valH>=120){
2523  if(180<=valH<300){
2524  valin[2] = valC;
2525  }else{
2526  valin[2] = valX;
2527  }
2528  }
2529 
2530  valin[2] += valM;
2531 
2532  for( int n=0; n<3; ++n){
2533  if( valin[n] > 0.04045 )
2534  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
2535  else
2536  valin[n] = valin[n]/12.92;
2537  }
2538 
2539  valX = (0.412453*valin[0] + 0.357580*valin[1] + 0.180423*valin[2])*((double)100/95.047);
2540  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
2541 
2542  valout = 0.0;
2543  if( valX > 0.008856 ) {
2544  valout += std::pow(valX, 0.333333);
2545  } else {
2546  valout += 7.787*valX + ((double)16/116);
2547  }
2548  if( valY > 0.008856 ) {
2549  valout -= std::pow(valY, 0.333333);
2550  } else {
2551  valout -= 7.787*valY + ((double)16/116);
2552  }
2553  valout *= 500;
2554 
2555  out( x, y, z, t ) = rescale<double,C>( valout );
2556  }
2557  }
2558 
2559  template <typename C>
2560  void ChannelExtractor<AimsHSV,C>::getChannelb( carto::VolumeRef<AimsHSV> in, carto::VolumeRef<C> out )
2561  {
2562  computeRuntimeMinMax<AimsHSV,C>( in );
2563  int valH;
2564  double valS, valV, valC, valX, valY, valZ, valM, valout;
2565  double valin[3];
2566  long dimx = in.getSizeX(),
2567  dimy = in.getSizeY(),
2568  dimz = in.getSizeZ(),
2569  dimt = in.getSizeT();
2570  for( long t=0; t< dimt; ++t )
2571  for( long z=0; z< dimz; ++z )
2572  for( long y=0; y< dimy; ++y )
2573  for( long x=0; x< dimx; ++x )
2574  {
2575  valH = (int) (((double) in( x, y, z, t ).hue())/255)*360;
2576  valS = ((double) in( x, y, z, t ).saturation())/255;
2577  valV = ((double) in( x, y, z, t ).value())/255;
2578  valC = valV*valS;
2579  valX = valC*(1-abs((valH/60)%2-1));
2580  valM = valV-valC;
2581 
2582  if (valH<120 || valH>=240){
2583  if(60<=valH<300){
2584  valin[0] = valX;
2585  }else{
2586  valin[0] = valC;
2587  }
2588  }
2589 
2590  valin[0] += valM;
2591 
2592  if (valH<240){
2593  if(60<=valH<180){
2594  valin[1] = valC;
2595  }else{
2596  valin[1] = valX;
2597  }
2598  }
2599 
2600  valin[1] += valM;
2601 
2602  if (valH>=120){
2603  if(180<=valH<300){
2604  valin[2] = valC;
2605  }else{
2606  valin[2] = valX;
2607  }
2608  }
2609 
2610  valin[2] += valM;
2611 
2612  for( int n=0; n<3; ++n){
2613  if( valin[n] > 0.04045 )
2614  valin[n] = std::pow((valin[n] + 0.055)/(1 + 0.055), 2.4);
2615  else
2616  valin[n] = valin[n]/12.92;
2617  }
2618 
2619  valY = 0.212671*valin[0] + 0.715160*valin[1] + 0.072169*valin[2];
2620  valZ = (0.019334*valin[0] + 0.119193*valin[1] + 0.950227*valin[2])*((double)100/108.883);
2621 
2622  valout = 0.0;
2623  if( valY > 0.008856 ) {
2624  valout += std::pow(valY, 0.333333);
2625  } else {
2626  valout += 7.787*valY + ((double)16/116);
2627  }
2628  if( valZ > 0.008856 ) {
2629  valout -= std::pow(valZ, 0.333333);
2630  } else {
2631  valout -= 7.787*valZ + ((double)16/116);
2632  }
2633  valout *= 200;
2634 
2635  out( x, y, z, t ) = rescale<double,C>( valout );
2636  }
2637  }
2638 
2639 } // namespace bio
2640 
2641 #endif // BRAINRAT_UTILITY_CHANNELEXTRACTOR_H
carto::VolumeRef< C > getChannelRGBNorm(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelYl(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelS(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelb(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > allocateVolume(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelCb(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelV(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelCr(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelH(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelB(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelR(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelZ(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelY(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelL(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelX(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelG(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannela(carto::VolumeRef< AimsHSV > in)
carto::VolumeRef< C > getChannelV(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelX(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > allocateVolume(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelL(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelYl(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannela(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelH(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelR(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelRGBNorm(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelS(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelB(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelb(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelG(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelA(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelCb(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelCr(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelZ(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannelY(carto::VolumeRef< AimsRGBA > in)
carto::VolumeRef< C > getChannela(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelR(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelS(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > allocateVolume(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelH(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelZ(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelL(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelB(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelX(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelCb(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelV(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelb(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelYl(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelRGBNorm(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelG(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelY(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelCr(carto::VolumeRef< AimsRGB > in)
carto::VolumeRef< C > getChannelb(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelB(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelL(carto::VolumeRef< T > in)
void getChannelb(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelY(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelZ(carto::VolumeRef< T >, carto::VolumeRef< C >)
carto::VolumeRef< C > getChannela(carto::VolumeRef< T > in)
void getChannela(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelH(carto::VolumeRef< T >, carto::VolumeRef< C >)
carto::VolumeRef< C > getChannelCr(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelV(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelZ(carto::VolumeRef< T > in)
void getChannelB(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelV(carto::VolumeRef< T >, carto::VolumeRef< C >)
carto::VolumeRef< C > getChannelYl(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelR(carto::VolumeRef< T > in)
void getChannelCb(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelRGBNorm(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelL(carto::VolumeRef< T >, carto::VolumeRef< C >)
carto::VolumeRef< C > getChannelCb(carto::VolumeRef< T > in)
void getChannelYl(carto::VolumeRef< T >, carto::VolumeRef< C >)
carto::VolumeRef< C > getChannelRGBNorm(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelX(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelY(carto::VolumeRef< T > in)
void getChannelS(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelR(carto::VolumeRef< T >, carto::VolumeRef< C >)
carto::VolumeRef< C > getChannelG(carto::VolumeRef< T > in)
void getChannelG(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelX(carto::VolumeRef< T >, carto::VolumeRef< C >)
void getChannelCr(carto::VolumeRef< T >, carto::VolumeRef< C >)
carto::VolumeRef< C > getChannelS(carto::VolumeRef< T > in)
carto::VolumeRef< C > getChannelH(carto::VolumeRef< T > in)
carto::VolumeRef< C > allocateVolume(carto::VolumeRef< T > in)
virtual const char * what() const
A Rescaler allows one to apply a linear transformation to a value of any type.
void setOutputMax(double val)
void setInputDynMinMax(bool val=true)
void computeInputDynMax(carto::VolumeRef< T > in, int ch=0)
void computeRuntimeMinMax(carto::VolumeRef< T > in, int ch=0)
void setOutputMin(double val)
virtual ~Rescaler()
void computeInputTypeMin()
void computeInputDynMin(carto::VolumeRef< T > in, int ch=0)
void setInputMax(double val)
void setInputDynMinMax(carto::VolumeRef< T > in)
void setRescale(bool val=true)
void computeInputTypeMax()
void setInputMin(double val)
float min(float x, float y)
float max(float x, float y)
ImageProcessors<AimsRGB, double> p(data, mask, "rgbm", options, ImageProcessorMode::Init); ImageProce...
Definition: classes.h:25