PCL
KernelFilter.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/KernelFilter.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_KernelFilter_h
53 #define __PCL_KernelFilter_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/Math.h>
61 #include <pcl/Matrix.h>
62 #include <pcl/SeparableFilter.h>
63 #include <pcl/String.h>
64 
65 namespace pcl
66 {
67 
68 // ----------------------------------------------------------------------------
69 
70 #define __PCL_DEFAULT_FILTER_SEPARABILITY_TOLERANCE 1.0e-06F
71 
89 class PCL_CLASS KernelFilter
90 {
91 public:
92 
96  using coefficient = float;
97 
102 
106  KernelFilter( const String& name = String() )
107  : filterName( name )
108  {
109  }
110 
119  KernelFilter( int n, const String& name = String() )
120  : coefficients( PCL_VALID_KERNEL_SIZE( n ), PCL_VALID_KERNEL_SIZE( n ) )
121  , filterName( name )
122  {
123  PCL_PRECONDITION( n == 0 || n >= 3 )
124  PCL_PRECONDITION( n == 0 || (n & 1) )
125  }
126 
131  template <typename T>
132  KernelFilter( int n, const T& x, const String& name = String() )
133  : coefficients( x, PCL_VALID_KERNEL_SIZE( n ), PCL_VALID_KERNEL_SIZE( n ) )
134  , filterName( name )
135  {
136  PCL_PRECONDITION( n == 0 || n >= 3 )
137  PCL_PRECONDITION( n == 0 || (n & 1) )
138  }
139 
144  KernelFilter( const coefficient_matrix& F, const String& name = String() )
145  : filterName( name )
146  {
147  if ( !F.IsEmpty() && (F.Rows() != F.Cols() || (F.Rows() & 1) == 0) )
148  throw Error( "KernelFilter: Invalid coefficient matrix in constructor." );
149  coefficients = F;
150  }
151 
157  template <typename T>
158  KernelFilter( const T* k, int n, const String& name = String() )
159  : coefficients( k, PCL_VALID_KERNEL_SIZE( n ), PCL_VALID_KERNEL_SIZE( n ) )
160  , filterName( name )
161  {
162  PCL_PRECONDITION( n == 0 || n >= 3 )
163  PCL_PRECONDITION( n == 0 || (n & 1) )
164  }
165 
169  KernelFilter( const KernelFilter& ) = default;
170 
174  KernelFilter( KernelFilter&& ) = default;
175 
179  virtual ~KernelFilter()
180  {
181  }
182 
190  virtual KernelFilter* Clone() const
191  {
192  return new KernelFilter( *this );
193  }
194 
213  virtual SeparableFilter AsSeparableFilter( float tolerance = __PCL_DEFAULT_FILTER_SEPARABILITY_TOLERANCE ) const;
214 
227  virtual bool IsSeparable() const
228  {
229  return !AsSeparableFilter().IsEmpty();
230  }
231 
235  KernelFilter& operator =( const KernelFilter& ) = default;
236 
240  KernelFilter& operator =( KernelFilter&& ) = default;
241 
250  KernelFilter& operator =( const coefficient_matrix& F )
251  {
252  if ( !F.IsEmpty() && (F.Rows() != F.Cols() || (F.Rows() & 1) == 0) )
253  throw Error( "KernelFilter: Invalid coefficient matrix assignment." );
254  coefficients = F;
255  flipped = false;
256  return *this;
257  }
258 
263  KernelFilter& operator =( const coefficient& x )
264  {
265  coefficients = x;
266  flipped = false;
267  return *this;
268  }
269 
275  bool operator ==( const KernelFilter& f ) const
276  {
277  return Name() == f.Name() && SameCoefficients( f );
278  }
279 
283  String Name() const
284  {
285  return filterName;
286  }
287 
291  virtual void Rename( const String& newName )
292  {
293  filterName = newName.Trimmed();
294  }
295 
299  int Size() const
300  {
301  return coefficients.Rows(); // coefficients *must* be a square matrix
302  }
303 
309  virtual void Resize( int n )
310  {
311  PCL_PRECONDITION( n == 0 || n >= 3 )
312  PCL_PRECONDITION( n == 0 || (n & 1) )
313  if ( n == 0 )
314  coefficients = coefficient_matrix();
315  else
316  {
317  n = PCL_VALID_KERNEL_SIZE( n );
318  coefficients = coefficient_matrix( n, n );
319  }
320  flipped = false;
321  }
322 
327  bool IsEmpty() const
328  {
329  return coefficients.IsEmpty();
330  }
331 
335  operator bool() const
336  {
337  return !IsEmpty();
338  }
339 
344  {
345  return coefficients.Rows()*coefficients.Cols();
346  }
347 
352  {
353  return coefficients;
354  }
355 
365  const coefficient* Begin() const
366  {
367  return coefficients.Begin();
368  }
369 
380  const coefficient* End() const
381  {
382  return coefficients.End();
383  }
384 
385 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
389  const coefficient* begin() const
390  {
391  return Begin();
392  }
393 
397  const coefficient* end() const
398  {
399  return End();
400  }
401 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
402 
408  const coefficient* operator[]( int row ) const
409  {
410  return coefficients[row];
411  }
412 
417  double Weight() const
418  {
419  return coefficients.Sum();
420  }
421 
425  double Modulus() const
426  {
427  return coefficients.Modulus();
428  }
429 
435  void Normalize()
436  {
437  double m = Modulus();
438  if ( 1 + m != 1 )
439  coefficients /= m;
440  }
441 
448  {
449  KernelFilter f( *this );
450  f.Normalize();
451  return f;
452  }
453 
458  void Flip()
459  {
460  coefficients.Flip();
461  flipped = !flipped;
462  }
463 
469  {
470  KernelFilter f( *this );
471  f.Flip();
472  return f;
473  }
474 
480  bool IsFlipped() const
481  {
482  return flipped;
483  }
484 
493  bool IsHighPassFilter() const
494  {
495  const coefficient* a = coefficients.Begin();
496  const coefficient* b = coefficients.End();
497  //while ( a < b )
498  // if ( *a++ < 0 || *--b < 0 )
499  // The above loop is better for nonsymmetrical filters, which are seldom used.
500  while ( a < b )
501  if ( *a++ < 0 )
502  return true;
503  return false;
504  }
505 
510  bool SameCoefficients( const KernelFilter& f ) const
511  {
512  return coefficients.SameElements( f.coefficients );
513  }
514 
519  virtual void Clear()
520  {
521  coefficients = coefficient_matrix();
522  flipped = false;
523  }
524 
525 #ifndef __PCL_NO_MATRIX_IMAGE_RENDERING
526 
543  template <class P>
544  void ToImage( GenericImage<P>& image ) const
545  {
546  coefficients.ToImage( image );
547  }
548 
562  void ToImage( ImageVariant& v ) const
563  {
564  coefficients.ToImage( v );
565  }
566 
567 #endif // !__PCL_NO_MATRIX_IMAGE_RENDERING
568 
569 protected:
570 
571  coefficient_matrix coefficients; // filter coefficients, size*size elements
572  String filterName; // identifying name
573  bool flipped = false; // flag true when filter rotated
574 };
575 
576 // ----------------------------------------------------------------------------
577 
578 } // pcl
579 
580 #endif // __PCL_KernelFilter_h
581 
582 // ----------------------------------------------------------------------------
583 // EOF pcl/KernelFilter.h - Released 2024-06-18T15:48:54Z
A simple exception with an associated error message.
Definition: Exception.h:239
Implements a generic, two-dimensional, shared or local image.
Definition: Image.h:278
Acts like a union for all types of images in PCL, with optional class-wide ownership of transported i...
Definition: ImageVariant.h:322
Kernel filter in two dimensions.
Definition: KernelFilter.h:90
virtual ~KernelFilter()
Definition: KernelFilter.h:179
virtual void Rename(const String &newName)
Definition: KernelFilter.h:291
const coefficient * End() const
Definition: KernelFilter.h:380
void ToImage(ImageVariant &v) const
Definition: KernelFilter.h:562
String Name() const
Definition: KernelFilter.h:283
virtual bool IsSeparable() const
Definition: KernelFilter.h:227
const coefficient * Begin() const
Definition: KernelFilter.h:365
double Modulus() const
Definition: KernelFilter.h:425
int NumberOfCoefficients() const
Definition: KernelFilter.h:343
KernelFilter Flipped() const
Definition: KernelFilter.h:468
virtual KernelFilter * Clone() const
Definition: KernelFilter.h:190
KernelFilter(const T *k, int n, const String &name=String())
Definition: KernelFilter.h:158
virtual void Resize(int n)
Definition: KernelFilter.h:309
KernelFilter(KernelFilter &&)=default
KernelFilter(const KernelFilter &)=default
void ToImage(GenericImage< P > &image) const
Definition: KernelFilter.h:544
KernelFilter(int n, const String &name=String())
Definition: KernelFilter.h:119
bool IsEmpty() const
Definition: KernelFilter.h:327
double Weight() const
Definition: KernelFilter.h:417
bool IsHighPassFilter() const
Definition: KernelFilter.h:493
bool SameCoefficients(const KernelFilter &f) const
Definition: KernelFilter.h:510
bool IsFlipped() const
Definition: KernelFilter.h:480
const coefficient * operator[](int row) const
Definition: KernelFilter.h:408
KernelFilter Normalized() const
Definition: KernelFilter.h:447
int Size() const
Definition: KernelFilter.h:299
KernelFilter(int n, const T &x, const String &name=String())
Definition: KernelFilter.h:132
coefficient_matrix Coefficients() const
Definition: KernelFilter.h:351
const coefficient * end() const
Definition: KernelFilter.h:397
KernelFilter(const String &name=String())
Definition: KernelFilter.h:106
KernelFilter(const coefficient_matrix &F, const String &name=String())
Definition: KernelFilter.h:144
virtual SeparableFilter AsSeparableFilter(float tolerance=__PCL_DEFAULT_FILTER_SEPARABILITY_TOLERANCE) const
const coefficient * begin() const
Definition: KernelFilter.h:389
virtual void Clear()
Definition: KernelFilter.h:519
Separable filter in two dimensions.
Unicode (UTF-16) string.
Definition: String.h:8113
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2267
double Modulus(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2617
String Name(int colorSpace)
PCL root namespace.
Definition: AbstractImage.h:77