PCL
VariableShapeFilter.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/VariableShapeFilter.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_VariableShapeFilter_h
53 #define __PCL_VariableShapeFilter_h
54 
56 
57 #include <pcl/Defs.h>
58 
59 #include <pcl/AutoPointer.h>
60 #include <pcl/KernelFilter.h>
61 #include <pcl/Math.h>
62 #include <pcl/PixelInterpolation.h>
63 
64 namespace pcl
65 {
66 
67 // ----------------------------------------------------------------------------
68 
104 class PCL_CLASS VariableShapeFilter : public KernelFilter
105 {
106 public:
107 
112  VariableShapeFilter() = default;
113 
119  VariableShapeFilter( float sigma, float shape = 2, float epsilon = 0.01, const String& name = String() )
120  {
121  Initialize( sigma, shape, epsilon, 1, 0 );
122  Rename( name );
123  }
124 
131  VariableShapeFilter( float sigma, float shape, float epsilon, float rho, float theta = 0, const String& name = String() )
132  {
133  Initialize( sigma, shape, epsilon, rho, theta );
134  Rename( name );
135  }
136 
142  VariableShapeFilter( int n, float shape = 2, float epsilon = 0.01, const String& name = String() )
143  {
144  Initialize( n, shape, epsilon, 1, 0 );
145  Rename( name );
146  }
147 
154  VariableShapeFilter( int n, float shape, float epsilon, float rho, float theta = 0, const String& name = String() )
155  {
156  Initialize( n, shape, epsilon, rho, theta );
157  Rename( name );
158  }
159 
164 
169 
174  KernelFilter* Clone() const override
175  {
176  return new VariableShapeFilter( *this );
177  }
178 
188  SeparableFilter AsSeparableFilter( float tolerance = __PCL_DEFAULT_FILTER_SEPARABILITY_TOLERANCE ) const override
189  {
190  if ( m_shape == 2 && m_rho == 1 )
191  {
192  FVector v = coefficients.RowVector( Size()>>1 );
193  return SeparableFilter( v, v );
194  }
195  return SeparableFilter();
196  }
197 
205  bool IsSeparable() const override
206  {
207  return m_shape == 2 && m_rho == 1;
208  }
209 
213  VariableShapeFilter& operator =( const VariableShapeFilter& ) = default;
214 
218  VariableShapeFilter& operator =( VariableShapeFilter&& ) = default;
219 
224  float SigmaX() const
225  {
226  return m_sigma;
227  }
228 
233  float SigmaY() const
234  {
235  return m_rho*m_sigma;
236  }
237 
244  float Sigma() const
245  {
246  return SigmaX();
247  }
248 
259  float Shape() const
260  {
261  return m_shape;
262  }
263 
267  float Truncation() const
268  {
269  return m_epsilon;
270  }
271 
276  float AspectRatio() const
277  {
278  return m_rho;
279  }
280 
286  float RotationAngle() const
287  {
288  return m_theta;
289  }
290 
295  double FWHMx() const
296  {
297  return 2 * m_sigma * Pow( m_shape*0.6931471805599453, 1.0/m_shape );
298 
299  }
300 
305  double FWHMy() const
306  {
307  return m_rho * FWHMx();
308 
309  }
310 
317  double FWHM() const
318  {
319  return FWHMx();
320  }
321 
327  void Set( float sigma, float shape, float epsilon, float rho, float theta )
328  {
329  Initialize( sigma, shape, epsilon, rho, theta );
330  }
331 
337  void Set( float sigma, float shape, float epsilon, float rho )
338  {
339  Initialize( sigma, shape, epsilon, rho, m_theta );
340  }
341 
347  void Set( float sigma, float shape, float epsilon )
348  {
349  Initialize( sigma, shape, epsilon, m_rho, m_theta );
350  }
351 
357  void Set( float sigma, float shape )
358  {
359  Initialize( sigma, shape, m_epsilon, m_rho, m_theta );
360  }
361 
367  void Set( float sigma )
368  {
369  Initialize( sigma, m_shape, m_epsilon, m_rho, m_theta );
370  }
371 
375  void SetSigma( float sigma )
376  {
377  Set( sigma );
378  }
379 
384  void SetShape( float shape )
385  {
386  Set( m_sigma, shape );
387  }
388 
393  void SetTruncation( float epsilon )
394  {
395  Set( m_sigma, m_shape, epsilon );
396  }
397 
402  void SetAspectRatio( float rho )
403  {
404  Set( m_sigma, m_shape, m_epsilon, rho );
405  }
406 
411  void SetRotationAngle( float theta )
412  {
413  Set( m_sigma, m_shape, m_epsilon, m_rho, theta );
414  }
415 
422  void Resize( int n ) override
423  {
424  Initialize( n, m_shape, m_epsilon, m_rho, m_theta );
425  }
426 
427 private:
428 
429  float m_sigma = 2.0F; // standard deviation, horizontal axis
430  float m_shape = 2.0F; // controls the kurtosis of the filter distribution (2=normal)
431  float m_rho = 1.0F; // vertical:horizontal axes ratio
432  float m_theta = 0.0F; // rotation angle in radians, [0,+pi]
433  float m_epsilon = 0.01F; // maximum truncation error in sigma units
434 
435  void Initialize( float s, float k, float e, float r, float a )
436  {
437  PCL_PRECONDITION( s > 0 )
438  PCL_PRECONDITION( k > 0 )
439  PCL_PRECONDITION( e > 0 )
440  PCL_PRECONDITION( r >= 0 && r <= 1 )
441  PCL_PRECONDITION( a >= 0 && a <= Const<float>::pi() )
442  m_sigma = s;
443  m_shape = k;
444  m_epsilon = Abs( e );
445  m_rho = Range( r, 0.0F, 1.0F );
446  m_theta = Range( a, 0.0F, Const<float>::pi() );
447  KernelFilter::Resize( 1 + (Max( 1, RoundInt( Pow( -m_shape*Pow( m_sigma, m_shape )*Ln( m_epsilon ), 1/m_shape ) ) ) << 1) );
448  Rebuild();
449  }
450 
451  void Initialize( int n, float k, float e, float r, float a )
452  {
453  PCL_PRECONDITION( n == 0 || n >= 3 && (n & 1) != 0 )
454  PCL_PRECONDITION( k > 0 )
455  PCL_PRECONDITION( e > 0 )
456  PCL_PRECONDITION( r >= 0 && r <= 1 )
457  PCL_PRECONDITION( a >= 0 && a <= Const<float>::pi() )
458  KernelFilter::Resize( n );
459  m_shape = k;
460  m_epsilon = Abs( e );
461  m_sigma = (Size() >> 1)/Pow( -m_shape*Ln( m_epsilon ), 1/m_shape );
462  m_rho = Range( r, 0.0F, 1.0F );
463  m_theta = Range( a, 0.0F, Const<float>::pi() );
464  Rebuild();
465  }
466 
467  void Rebuild()
468  {
469  int size = Size();
470  if ( size == 0 )
471  return;
472 
473  float* h = *coefficients;
474  float rk = m_shape * Pow( m_sigma, m_shape );
475 
476  for ( int n2 = size >> 1, y = -n2; y <= n2; ++y )
477  if ( y > 0 )
478  for ( int x = 0; x < size; ++x, ++h )
479  *h = *(h - ((y+y)*size));
480  else
481  for ( int x = -n2; x <= n2; ++x, ++h )
482  *h = (x > 0) ? *(h - (x+x)) : float( Exp( -Pow( Sqrt( float( x*x + y*y ) ), m_shape )/rk ) );
483 
484  if ( m_rho != 1 )
485  {
487 
488  {
489  coefficient_matrix ctemp( coefficients );
490  ctemp.EnsureUnique(); // because we need invariant *ctemp for interpolation
492  interpolator( B.NewInterpolator<FloatPixelTraits>( *ctemp, size, size ) );
493  h = *coefficients;
494  float r = Max( 0.5F/size, m_rho );
495  for ( int n2 = size >> 1, i = -n2; i <= n2; ++i )
496  {
497  float y = float( i )/r + n2;
498  for ( int x = 0; x < size; ++x )
499  *h++ = (y < 0 || y >= size) ? 0.0F : (*interpolator)( float( x ), y );
500  }
501  }
502 
503  if ( m_theta != 0 )
504  {
505  coefficient_matrix ctemp( coefficients );
506  ctemp.EnsureUnique(); // because we need invariant *ctemp for interpolation
507  AutoPointer<PixelInterpolation::Interpolator<FloatPixelTraits> >
508  interpolator( B.NewInterpolator<FloatPixelTraits>( *ctemp, size, size ) );
509  h = *coefficients;
510  float sa, ca;
511  SinCos( -m_theta, sa, ca );
512  for ( int n2 = size >> 1, i = -n2; i <= n2; ++i )
513  for ( int j = -n2; j <= n2; ++j )
514  {
515  float x = ca*j + sa*i + n2;
516  float y = -sa*j + ca*i + n2;
517  *h++ = (x < 0 || y < 0 || x >= size || y >= size) ? 0.0F : (*interpolator)( x, y );
518  }
519  }
520  }
521  }
522 };
523 
524 // ----------------------------------------------------------------------------
525 
526 } // pcl
527 
528 #endif // __PCL_VariableShapeFilter_h
529 
530 // ----------------------------------------------------------------------------
531 // EOF pcl/VariableShapeFilter.h - Released 2024-06-18T15:48:54Z
A smart pointer with exclusive object ownership and optional automatic object destruction.
Definition: AutoPointer.h:241
Bicubic pixel interpolation - an alias for BicubicSplinePixelInterpolation.
Fundamental numeric constants.
Definition: Constants.h:73
32-bit IEEE 754 normalized floating point real pixel traits.
Definition: PixelTraits.h:369
Generic vector of arbitrary length.
Definition: Vector.h:107
Kernel filter in two dimensions.
Definition: KernelFilter.h:90
Separable filter in two dimensions.
Unicode (UTF-16) string.
Definition: String.h:8113
A kernel filter with variable kurtosis.
void Resize(int n) override
VariableShapeFilter(float sigma, float shape, float epsilon, float rho, float theta=0, const String &name=String())
VariableShapeFilter(const VariableShapeFilter &)=default
VariableShapeFilter(int n, float shape=2, float epsilon=0.01, const String &name=String())
VariableShapeFilter(int n, float shape, float epsilon, float rho, float theta=0, const String &name=String())
void Set(float sigma, float shape)
bool IsSeparable() const override
void Set(float sigma, float shape, float epsilon, float rho, float theta)
void SetTruncation(float epsilon)
void Set(float sigma, float shape, float epsilon, float rho)
void Set(float sigma, float shape, float epsilon)
VariableShapeFilter(float sigma, float shape=2, float epsilon=0.01, const String &name=String())
VariableShapeFilter(VariableShapeFilter &&)=default
SeparableFilter AsSeparableFilter(float tolerance=__PCL_DEFAULT_FILTER_SEPARABILITY_TOLERANCE) const override
void SetRotationAngle(float theta)
KernelFilter * Clone() const override
Complex< T1 > Pow(const Complex< T1 > &c, T2 x) noexcept
Definition: Complex.h:747
Complex< T > Sqrt(const Complex< T > &c) noexcept
Definition: Complex.h:674
Complex< T > Exp(const Complex< T > &c) noexcept
Definition: Complex.h:714
Complex< T > Ln(const Complex< T > &c) noexcept
Definition: Complex.h:725
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:429
void SinCos(T x, T &sx, T &cx) noexcept
Definition: Math.h:1030
int RoundInt(T x) noexcept
Definition: Math.h:1503
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
Definition: Utility.h:190
constexpr const T & Max(const T &a, const T &b) noexcept
Definition: Utility.h:119
PCL root namespace.
Definition: AbstractImage.h:77