PCL
SeparableConvolution.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/SeparableConvolution.h - Released 2024-06-18T15:48:54Z
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-2024 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 (https://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_SeparableConvolution_h
53 #define __PCL_SeparableConvolution_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/AutoPointer.h>
62 #include <pcl/ParallelProcess.h>
63 #include <pcl/SeparableFilter.h>
64 
65 #define __PCL_SEPARABLE_CONVOLUTION_TINY_WEIGHT 1.0e-20
66 
67 namespace pcl
68 {
69 
70 // ----------------------------------------------------------------------------
71 
83  public ParallelProcess
84 {
85 public:
86 
91 
96 
103  SeparableConvolution() = default;
104 
115  {
116  SetFilter( filter );
117  }
118 
124  , ParallelProcess( x )
125  , m_weight( x.m_weight )
126  , m_highPass( x.m_highPass )
127  , m_rawHighPass( x.m_rawHighPass )
128  , m_rescaleHighPass( x.m_rescaleHighPass )
129  , m_convolveRows( x.m_convolveRows )
130  , m_convolveCols( x.m_convolveCols )
131  {
132  if ( !x.m_filter.IsNull() )
133  m_filter = x.m_filter->Clone();
134  }
135 
140 
145  {
146  }
147 
152  {
153  if ( &x != this )
154  {
155  (void)InterlacedTransformation::operator =( x );
156  (void)ParallelProcess::operator =( x );
157  if ( x.m_filter.IsNull() )
158  m_filter.Destroy();
159  else
160  m_filter = x.m_filter->Clone();
161  m_weight = x.m_weight;
162  m_highPass = x.m_highPass;
163  m_rawHighPass = x.m_rawHighPass;
164  m_rescaleHighPass = x.m_rescaleHighPass;
165  m_convolveRows = x.m_convolveRows;
166  m_convolveCols = x.m_convolveCols;
167  }
168  return *this;
169  }
170 
174  SeparableConvolution& operator =( SeparableConvolution&& ) = default;
175 
183  const SeparableFilter& Filter() const
184  {
185  PCL_PRECONDITION( !m_filter.IsNull() )
186  return *m_filter;
187  }
188 
198  coefficient_vector Filter( int phase ) const
199  {
200  PCL_PRECONDITION( !m_filter.IsNull() )
201  return m_filter->Filter( phase );
202  }
203 
207  void SetFilter( const SeparableFilter& filter )
208  {
209  m_filter = filter.Clone();
210  CacheFilterProperties();
211  }
212 
222  double FilterWeight() const
223  {
224  return m_weight;
225  }
226 
238  bool IsHighPassFilter() const
239  {
240  return m_highPass;
241  }
242 
262  {
263  return m_rescaleHighPass;
264  }
265 
271  void EnableHighPassRescaling( bool enable = true )
272  {
273  m_rescaleHighPass = enable;
274  }
275 
281  void DisableHighPassRescaling( bool disable = true )
282  {
283  EnableHighPassRescaling( !disable );
284  }
285 
296  bool IsRawHighPassEnabled() const
297  {
298  return m_rawHighPass;
299  }
300 
305  void EnableRawHighPass( bool enable = true )
306  {
307  m_rawHighPass = enable;
308  }
309 
314  void DisableRawHighPass( bool disable = true )
315  {
316  EnableRawHighPass( !disable );
317  }
318 
323  {
324  return m_convolveRows;
325  }
326 
330  void EnableRowConvolution( bool enable = true )
331  {
332  m_convolveRows = enable;
333  }
334 
341  void DisableRowConvolution( bool disable = true )
342  {
343  EnableRowConvolution( !disable );
344  }
345 
350  {
351  return m_convolveCols;
352  }
353 
357  void EnableColumnConvolution( bool enable = true )
358  {
359  m_convolveCols = enable;
360  }
361 
368  void DisableColumnConvolution( bool disable = true )
369  {
370  EnableColumnConvolution( !disable );
371  }
372 
379  {
380  PCL_PRECONDITION( !m_filter.IsNull() )
381  return m_filter->Size() + (m_filter->Size() - 1)*(InterlacingDistance() - 1);
382  }
383 
396  static constexpr int FasterThanNonseparableFilterSize( int numThreads )
397  {
398 #ifdef __PCL_COMPATIBILITY
399 
400  // No vectorization
401 
402  if ( numThreads >= 32 )
403  return 15;
404  if ( numThreads >= 16 )
405  return 11;
406  if ( numThreads >= 8 )
407  return 9;
408  if ( numThreads >= 4 )
409  return 7;
410  return 5;
411 
412 #else
413 
414  // Vectorization with SSE4.2 / AVX2 and FMA instructions
415 
416  if ( numThreads >= 32 )
417  return 29;
418  if ( numThreads >= 28 )
419  return 25;
420  if ( numThreads >= 24 )
421  return 21;
422  if ( numThreads >= 16 )
423  return 19;
424  if ( numThreads >= 8 )
425  return 13;
426  if ( numThreads >= 4 )
427  return 11;
428  if ( numThreads >= 2 )
429  return 9;
430  return 7;
431 
432 #endif
433  }
434 
435 protected:
436 
437  /*
438  * The response function for convolution is a separable filter.
439  */
441 
442  /*
443  * Cached filter properties.
444  */
445  double m_weight = 0; // filter weight for low-pass normalization
446  bool m_highPass = false; // true iff this is a high-pass filter
447 
448  /*
449  * User-selectable options.
450  */
451  bool m_rawHighPass = false; // neither truncate nor normalize out-of-range values
452  bool m_rescaleHighPass = false; // truncate out-of-range values instead of normalize
453  bool m_convolveRows = true; // perform one-dimensional convolution of pixel rows
454  bool m_convolveCols = true; // perform one-dimensional convolution of pixel columns
455 
456  /*
457  * In-place 2-D separable convolution algorithm.
458  */
459  void Apply( pcl::Image& ) const override;
460  void Apply( pcl::DImage& ) const override;
461  void Apply( pcl::UInt8Image& ) const override;
462  void Apply( pcl::UInt16Image& ) const override;
463  void Apply( pcl::UInt32Image& ) const override;
464 
465 private:
466 
467  void CacheFilterProperties()
468  {
469  PCL_PRECONDITION( !m_filter.IsNull() )
470  PCL_PRECONDITION( !m_filter->IsEmpty() )
471  ValidateFilter();
472  m_highPass = m_filter->IsHighPassFilter();
473  m_weight = m_filter->Weight();
474  if ( pcl::Abs( m_weight ) < __PCL_SEPARABLE_CONVOLUTION_TINY_WEIGHT )
475  m_weight = 1;
476  }
477 
478  void ValidateFilter() const;
479 };
480 
481 // ----------------------------------------------------------------------------
482 
483 } // pcl
484 
485 #endif // __PCL_SeparableConvolution_h
486 
487 // ----------------------------------------------------------------------------
488 // EOF pcl/SeparableConvolution.h - Released 2024-06-18T15:48:54Z
A smart pointer with exclusive object ownership and optional automatic object destruction.
Definition: AutoPointer.h:241
bool IsNull() const
Definition: AutoPointer.h:453
Implements a generic, two-dimensional, shared or local image.
Definition: Image.h:278
Interlaced image transformation in the spatial domain.
A process using multiple concurrent execution threads.
Discrete two-dimensional separable convolution in the spatial domain.
void Apply(pcl::Image &) const override
SeparableConvolution(SeparableConvolution &&)=default
void DisableHighPassRescaling(bool disable=true)
const SeparableFilter & Filter() const
SeparableConvolution(const SeparableConvolution &x)
void Apply(pcl::UInt8Image &) const override
void Apply(pcl::UInt32Image &) const override
void EnableHighPassRescaling(bool enable=true)
void DisableColumnConvolution(bool disable=true)
void DisableRawHighPass(bool disable=true)
void EnableRowConvolution(bool enable=true)
void EnableColumnConvolution(bool enable=true)
coefficient_vector Filter(int phase) const
void DisableRowConvolution(bool disable=true)
SeparableConvolution(const SeparableFilter &filter)
SeparableFilter::coefficient coefficient
void EnableRawHighPass(bool enable=true)
void Apply(pcl::UInt16Image &) const override
void SetFilter(const SeparableFilter &filter)
void Apply(pcl::DImage &) const override
Separable filter in two dimensions.
virtual SeparableFilter * Clone() const
GenericVector< coefficient > coefficient_vector
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:429
static constexpr int FasterThanNonseparableFilterSize(int numThreads)
PCL root namespace.
Definition: AbstractImage.h:77