Files
tenmon/3rdparty/include/pcl/LocalNormalizationData.h
T
2022-04-12 08:17:18 +02:00

796 lines
30 KiB
C++

// ____ ______ __
// / __ \ / ____// /
// / /_/ // / / /
// / ____// /___ / /___ PixInsight Class Library
// /_/ \____//_____/ PCL 2.4.23
// ----------------------------------------------------------------------------
// pcl/LocalNormalizationData.h - Released 2022-03-12T18:59:29Z
// ----------------------------------------------------------------------------
// This file is part of the PixInsight Class Library (PCL).
// PCL is a multiplatform C++ framework for development of PixInsight modules.
//
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
//
// Redistribution and use in both source and binary forms, with or without
// modification, is permitted provided that the following conditions are met:
//
// 1. All redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. All redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
// of their contributors, may be used to endorse or promote products derived
// from this software without specific prior written permission. For written
// permission, please contact info@pixinsight.com.
//
// 4. All products derived from this software, in any form whatsoever, must
// reproduce the following acknowledgment in the end-user documentation
// and/or other materials provided with the product:
//
// "This product is based on software from the PixInsight project, developed
// by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
//
// Alternatively, if that is where third-party acknowledgments normally
// appear, this acknowledgment must be reproduced in the product itself.
//
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------
#ifndef __PCL_LocalNormalizationData_h
#define __PCL_LocalNormalizationData_h
/// \file pcl/LocalNormalizationData.h
#include <pcl/Defs.h>
#include <pcl/BicubicInterpolation.h>
#include <pcl/File.h>
#include <pcl/Image.h>
#include <pcl/TimePoint.h>
namespace pcl
{
// ----------------------------------------------------------------------------
class PCL_CLASS XMLDocument;
class PCL_CLASS XMLElement;
/*!
* \class LocalNormalizationData
* \brief Normalization data parser and generator
*
* %LocalNormalizationData implements support for the %XML normalization data
* format (XNML format, .xnml file suffix).
*
* An XNML file stores local normalization function data suitable for pixel
* rejection and image integration tasks, including drizzle integration. The
* %LocalNormalizationData class is a high-level interface for parsing and
* generation of these special files.
*
* Local normalization functions are serialized as floating point real images,
* where each channel stores scaling and zero offset coefficients, sampled at a
* prescribed normalization scale, for a channel of a specific image.
*
* For a channel index c and position vector i on a given input image, the
* local normalization function is:
*
* v'(c,i) = U(A(c,i))*(v(c,i) - C(c)) + U(B(c,i))
*
* where A(c) is the matrix of scaling coefficients, B(c) is the matrix of zero
* offset coefficients, C(c) is the bias level (C = 0 by default), U() is a
* scale-dependent interpolation functional, v is an input pixel value, and v'
* is the normalized pixel value.
*
* This implementation can also apply an optional global normalization function
* after the local normalization. If the corresponding parameters are defined,
* the global normalization function is:
*
* v''(c,i) = S(c)*(v'(c,i) - T(c)) + R(c)
*
* where S is a vector of global scaling factors, T is a vector of target
* locations, and R is a vector of reference locations. v' is the locally
* normalized pixel value, as defined above, and v'' is the output value after
* local and global normalization.
*
* Local normalization matrices are conveniently stored as multichannel,
* two-dimensional images, which facilitates two-dimensional interpolation with
* smooth pixel interpolation algorithms. Normalization matrices are normally
* much smaller than the reference image dimensions. This happens because we
* define local normalization functions at a specific dimensional scale, which
* typically corresponds to a large dyadic scale of 64, 128, or 256 pixels. For
* this reason, normalization matrices require a smooth interpolation to
* compute normalization coefficients at reference image coordinates.
*
* \sa DrizzleData
*/
class PCL_CLASS LocalNormalizationData
{
public:
/*!
* Represents a per-channel set of local image normalization matrices.
*/
typedef Image normalization_matrices;
/*!
* Represents a local normalization function coefficient.
*/
typedef normalization_matrices::sample normalization_coefficient;
/*!
* Represents a smooth interpolation used for calculation of local
* normalization function values at image pixel coordinates.
*/
typedef BicubicBSplineInterpolation<normalization_coefficient>
matrix_interpolation;
/*!
* Represents an array of local normalization interpolators.
*/
typedef Array<matrix_interpolation> matrix_interpolations;
/*!
* Constructs an empty %LocalNormalizationData object.
*/
LocalNormalizationData() = default;
/*!
* Copy constructor.
*/
LocalNormalizationData( const LocalNormalizationData& ) = default;
/*!
* Move constructor.
*/
LocalNormalizationData( LocalNormalizationData&& ) = default;
/*!
* Constructs a new %LocalNormalizationData instance by loading and parsing
* a file in XNML format.
*
* \param filePath Path to an existing file that will be parsed. The file
* contents must be in %XML normalization data format
* (usually, a file with the .xnml suffix).
*
* \param ignoreNormalizationData If true, local normalization data will
* be ignored and not parsed. This includes matrices of
* normalization function coefficients. Setting this
* parameter to true can be useful when the caller only
* needs to retrieve information on file paths and
* reference dimensions.
*
* This constructor validates the data retrieved from the specified file. It
* throws the appropriate Error exceptions in the event of parsing errors or
* invalid data.
*/
LocalNormalizationData( const String& filePath, bool ignoreNormalizationData = false )
{
Parse( filePath, ignoreNormalizationData );
}
/*!
* Constructs a new %LocalNormalizationData instance by parsing a
* well-formed %XML document in XNML format.
*
* \param xml Reference to the source %XML document. This constructor
* expects an %XML document in valid %XML normalization
* data format (.xnml).
*
* \param ignoreNormalizationData If true, local normalization data will
* be ignored and not parsed. This includes matrices of
* normalization function coefficients. Setting this
* parameter to true can be useful when the caller only
* needs to retrieve information on file paths and
* reference dimensions.
*
* This constructor validates the data retrieved from the specified %XML
* document. It throws an Error exception in the event of an invalid
* document or invalid data.
*/
LocalNormalizationData( const XMLDocument& xml, bool ignoreNormalizationData = false )
{
Parse( xml, ignoreNormalizationData );
}
/*!
* Constructs a new %LocalNormalizationData instance by parsing an %XML
* element in XNML format.
*
* \param element Reference to the source %XML element. This constructor
* expects an %XML document tree in valid %XML
* normalization data format (.xnml) rooted at the
* specified element.
*
* \param ignoreNormalizationData If true, local normalization data will
* be ignored and not parsed. This includes matrices of
* normalization function coefficients. Setting this
* parameter to true can be useful when the caller only
* needs to retrieve information on file paths and
* reference dimensions.
*
* This constructor validates the data retrieved from the specified %XML
* element. It throws an Error exception in the event of invalid data.
*/
LocalNormalizationData( const XMLElement& element, bool ignoreNormalizationData = false )
{
Parse( element, ignoreNormalizationData );
}
/*!
* Virtual destructor.
*/
virtual ~LocalNormalizationData()
{
}
/*!
* Returns the full path to the reference image file used for calculation of
* the normalization data represented by this instance, or an empty string
* if that file path is not available.
*
* \sa SetReferenceFilePath()
*/
const String& ReferenceFilePath() const
{
return m_referenceFilePath;
}
/*!
* Sets the path to the reference image file used for calculation of the
* normalization data stored in this instance.
*
* \sa ReferenceFilePath()
*/
void SetReferenceFilePath( const String& filePath )
{
m_referenceFilePath = File::FullPath( filePath );
}
/*!
* Returns the full path to the image file for which the normalization data
* represented by this instance was calculated, or an empty string if such
* file path is not available.
*
* The file identified by this function stores the input image of the image
* normalization task that created this object. This file can be used as
* input for a regular (non-drizzle) integration task, and the data
* transported by this object can then be used for normalization of pixel
* values in pixel rejection and/or integration output generation, including
* drizzle integration.
*
* \sa SetTargetFilePath()
*/
const String& TargetFilePath() const
{
return m_targetFilePath;
}
/*!
* Sets the path to the image file for which the normalization data stored
* in this instance was calculated.
*
* \sa TargetFilePath()
*/
void SetTargetFilePath( const String& filePath )
{
m_targetFilePath = File::FullPath( filePath );
}
/*!
* Returns the scale in pixels at which the local normalization functions
* were sampled and calculated. For valid normalization data, the returned
* value must be larger than zero, and should normally be larger than or
* equal to 32 pixels.
*
* \sa SetNormalizationScale()
*/
int NormalizationScale() const
{
return m_scale;
}
/*!
* Sets the scale in pixels at which the local normalization functions have
* been sampled and calculated.
*
* \sa NormalizationScale()
*/
void SetNormalizationScale( int scale )
{
m_scale = scale;
}
/*!
* Returns the width in pixels of the normalization reference and target
* images, or -1 if this object has not been initialized with valid data.
*
* \sa ReferenceHeight(), SetReferenceDimensions()
*/
int ReferenceWidth() const
{
return m_referenceWidth;
}
/*!
* Returns the height in pixels of the normalization reference and target
* images, or -1 if this object has not been initialized with valid data.
*
* \sa ReferenceWidth(), SetReferenceDimensions()
*/
int ReferenceHeight() const
{
return m_referenceHeight;
}
/*!
* Sets new normalization image dimensions in pixels, \a width and
* \a height, respectively.
*
* \sa ReferenceWidth(), ReferenceHeight()
*/
void SetReferenceDimensions( int width, int height )
{
m_referenceWidth = width;
m_referenceHeight = height;
}
/*!
* Returns the number of channels or pixel sample planes in the image
* represented by this instance, or zero if this object has not been
* initialized with valid data.
*/
int NumberOfChannels() const
{
return m_A.NumberOfChannels();
}
/*!
* Returns a reference to the set of matrices of zero offset coefficients in
* the local normalization function.
*
* See the class description for detailed information on local normalization
* functions.
*
* \sa Scale(), SetLocalNormalizationParameters(), NormalizationScale()
*/
const normalization_matrices& ZeroOffset() const
{
return m_B;
}
/*!
* Returns a reference to the set of matrices of scaling coefficients in the
* local normalization function.
*
* See the class description for detailed information on local normalization
* functions.
*
* \sa ZeroOffset(), SetLocalNormalizationParameters(), NormalizationScale()
*/
const normalization_matrices& Scale() const
{
return m_A;
}
/*!
* Returns a reference to the vector of per-channel bias levels. Each bias
* is a constant scalar subtracted from input pixel sample values before
* applying the local normalization function. This allows to remove any
* systematic offset or additive pedestal that could be present in the data
* to be normalized. The possibility to remove a constant value also adds
* flexibility to the local normalization function.
*
* If not specified, the target bias is always zero by default.
*/
const Vector& Bias() const
{
return m_C;
}
/*!
* Sets new local normalization function parameters.
*
* \param A Reference to an image storing the matrices of scaling
* normalization coefficients.
*
* \param B Reference to an image storing the matrices of zero
* offset normalization coefficients.
*
* \param C Reference to an optional vector of per-channel biases.
* If not specified, the bias will be set to zero for each
* channel by default.
*
* See the class description for detailed information on local normalization
* functions.
*
* This function throws an Error exception if some of the specified local
* normalization parameters are invalid or incongruent.
*
* \sa ZeroOffset(), Scale(), Bias(), SetGlobalNormalizationParameters()
*/
void SetLocalNormalizationParameters( const normalization_matrices& A, const normalization_matrices& B, const Vector& C = Vector() )
{
if ( A.Bounds() != B.Bounds() )
throw Error( "LocalNormalizationData::SetLocalNormalizationParameters(): Incompatible matrix dimensions." );
if ( A.NumberOfChannels() != B.NumberOfChannels() )
throw Error( "LocalNormalizationData::SetLocalNormalizationParameters(): Incompatible number of normalization matrices." );
m_A = A;
m_B = B;
if ( !C.IsEmpty() )
{
if ( C.Length() != A.NumberOfChannels() )
throw Error( "LocalNormalizationData::SetLocalNormalizationParameters(): Incompatible bias vector length." );
m_C = C;
}
}
/*!
* Returns a reference to the vector of per-channel global reference
* locations (or zero-offsets).
*
* \sa GlobalTargetLocation(), GlobalScalingFactors(),
* SetGlobalNormalizationParameters()
*/
const Vector& GlobalReferenceLocation() const
{
return m_Rc;
}
/*!
* Returns a reference to the vector of per-channel global target locations
* (or zero-offsets).
*
* \sa GlobalReferenceLocation(), GlobalScalingFactors(),
* SetGlobalNormalizationParameters()
*/
const Vector& GlobalTargetLocation() const
{
return m_Rc;
}
/*!
* Returns a reference to the vector of per-channel global scaling factors.
*
* \sa GlobalReferenceLocation(), GlobalTargetLocation(),
* SetGlobalNormalizationParameters()
*/
const Vector& GlobalScalingFactors() const
{
return m_S;
}
/*!
* Sets new global normalization vectors.
*
* \param Rc Reference to a vector of per-channel reference global
* locations.
*
* \param Tc Reference to a vector of per-channel target global
* locations.
*
* \param S Reference to a vector of per-channel global scaling
* factors.
*
* See the class description for detailed information on local normalization
* functions.
*
* This function throws an Error exception if some of the specified global
* normalization parameters are invalid or incongruent.
*
* \sa GlobalReferenceLocation(), GlobalTargetLocation(),
* GlobalScalingFactors(), SetLocalNormalizationParameters()
*/
void SetGlobalNormalizationParameters( const Vector& Rc, const Vector& Tc, const Vector& S )
{
if ( m_B.IsEmpty() )
throw Error( "LocalNormalizationData::SetGlobalNormalizationParameters(): No zero offset coefficient matrix has been defined." );
if ( Rc.Length() != m_B.NumberOfChannels() || Tc.Length() != m_B.NumberOfChannels() || S.Length() != m_B.NumberOfChannels() )
throw Error( "LocalNormalizationData::SetGlobalNormalizationParameters(): Incompatible vector lengths." );
m_Rc = Rc;
m_Tc = Tc;
m_S = S;
}
/*!
* Returns a reference to the vector of per-channel relative scale factors.
*/
const Vector& RelativeScaleFactors() const
{
return m_relScale;
}
/*!
* Sets a new relative scale factors vector.
*
* \param Rc Reference to a vector of per-channel relative scale factors.
*
* See the class description for detailed information on local normalization
* functions.
*
* This function throws an Error exception if the specified vector is
* invalid or incongruent with normalization data.
*/
void SetRelativeScaleFactors( const Vector& s )
{
if ( m_B.IsEmpty() )
throw Error( "LocalNormalizationData::SetRelativeScaleFactors(): No zero offset coefficient matrix has been defined." );
if ( s.Length() != m_B.NumberOfChannels() )
throw Error( "LocalNormalizationData::SetRelativeScaleFactors(): Incompatible vector lengths." );
m_relScale = s;
}
/*!
* Initializes the internal local normalization function interpolators.
* After this initialization, operator()() can be called repeatedly to apply
* the local normalization function to pixel sample values in reference
* image coordinates.
*
* Calling this member function is not necessary when valid local
* normalization data have been loaded from an XNML file or %XML document,
* since in this case the internal interpolators are always initialized
* automatically. This function must be called, however, for newly defined
* normalization data set by calling SetReferenceDimensions() and
* SetLocalNormalizationParameters().
*
* If this object has not been initialized with valid local normalization
* data, this member function throws an Error exception.
*
* \sa operator()()
*/
void InitInterpolations();
/*!
* Returns true iff valid local normalization function data have been loaded
* and the internal interpolators have been initialized.
*/
bool HasInterpolations() const
{
return !m_UA.IsEmpty() && !m_UB.IsEmpty();
}
/*!
* Returns a locally normalized pixel sample value.
*
* \param z Input pixel sample value (unnormalized).
* \param x Horizontal image pixel coordinate.
* \param y Vertical image pixel coordinate.
* \param c Channel index.
*
* This operator interpolates local normalization functions and applies the
* corresponding linear transformation to the input value \a z, which gives
* the return value. Note that the normalized value might be out of the
* input pixel sample range. In such case the normalized value should be
* truncated or rescaled as appropriate.
*
* For performance reasons, this operator does not check that the required
* normalization and interpolation data have been initialized; if they are
* not, calling this operator will most likely lead to a crash.
* Interpolation data are automatically initialized when a valid XNML file
* or %XML element is loaded and parsed. For newly constructed objects, make
* sure you define the required reference dimensions and normalization
* matrices. Then call InitInterpolations() before starting to call this
* operator.
*/
double operator()( double z, int x, int y, int c = 0 ) const
{
double sx = m_sx*x;
double sy = m_sy*y;
if ( likely( m_S.IsEmpty() ) )
return m_UA[c]( sx, sy )*(z - m_C[c]) + m_UB[c]( sx, sy );
return (m_UA[c]( sx, sy )*(z - m_C[c]) + m_UB[c]( sx, sy ) - m_Tc[c])*m_S[c] + m_Rc[c];
}
/*!
* Returns the UTC time this normalization data was created, or an invalid
* TimePoint instance if creation time information is not available.
*/
TimePoint CreationTime() const
{
return m_creationTime;
}
/*!
* Clears all of the image normalization data transported by this instance,
* yielding an empty %LocalNormalizationData object.
*/
void Clear();
/*!
* Loads and parses a normalization data file in XNML format.
*
* \param filePath Path to an existing file that will be parsed. The file
* contents must be in %XML normalization data format
* (usually, a file with the .xnml suffix).
*
* \param ignoreNormalizationData If true, local normalization data will
* be ignored and not parsed. This includes matrices of
* normalization function coefficients. Setting this
* parameter to true can be useful when the caller only
* needs to retrieve information on file paths and
* reference dimensions.
*
* All of the previous data transported by this instance will be replaced
* with new data acquired from the specified file.
*
* This function validates the data retrieved from the specified file. It
* throws an Error exception in the event of parsing errors or invalid data.
*/
void Parse( const String& filePath, bool ignoreNormalizationData = false );
/*!
* Parses a well-formed %XML document in XNML format.
*
* \param xml Reference to the source %XML document. This member
* function expects an %XML document in valid %XML
* normalization data format (.xnml).
*
* \param ignoreNormalizationData If true, local normalization data will
* be ignored and not parsed. This includes matrices of
* normalization function coefficients. Setting this
* parameter to true can be useful when the caller only
* needs to retrieve information on file paths and
* reference dimensions.
*
* All of the previous data transported by this instance will be replaced
* with new data acquired from the specified %XML contents.
*
* This function validates the data retrieved from the specified %XML
* document. It throws an Error exception in the event of an invalid
* document or invalid data.
*/
void Parse( const XMLDocument& xml, bool ignoreNormalizationData = false );
/*!
* Parses an %XML element in XNML format.
*
* \param element Reference to the source %XML element. This member
* function expects an %XML document tree in valid %XML
* normalization data format (.xnml) rooted at the
* specified element.
*
* \param ignoreNormalizationData If true, local normalization data will
* be ignored and not parsed. This includes matrices of
* normalization function coefficients. Setting this
* parameter to true can be useful when the caller only
* needs to retrieve information on file paths and
* reference dimensions.
*
* All of the previous data transported by this instance will be replaced
* with new data acquired from the specified %XML contents.
*
* This function validates the data retrieved from the specified %XML
* element. It throws an Error exception in the event of invalid data.
*/
void Parse( const XMLElement& element, bool ignoreNormalizationData = false );
/*!
* Returns true if data compression is enabled for serializations performed
* with this object.
*
* Data compression is enabled by default for newly constructed
* %LocalNormalizationData objects. Currently the LZ4 compression codec is
* applied for serialization of local normalization matrices.
*
* \sa EnableCompression(), DisableCompression()
*/
bool IsCompressionEnabled() const
{
return m_compressionEnabled;
}
/*!
* Enables compression of serialized local normalization data.
*
* \sa IsCompressionEnabled(), DisableCompression()
*/
void EnableCompression( bool enable = true )
{
m_compressionEnabled = enable;
}
/*!
* Returns a version number corresponding to the normalization data
* transported by this object.
*
* Version numbers can be used to control the use and propagation of
* normalization data generated by different versions of a normalization
* tool or process, such as the standard LocalNormalization process in
* PixInsight. The version number is zero by default, meaning that the
* version is unspecified. An appropriate version number &gt; 0 can be set
* by calling SetVersion(), which is recommended before serializing
* normalization data to a new XNML file. When an XNML file is loaded and it
* contains a valid version number tag, it is loaded and will be returned by
* this function. Otherwise the returned value will be zero.
*/
int Version() const
{
return m_version;
}
/*!
* Sets the normalization data version. See Version() for information on
* normalization data versions.
*/
void SetVersion( int version )
{
m_version = version;
}
/*!
* Disables compression of serialized local normalization data.
*
* \sa IsCompressionEnabled(), EnableCompression()
*/
void DisableCompression( bool disable = true )
{
EnableCompression( !disable );
}
/*!
* Serializes the normalization data transported by this object as a new
* %XML document in XNML format.
*
* The returned XMLDocument object has been allocated dynamically. The
* caller is responsible for destroying and deallocating it as appropriate.
*/
XMLDocument* Serialize() const;
/*!
* Serializes the normalization data transported by this object as a new
* %XML document file in XNML format (.xnml). The file will be newly created
* at the specified file \a path.
*
* \warning If a file already exists at the specified \a path, its previous
* contents will be lost after calling this function.
*/
void SerializeToFile( const String& path ) const;
private:
String m_referenceFilePath; // path to the normalization reference image
String m_targetFilePath; // path to the normalization target image
int m_scale = -1; // normalization scale in px
int m_referenceWidth = -1; // reference image width in px
int m_referenceHeight = -1; // reference image height in px
normalization_matrices m_A; // scaling coefficients
normalization_matrices m_B; // zero offset coefficients
Vector m_C; // input bias
matrix_interpolations m_UA; // interpolators for m_A
matrix_interpolations m_UB; // interpolators for m_B
Vector m_Rc; // global normalization, reference center
Vector m_Tc; // global normalization, target center
Vector m_S; // global normalization, scale factor
Vector m_relScale; // relative scale factor
double m_sx; // coordinate scaling factor, X axis
double m_sy; // coordinate scaling factor, Y axis
TimePoint m_creationTime;
bool m_compressionEnabled = true;
int m_version = 0;
void ParseNormalizationMatrices( normalization_matrices&, const XMLElement& ) const;
void SerializeNormalizationMatrices( XMLElement*, const normalization_matrices& ) const;
};
// ----------------------------------------------------------------------------
} // pcl
#endif // __PCL_LocalNormalizationData_h
// ----------------------------------------------------------------------------
// EOF pcl/LocalNormalizationData.h - Released 2022-03-12T18:59:29Z