PCL
AbstractImage.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.1.19
6 // ----------------------------------------------------------------------------
7 // pcl/AbstractImage.h - Released 2019-11-07T10:59:34Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2019 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (http://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_AbstractImage_h
53 #define __PCL_AbstractImage_h
54 
56 
57 #include <pcl/Defs.h>
58 
59 #include <pcl/Array.h>
60 #include <pcl/ImageColor.h>
61 #include <pcl/ImageGeometry.h>
62 #include <pcl/ImageSelections.h>
63 #include <pcl/Mutex.h>
64 #include <pcl/ParallelProcess.h>
65 #include <pcl/ReferenceArray.h>
66 #include <pcl/StatusMonitor.h>
67 #include <pcl/Thread.h>
68 
69 #ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
70 namespace pi
71 {
72 class SharedImage;
73 }
74 #endif
75 
76 namespace pcl
77 {
78 
79 // ----------------------------------------------------------------------------
80 
81 #define m_width m_geometry->width
82 #define m_height m_geometry->height
83 #define m_numberOfChannels m_geometry->numberOfChannels
84 
85 #define m_colorSpace m_color->colorSpace
86 #define m_RGBWS m_color->RGBWS
87 
88 // ----------------------------------------------------------------------------
89 
118 class PCL_CLASS AbstractImage : public ImageGeometry,
119  public ImageColor,
120  public ParallelProcess
121 {
122 public:
123 
128 
134  typedef ImageColor::color_space color_space;
135 
139  virtual ~AbstractImage()
140  {
141  }
142 
148  {
149  return ColorSpace::NumberOfNominalChannels( m_colorSpace );
150  }
151 
157  {
158  return NumberOfPixels() * NumberOfNominalChannels();
159  }
160 
167  bool HasAlphaChannels() const
168  {
169  PCL_PRECONDITION( NumberOfChannels() != 0 )
170  return NumberOfChannels() > NumberOfNominalChannels();
171  }
172 
177  {
178  PCL_PRECONDITION( NumberOfChannels() != 0 )
179  return NumberOfChannels() - NumberOfNominalChannels();
180  }
181 
188  {
189  return NumberOfPixels() * NumberOfAlphaChannels();
190  }
191 
192  // -------------------------------------------------------------------------
193 
200  void SelectChannel( int c ) const
201  {
202  PCL_PRECONDITION( 0 <= c && c < m_numberOfChannels )
203  m_selected.channel = m_selected.lastChannel = c;
204  ValidateChannelRange();
205  }
206 
215  int SelectedChannel() const
216  {
217  return m_selected.channel;
218  }
219 
227  void SelectChannelRange( int c0, int c1 ) const
228  {
229  PCL_PRECONDITION( 0 <= c0 && c0 < m_numberOfChannels )
230  PCL_PRECONDITION( 0 <= c1 && c1 < m_numberOfChannels )
231  m_selected.channel = c0;
232  m_selected.lastChannel = c1;
233  ValidateChannelRange();
234  }
235 
241  {
242  m_selected.channel = 0;
243  m_selected.lastChannel = NumberOfNominalChannels()-1;
244  ValidateChannelRange();
245  }
246 
254  void SelectAlphaChannels() const
255  {
256  m_selected.channel = NumberOfNominalChannels();
257  m_selected.lastChannel = m_numberOfChannels-1;
258  ValidateChannelRange();
259  }
260 
265  void ResetChannelRange() const
266  {
267  m_selected.channel = 0;
268  m_selected.lastChannel = pcl::Max( 0, m_numberOfChannels-1 );
269  }
270 
275  {
276  return 1 + m_selected.lastChannel - m_selected.channel;
277  }
278 
283  {
284  return m_selected.channel;
285  }
286 
291  {
292  return m_selected.lastChannel;
293  }
294 
302  void GetSelectedChannelRange( int& c0, int& c1 ) const
303  {
304  c0 = m_selected.channel;
305  c1 = m_selected.lastChannel;
306  }
307 
314  void SelectPoint( int x, int y ) const
315  {
316  m_selected.point.MoveTo( x, y );
317  }
318 
322  void SelectPoint( const Point& p ) const
323  {
324  m_selected.point = p;
325  }
326 
330  void ResetPoint() const
331  {
332  m_selected.point = 0;
333  }
334 
338  const Point& SelectedPoint() const
339  {
340  return m_selected.point;
341  }
342 
356  void SelectRectangle( int x0, int y0, int x1, int y1 ) const
357  {
358  m_selected.rectangle.Set( x0, y0, x1, y1 );
359  Clip( m_selected.rectangle );
360  }
361 
370  void SelectRectangle( const Point& p0, const Point& p1 ) const
371  {
372  SelectRectangle( p0.x, p0.y, p1.x, p1.y );
373  }
374 
379  void SelectRectangle( const Rect& r ) const
380  {
381  SelectRectangle( r.x0, r.y0, r.x1, r.y1 );
382  }
383 
387  void ResetSelection() const
388  {
389  m_selected.rectangle.Set( 0, 0, m_width, m_height );
390  }
391 
395  bool IsEmptySelection() const
396  {
397  return m_selected.rectangle.IsPointOrLine();
398  }
399 
404  bool IsFullSelection() const
405  {
406  return m_selected.rectangle.x0 <= 0 &&
407  m_selected.rectangle.y0 <= 0 &&
408  m_selected.rectangle.x1 >= m_width &&
409  m_selected.rectangle.y1 >= m_height;
410  }
411 
415  const Rect& SelectedRectangle() const
416  {
417  return m_selected.rectangle;
418  }
419 
428  bool IsCompletelySelected() const
429  {
430  return m_selected.channel == 0 &&
431  m_selected.lastChannel >= m_numberOfChannels-1 &&
432  m_selected.rectangle.x0 <= 0 &&
433  m_selected.rectangle.y0 <= 0 &&
434  m_selected.rectangle.x1 >= m_width &&
435  m_selected.rectangle.y1 >= m_height;
436  }
437 
443  {
444  return size_type( m_selected.rectangle.Width() ) * size_type( m_selected.rectangle.Height() );
445  // ### NB: Rect::Area() cannot be used here because it performs a
446  // *signed* multiplication of two 32-bit signed integers.
447  //return m_selected.rectangle.Area();
448  }
449 
456  {
457  return NumberOfSelectedPixels()*size_type( NumberOfSelectedChannels() );
458  }
459 
480  {
481  return m_selected.clipped;
482  }
483 
489  void EnableRangeClipping( bool enable = true ) const
490  {
491  m_selected.clipped = enable;
492  }
493 
499  void DisableRangeClipping( bool disable = true ) const
500  {
501  m_selected.clipped = !disable;
502  }
503 
509  double RangeClipLow() const
510  {
511  return m_selected.clipLow;
512  }
513 
519  double RangeClipHigh() const
520  {
521  return m_selected.clipHigh;
522  }
523 
529  void SetRangeClipLow( double clipLow ) const
530  {
531  m_selected.clipLow = clipLow;
532  if ( m_selected.clipHigh < m_selected.clipLow )
533  pcl::Swap( m_selected.clipLow, m_selected.clipHigh );
534  }
535 
541  void SetRangeClipHigh( double clipHigh ) const
542  {
543  m_selected.clipHigh = clipHigh;
544  if ( m_selected.clipHigh < m_selected.clipLow )
545  pcl::Swap( m_selected.clipLow, m_selected.clipHigh );
546  }
547 
554  void SetRangeClipping( double clipLow, double clipHigh ) const
555  {
556  if ( clipHigh < clipLow )
557  pcl::Swap( clipLow, clipHigh );
558  m_selected.clipLow = clipLow;
559  m_selected.clipHigh = clipHigh;
560  m_selected.clipped = true;
561  }
562 
570  void ResetRangeClipping() const
571  {
572  m_selected.clipLow = 0;
573  m_selected.clipHigh = 1;
574  m_selected.clipped = false;
575  }
576 
595  void ResetSelections() const
596  {
597  ResetChannelRange();
598  ResetPoint();
599  ResetSelection();
600  ResetRangeClipping();
601  }
602 
607  {
608  return m_selected;
609  }
610 
615  void PushSelections() const
616  {
617  m_savedSelections.Append( m_selected );
618  }
619 
628  void PopSelections() const
629  {
630  if ( CanPopSelections() )
631  {
632  selection_stack::iterator i = m_savedSelections.ReverseBegin();
633  m_selected = *i;
634  m_savedSelections.Remove( i );
635  }
636  }
637 
643  bool CanPopSelections() const
644  {
645  return !m_savedSelections.IsEmpty();
646  }
647 
660  bool ParseRect( Rect& rect ) const
661  {
662  if ( !rect.IsRect() )
663  {
664  rect = m_selected.rectangle;
665  if ( !rect.IsRect() )
666  return false;
667  }
668  if ( !Clip( rect ) )
669  return false;
670  return true;
671  }
672 
683  bool ParseChannel( int& channel ) const
684  {
685  if ( channel < 0 )
686  {
687  channel = m_selected.channel;
688  if ( channel < 0 )
689  return false;
690  }
691  if ( channel >= m_numberOfChannels )
692  return false;
693 
694  return true;
695  }
696 
721  bool ParseSelection( Rect& rect, int& firstChannel, int& lastChannel ) const
722  {
723  if ( !ParseRect( rect ) || !ParseChannel( firstChannel ) )
724  return false;
725 
726  if ( lastChannel < 0 )
727  {
728  lastChannel = m_selected.lastChannel;
729  if ( lastChannel < 0 )
730  return false;
731  }
732  if ( lastChannel >= m_numberOfChannels )
733  return false;
734 
735  if ( lastChannel < firstChannel )
736  pcl::Swap( firstChannel, lastChannel );
737 
738  return true;
739  }
740 
758  bool ParseSelection( Rect& rect, int& channel ) const
759  {
760  return ParseRect( rect ) && ParseChannel( channel );
761  }
762 
763  // -------------------------------------------------------------------------
764 
770  {
771  return m_status;
772  }
773 
779  {
780  return m_status.Callback();
781  }
782 
789  {
790  return StatusCallback();
791  }
792 
797  void SetStatusCallback( pcl::StatusCallback* callback ) const
798  {
799  m_status.SetCallback( callback );
800  }
801 
828  int NumberOfThreads( size_type count, int maxProcessors = 0, size_type overheadLimit = 16u ) const
829  {
830  return m_parallel ? pcl::Min( (maxProcessors > 0) ? maxProcessors : m_maxProcessors,
831  Thread::NumberOfThreads( count, overheadLimit ) ) : 1;
832  }
833 
866  int NumberOfThreadsForRows( int rowCount = 0, int rowWidth = 0, int maxProcessors = 0, size_type overheadLimitPx = 1024u ) const
867  {
868  return NumberOfThreads( (rowCount > 0) ? rowCount : Height(),
869  maxProcessors,
870  pcl::Max( size_type( 1 ), size_type( overheadLimitPx/((rowWidth > 0) ? rowWidth : Width()) ) ) );
871  }
872 
913  Array<size_type> OptimalThreadRows( int rowCount = 0, int rowWidth = 0, int maxProcessors = 0, size_type overheadLimitPx = 1024u ) const
914  {
915  return Thread::OptimalThreadLoads( (rowCount > 0) ? rowCount : Height(),
916  pcl::Max( size_type( 1 ), size_type( overheadLimitPx/((rowWidth > 0) ? rowWidth : Width()) ) ),
917  m_parallel ? ((maxProcessors > 0) ? maxProcessors : m_maxProcessors) : 1 );
918  }
919 
920  // -------------------------------------------------------------------------
921 
933  struct ThreadData
934  {
936  mutable Mutex mutex;
937  mutable size_type count = 0;
938  size_type total = 0;
939  size_type numThreads = 0;
940 
944  ThreadData() = default;
945 
955  ThreadData( const AbstractImage& image, size_type N ) :
956  status( image.Status() ),
957  total( N )
958  {
959  }
960 
969  ThreadData( const StatusMonitor& a_status, size_type N ) :
970  status( a_status ),
971  total( N )
972  {
973  }
974  };
975 
1040  template <class thread>
1041  static void RunThreads( ReferenceArray<thread>& threads, ThreadData& data, bool useAffinity = true )
1042  {
1043  if ( threads.IsEmpty() )
1044  return;
1045 
1046  data.numThreads = threads.Length();
1047  if ( data.numThreads == 1 )
1048  {
1049  try
1050  {
1051  threads[0].Run();
1052  return;
1053  }
1054  catch ( ... )
1055  {
1056  threads.Destroy();
1057  throw;
1058  }
1059  }
1060 
1061  if ( useAffinity )
1062  if ( !Thread::IsRootThread() )
1063  useAffinity = false;
1064 
1065  {
1066  int n = 0;
1067  for ( thread& t : threads )
1068  t.Start( ThreadPriority::DefaultMax, useAffinity ? n++ : -1 );
1069  }
1070 
1071  uint32 waitTime = StatusMonitor::RefreshRate() >> 1;
1072  waitTime += waitTime >> 2; // waitTime = 0.625 * StatusMonitor::RefreshRate()
1073 
1074  for ( size_type lastCount = 0; ; )
1075  {
1076  for ( typename ReferenceArray<thread>::iterator i = threads.Begin(); ; )
1077  {
1078  if ( !i->Wait( waitTime ) )
1079  break;
1080 
1081  if ( ++i == threads.End() )
1082  {
1083  if ( data.total > 0 )
1084  data.status += data.total - lastCount;
1085  return;
1086  }
1087  }
1088 
1089  if ( data.mutex.TryLock() )
1090  {
1091  try
1092  {
1093  if ( data.total > 0 )
1094  {
1095  data.status += data.count - lastCount;
1096  lastCount = data.count;
1097  }
1098  else
1099  ++data.status;
1100 
1101  data.mutex.Unlock();
1102  }
1103  catch ( ... )
1104  {
1105  data.mutex.Unlock();
1106  for ( thread& t : threads )
1107  t.Abort();
1108  for ( thread& t : threads )
1109  t.Wait();
1110  threads.Destroy();
1111  throw ProcessAborted();
1112  }
1113  }
1114  }
1115  }
1116 
1117 protected:
1118 
1119  mutable ImageSelections m_selected;
1120  mutable selection_stack m_savedSelections;
1121  mutable StatusMonitor m_status;
1122 
1123  AbstractImage() = default;
1124 
1125  AbstractImage( const AbstractImage& ) = default;
1126 
1127  AbstractImage& operator =( const AbstractImage& ) = default;
1128 
1129  void Swap( AbstractImage& image )
1130  {
1131  ImageGeometry::Swap( image );
1132  ImageColor::Swap( image );
1133  ParallelProcess::Swap( image );
1134  pcl::Swap( m_selected, image.m_selected );
1135  pcl::Swap( m_savedSelections, image.m_savedSelections );
1136  pcl::Swap( m_status, image.m_status );
1137  }
1138 
1139  void ValidateChannelRange() const
1140  {
1141  if ( m_numberOfChannels > 0 )
1142  {
1143  if ( m_selected.channel < 0 )
1144  m_selected.channel = 0;
1145  else if ( m_selected.channel >= m_numberOfChannels )
1146  m_selected.channel = m_numberOfChannels-1;
1147 
1148  if ( m_selected.lastChannel < 0 )
1149  m_selected.lastChannel = 0;
1150  else if ( m_selected.lastChannel >= m_numberOfChannels )
1151  m_selected.lastChannel = m_numberOfChannels-1;
1152 
1153  if ( m_selected.lastChannel < m_selected.channel )
1154  pcl::Swap( m_selected.channel, m_selected.lastChannel );
1155  }
1156  else
1157  {
1158  m_selected.channel = m_selected.lastChannel = 0;
1159  }
1160  }
1161 
1162 #ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
1163  friend class pi::SharedImage;
1164 #endif
1165 };
1166 
1167 // ----------------------------------------------------------------------------
1168 
1169 #undef m_width
1170 #undef m_height
1171 #undef m_numberOfChannels
1172 #undef m_colorSpace
1173 #undef m_RGBWS
1174 
1175 // ----------------------------------------------------------------------------
1176 
1195 #define INIT_THREAD_MONITOR() \
1196  size_type ___n___ = 0, ___n1___ = 0;
1197 
1283 #define UPDATE_THREAD_MONITOR( N ) \
1284  if ( ++___n1___ == (N) ) \
1285  { \
1286  if ( this->m_data.numThreads > 1 ) \
1287  { \
1288  if ( this->TryIsAborted() ) \
1289  return; \
1290  ___n___ += (N); \
1291  if ( this->m_data.total > 0 ) \
1292  if ( this->m_data.mutex.TryLock() ) \
1293  { \
1294  this->m_data.count += ___n___; \
1295  this->m_data.mutex.Unlock(); \
1296  ___n___ = 0; \
1297  } \
1298  } \
1299  else \
1300  { \
1301  if ( this->m_data.total > 0 ) \
1302  this->m_data.status += (N); \
1303  else \
1304  ++this->m_data.status; \
1305  } \
1306  ___n1___ = 0; \
1307  }
1308 
1364 #define UPDATE_THREAD_MONITOR_CHUNK( N, chunkSize ) \
1365  if ( (___n1___ += (chunkSize)) == (N) ) \
1366  { \
1367  if ( this->m_data.numThreads > 1 ) \
1368  { \
1369  if ( this->TryIsAborted() ) \
1370  return; \
1371  ___n___ += (N); \
1372  if ( this->m_data.total > 0 ) \
1373  if ( this->m_data.mutex.TryLock() ) \
1374  { \
1375  this->m_data.count += ___n___; \
1376  this->m_data.mutex.Unlock(); \
1377  ___n___ = 0; \
1378  } \
1379  } \
1380  else \
1381  { \
1382  if ( this->m_data.total > 0 ) \
1383  this->m_data.status += (N); \
1384  else \
1385  ++this->m_data.status; \
1386  } \
1387  ___n1___ = 0; \
1388  }
1389 
1390 // ----------------------------------------------------------------------------
1391 
1392 } // pcl
1393 
1394 #endif // __PCL_AbstractImage_h
1395 
1396 // ----------------------------------------------------------------------------
1397 // EOF pcl/AbstractImage.h - Released 2019-11-07T10:59:34Z
bool ParseSelection(Rect &rect, int &channel) const
int NumberOfNominalChannels() const
void GetSelectedChannelRange(int &c0, int &c1) const
An exception class signaling the interruption of a process.
bool CanPopSelections() const
void SelectPoint(const Point &p) const
void ResetSelection() const
size_type count
current monitoring count.
void Swap(GenericPoint< T > &p1, GenericPoint< T > &p2)
Definition: Point.h:1402
void ResetPoint() const
Dynamic array of pointers to objects providing direct iteration and element access by reference...
size_type NumberOfSelectedSamples() const
Adaptive mutual exclusion lock variable.
Definition: Mutex.h:208
void ResetChannelRange() const
bool ParseSelection(Rect &rect, int &firstChannel, int &lastChannel) const
PCL root namespace.
Definition: AbstractImage.h:76
pcl::StatusCallback * GetStatusCallback() const
int channel
First selected channel.
Array< ImageSelections > selection_stack
Mutable ReferenceArray iterator.
static void RunThreads(ReferenceArray< thread > &threads, ThreadData &data, bool useAffinity=true)
void SelectPoint(int x, int y) const
void SelectChannelRange(int c0, int c1) const
const Rect & SelectedRectangle() const
void SetRangeClipLow(double clipLow) const
size_type NumberOfSelectedPixels() const
int NumberOfAlphaChannels() const
StatusMonitor status
Status monitoring object.
Implements color space properties of images.
Definition: ImageColor.h:96
void SelectRectangle(const Point &p0, const Point &p1) const
bool IsCompletelySelected() const
int LastSelectedChannel() const
size_t size_type
Definition: Defs.h:543
size_type NumberOfAlphaSamples() const
int NumberOfThreadsForRows(int rowCount=0, int rowWidth=0, int maxProcessors=0, size_type overheadLimitPx=1024u) const
void SelectRectangle(int x0, int y0, int x1, int y1) const
Mutex mutex
Mutual exclusion for synchronized thread access.
ThreadData(const StatusMonitor &a_status, size_type N)
constexpr const T & Max(const T &a, const T &b)
Definition: Utility.h:119
void PushSelections() const
int NumberOfThreads(size_type count, int maxProcessors=0, size_type overheadLimit=16u) const
bool HasAlphaChannels() const
virtual ~AbstractImage()
double RangeClipLow() const
constexpr const T & Min(const T &a, const T &b)
Definition: Utility.h:90
pcl::StatusCallback * StatusCallback() const
bool TryLock()
Definition: Mutex.h:362
void SelectAlphaChannels() const
Base class of all two-dimensional images in PCL.
int SelectedChannel() const
An asynchronous status monitoring system.
A structure used to store rectangular image selections, channel ranges, anchor points, and clipping ranges.
bool ParseChannel(int &channel) const
bool IsRangeClippingEnabled() const
void ResetSelections() const
size_type numThreads
Number of concurrent threads being executed (set by RunThreads()).
bool IsEmptySelection() const
Array< size_type > OptimalThreadRows(int rowCount=0, int rowWidth=0, int maxProcessors=0, size_type overheadLimitPx=1024u) const
size_type NumberOfNominalSamples() const
Provides status monitoring callback functions.
Definition: StatusMonitor.h:97
ImageColor::color_space color_space
void DisableRangeClipping(bool disable=true) const
void EnableRangeClipping(bool enable=true) const
bool ParseRect(Rect &rect) const
32-bit integer point on the plane.
size_type Length() const
int NumberOfSelectedChannels() const
StatusMonitor & Status() const
int lastChannel
Last selected channel.
void PopSelections() const
void SelectRectangle(const Rect &r) const
void SelectNominalChannels() const
void SetStatusCallback(pcl::StatusCallback *callback) const
int NumberOfNominalChannels(int colorSpace)
Definition: ColorSpace.h:102
size_type total
Total monitoring count.
double RangeClipHigh() const
void SelectChannel(int c) const
const Point & SelectedPoint() const
bool IsEmpty() const
ImageSelections & Selections() const
Implements geometric properties of two-dimensional images.
Definition: ImageGeometry.h:83
unsigned int uint32
Definition: Defs.h:600
32-bit integer rectangle on the plane.
void ResetRangeClipping() const
void SetRangeClipHigh(double clipHigh) const
Thread synchronization data for status monitoring of parallel image processing tasks.
void Unlock()
Definition: Mutex.h:310
void SetRangeClipping(double clipLow, double clipHigh) const
int FirstSelectedChannel() const
ThreadData(const AbstractImage &image, size_type N)
A process using multiple concurrent execution threads.
void Destroy(iterator i, size_type n=1)
bool IsFullSelection() const