PCL
MoffatFilter.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.6.5
6 // ----------------------------------------------------------------------------
7 // pcl/MoffatFilter.h - Released 2024-01-13T15:47:58Z
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_MoffatFilter_h
53 #define __PCL_MoffatFilter_h
54 
56 
57 #include <pcl/Defs.h>
58 
59 #include <pcl/KernelFilter.h>
60 #include <pcl/Math.h>
61 
62 namespace pcl
63 {
64 
65 // ----------------------------------------------------------------------------
66 
105 class PCL_CLASS MoffatFilter : public KernelFilter
106 {
107 public:
108 
113  MoffatFilter() = default;
114 
120  MoffatFilter( float sigma, float beta = 4, float epsilon = 0.01, const String& name = String() )
121  {
122  Initialize( sigma, beta, epsilon, 1, 0 );
123  Rename( name );
124  }
125 
132  MoffatFilter( float sigma, float beta, float epsilon, float rho, float theta = 0, const String& name = String() )
133  {
134  Initialize( sigma, beta, epsilon, rho, theta );
135  Rename( name );
136  }
137 
143  MoffatFilter( int n, float beta = 4, float epsilon = 0.01, const String& name = String() )
144  {
145  Initialize( n, beta, epsilon, 1, 0 );
146  Rename( name );
147  }
148 
155  MoffatFilter( int n, float beta, float epsilon, float rho, float theta = 0, const String& name = String() )
156  {
157  Initialize( n, beta, epsilon, rho, theta );
158  Rename( name );
159  }
160 
164  MoffatFilter( const MoffatFilter& ) = default;
165 
169  MoffatFilter( MoffatFilter&& ) = default;
170 
173  KernelFilter* Clone() const override
174  {
175  return new MoffatFilter( *this );
176  }
177 
184  SeparableFilter AsSeparableFilter( float tolerance = __PCL_DEFAULT_FILTER_SEPARABILITY_TOLERANCE ) const override
185  {
186  return SeparableFilter();
187  }
188 
195  bool IsSeparable() const override
196  {
197  return false;
198  }
199 
203  MoffatFilter& operator =( const MoffatFilter& ) = default;
204 
208  MoffatFilter& operator =( MoffatFilter&& ) = default;
209 
214  float SigmaX() const
215  {
216  return m_sigma;
217  }
218 
223  float SigmaY() const
224  {
225  return m_rho*m_sigma;
226  }
227 
234  float Sigma() const
235  {
236  return SigmaX();
237  }
238 
243  float Beta() const
244  {
245  return m_beta;
246  }
247 
251  float Truncation() const
252  {
253  return m_epsilon;
254  }
255 
260  float AspectRatio() const
261  {
262  return m_rho;
263  }
264 
270  float RotationAngle() const
271  {
272  return m_theta;
273  }
274 
279  double FWHMx() const
280  {
281  return 2 * Sqrt( Pow2( 1/m_beta ) - 1 ) * m_sigma;
282 
283  }
284 
289  double FWHMy() const
290  {
291  return m_rho * FWHMx();
292 
293  }
294 
301  double FWHM() const
302  {
303  return FWHMx();
304  }
305 
311  void Set( float sigma, float beta, float epsilon, float rho, float theta )
312  {
313  Initialize( sigma, beta, epsilon, rho, theta );
314  }
315 
321  void Set( float sigma, float beta, float epsilon, float rho )
322  {
323  Initialize( sigma, beta, epsilon, rho, m_theta );
324  }
325 
331  void Set( float sigma, float beta, float epsilon )
332  {
333  Initialize( sigma, beta, epsilon, m_rho, m_theta );
334  }
335 
341  void Set( float sigma, float beta )
342  {
343  Initialize( sigma, beta, m_epsilon, m_rho, m_theta );
344  }
345 
351  void Set( float sigma )
352  {
353  Initialize( sigma, m_beta, m_epsilon, m_rho, m_theta );
354  }
355 
359  void SetSigma( float sigma )
360  {
361  Set( sigma );
362  }
363 
368  void SetBeta( float beta )
369  {
370  Set( m_sigma, beta );
371  }
372 
377  void SetTruncation( float epsilon )
378  {
379  Set( m_sigma, m_beta, epsilon );
380  }
381 
386  void SetAspectRatio( float rho )
387  {
388  Set( m_sigma, m_beta, m_epsilon, rho );
389  }
390 
395  void SetRotationAngle( float theta )
396  {
397  Set( m_sigma, m_beta, m_epsilon, m_rho, theta );
398  }
399 
407  void Resize( int n ) override
408  {
409  Initialize( n, m_beta, m_epsilon, m_rho, m_theta );
410  }
411 
412 private:
413 
414  float m_sigma = 2.0F; // standard deviation, horizontal axis
415  float m_beta = 4.0F; // beta exponent
416  float m_rho = 1.0F; // vertical:horizontal axis ratio
417  float m_theta = 0.0F; // rotation angle in radians, [0,+pi]
418  float m_epsilon = 0.01F; // maximum truncation error in sigma units
419 
420  void Initialize( float s, float b, float e, float r, float a )
421  {
422  PCL_PRECONDITION( s > 0 )
423  PCL_PRECONDITION( b > 0 )
424  PCL_PRECONDITION( e > 0 )
425  PCL_PRECONDITION( r >= 0 && r <= 1 )
426  PCL_PRECONDITION( a >= 0 && a <= Const<float>::pi() )
427  m_sigma = Abs( s );
428  m_beta = Abs( b );
429  m_epsilon = Abs( e );
430  m_rho = Range( r, 0.0F, 1.0F );
431  m_theta = Range( a, 0.0F, Const<float>::pi() );
432  KernelFilter::Resize( 1 + (Max( 1, RoundInt( m_sigma*Sqrt( Pow( m_epsilon, -1/m_beta ) - 1 ) ) ) << 1) );
433  Rebuild();
434  }
435 
436  void Initialize( int n, float b, float e, float r, float a )
437  {
438  PCL_PRECONDITION( n == 0 || n >= 3 && (n & 1) != 0 )
439  PCL_PRECONDITION( b > 0 )
440  PCL_PRECONDITION( e > 0 )
441  PCL_PRECONDITION( r >= 0 && r <= 1 )
442  PCL_PRECONDITION( a >= 0 && a <= Const<float>::pi() )
443  KernelFilter::Resize( n );
444  m_beta = Abs( b );
445  m_epsilon = Abs( e );
446  m_sigma = (Size() >> 1)/Sqrt( Pow( m_epsilon, -1/m_beta ) - 1 );
447  m_rho = Range( r, 0.0F, 1.0F );
448  m_theta = Range( a, 0.0F, Const<float>::pi() );
449  Rebuild();
450  }
451 
452  void Rebuild()
453  {
454  int size = Size();
455  if ( size == 0 )
456  return;
457 
458  float* h = *coefficients;
459  double sx = m_sigma;
460  double sy = m_rho * sx;
461  double mb = -m_beta;
462 
463  if ( m_theta == 0 || m_rho == 1 )
464  {
465  double sx2 = sx*sx;
466  double sy2 = sy*sy;
467  for ( int n2 = size >> 1, dy = -n2; dy <= n2; ++dy )
468  if ( dy > 0 )
469  for ( int dx = 0; dx < size; ++dx, ++h )
470  *h = *(h - ((dy+dy)*size));
471  else
472  for ( int dx = -n2; dx <= n2; ++dx, ++h )
473  *h = (dx > 0) ? *(h - (dx+dx)) : float( Pow( 1 + dx*dx/sx2 + dy*dy/sy2, mb ) );
474  }
475  else
476  {
477  double st, ct; SinCos( double( m_theta ), st, ct );
478  double sct = st*ct;
479  double st2 = st*st;
480  double ct2 = ct*ct;
481  double sx2 = sx*sx;
482  double sy2 = sy*sy;
483  double p1 = ct2/sx2 + st2/sy2;
484  double p2 = sct/sy2 - sct/sx2;
485  double p3 = st2/sx2 + ct2/sy2;
486  for ( int n2 = size >> 1, dy = -n2; dy <= n2; ++dy )
487  {
488  double twop2dy = 2*p2*dy;
489  double p3dy2 = p3*dy*dy;
490  for ( int dx = -n2; dx <= n2; ++dx, ++h )
491  *h = float( Pow( 1 + p1*dx*dx + twop2dy*dx + p3dy2, mb ) );
492  }
493  }
494  }
495 };
496 
497 // ----------------------------------------------------------------------------
498 
499 } // pcl
500 
501 #endif // __PCL_MoffatFilter_h
502 
503 // ----------------------------------------------------------------------------
504 // EOF pcl/MoffatFilter.h - Released 2024-01-13T15:47:58Z
pcl::MoffatFilter::MoffatFilter
MoffatFilter(float sigma, float beta, float epsilon, float rho, float theta=0, const String &name=String())
Definition: MoffatFilter.h:132
pcl
PCL root namespace.
Definition: AbstractImage.h:76
pcl::MoffatFilter::Set
void Set(float sigma, float beta)
Definition: MoffatFilter.h:341
pcl::Range
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
Definition: Utility.h:190
pcl::MoffatFilter
A kernel filter implementing a discrete Moffat distribution in two dimensions.
Definition: MoffatFilter.h:105
pcl::MoffatFilter::FWHMy
double FWHMy() const
Definition: MoffatFilter.h:289
pcl::String
Unicode (UTF-16) string.
Definition: String.h:8112
pcl::MoffatFilter::AsSeparableFilter
SeparableFilter AsSeparableFilter(float tolerance=__PCL_DEFAULT_FILTER_SEPARABILITY_TOLERANCE) const override
Definition: MoffatFilter.h:184
pcl::MoffatFilter::MoffatFilter
MoffatFilter(int n, float beta, float epsilon, float rho, float theta=0, const String &name=String())
Definition: MoffatFilter.h:155
pcl::Max
constexpr const T & Max(const T &a, const T &b) noexcept
Definition: Utility.h:119
pcl::RoundInt
int RoundInt(T x) noexcept
Definition: Math.h:1503
pcl::MoffatFilter::Beta
float Beta() const
Definition: MoffatFilter.h:243
pcl::MoffatFilter::Set
void Set(float sigma, float beta, float epsilon)
Definition: MoffatFilter.h:331
pcl::MoffatFilter::Truncation
float Truncation() const
Definition: MoffatFilter.h:251
pcl::MoffatFilter::SetTruncation
void SetTruncation(float epsilon)
Definition: MoffatFilter.h:377
pcl::MoffatFilter::IsSeparable
bool IsSeparable() const override
Definition: MoffatFilter.h:195
pcl::MoffatFilter::SetBeta
void SetBeta(float beta)
Definition: MoffatFilter.h:368
pcl::Const
Fundamental numeric constants.
Definition: Constants.h:72
KernelFilter.h
pcl::MoffatFilter::MoffatFilter
MoffatFilter(int n, float beta=4, float epsilon=0.01, const String &name=String())
Definition: MoffatFilter.h:143
pcl::MoffatFilter::RotationAngle
float RotationAngle() const
Definition: MoffatFilter.h:270
pcl::MoffatFilter::Set
void Set(float sigma)
Definition: MoffatFilter.h:351
pcl::Pow
Complex< T1 > Pow(const Complex< T1 > &c, T2 x) noexcept
Definition: Complex.h:747
pcl::MoffatFilter::MoffatFilter
MoffatFilter(float sigma, float beta=4, float epsilon=0.01, const String &name=String())
Definition: MoffatFilter.h:120
Math.h
pcl::SinCos
void SinCos(T x, T &sx, T &cx) noexcept
Definition: Math.h:1030
pcl::SeparableFilter
Separable filter in two dimensions.
Definition: SeparableFilter.h:89
pcl::Sqrt
Complex< T > Sqrt(const Complex< T > &c) noexcept
Definition: Complex.h:674
pcl::KernelFilter
Kernel filter in two dimensions.
Definition: KernelFilter.h:89
pcl::MoffatFilter::AspectRatio
float AspectRatio() const
Definition: MoffatFilter.h:260
pcl::MoffatFilter::Set
void Set(float sigma, float beta, float epsilon, float rho)
Definition: MoffatFilter.h:321
pcl::MoffatFilter::FWHM
double FWHM() const
Definition: MoffatFilter.h:301
pcl::MoffatFilter::SetRotationAngle
void SetRotationAngle(float theta)
Definition: MoffatFilter.h:395
pcl::MoffatFilter::Clone
KernelFilter * Clone() const override
Definition: MoffatFilter.h:173
pcl::MoffatFilter::SetAspectRatio
void SetAspectRatio(float rho)
Definition: MoffatFilter.h:386
pcl::MoffatFilter::Set
void Set(float sigma, float beta, float epsilon, float rho, float theta)
Definition: MoffatFilter.h:311
pcl::MoffatFilter::SigmaY
float SigmaY() const
Definition: MoffatFilter.h:223
pcl::MoffatFilter::Sigma
float Sigma() const
Definition: MoffatFilter.h:234
pcl::MoffatFilter::SigmaX
float SigmaX() const
Definition: MoffatFilter.h:214
pcl::MoffatFilter::SetSigma
void SetSigma(float sigma)
Definition: MoffatFilter.h:359
pcl::MoffatFilter::FWHMx
double FWHMx() const
Definition: MoffatFilter.h:279
pcl::Abs
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:429
pcl::Pow2
constexpr T Pow2(T x) noexcept
Definition: Math.h:1717
Defs.h
pcl::MoffatFilter::Resize
void Resize(int n) override
Definition: MoffatFilter.h:407