You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
9.9 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageSincInterpolator.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkImageSincInterpolator
* @brief perform sinc interpolation on images
*
* vtkImageSincInterpolator provides various windowed sinc interpolation
* methods for image data. The default is a five-lobed Lanczos interpolant,
* with a kernel size of 6. The interpolator can also bandlimit the image,
* which can be used for antialiasing. The interpolation kernels are
* evaluated via a lookup table for efficiency.
* @par Thanks:
* Thanks to David Gobbi at the Seaman Family MR Centre and Dept. of Clinical
* Neurosciences, Foothills Medical Centre, Calgary, for providing this class.
* @sa
* vtkImageReslice
*/
#ifndef vtkImageSincInterpolator_h
#define vtkImageSincInterpolator_h
#include "vtkAbstractImageInterpolator.h"
#include "vtkImagingCoreModule.h" // For export macro
#define VTK_LANCZOS_WINDOW 0
#define VTK_KAISER_WINDOW 1
#define VTK_COSINE_WINDOW 2
#define VTK_HANN_WINDOW 3
#define VTK_HAMMING_WINDOW 4
#define VTK_BLACKMAN_WINDOW 5
#define VTK_BLACKMAN_HARRIS3 6
#define VTK_BLACKMAN_HARRIS4 7
#define VTK_NUTTALL_WINDOW 8
#define VTK_BLACKMAN_NUTTALL3 9
#define VTK_BLACKMAN_NUTTALL4 10
#define VTK_SINC_KERNEL_SIZE_MAX 32
class vtkImageData;
struct vtkInterpolationInfo;
class VTKIMAGINGCORE_EXPORT vtkImageSincInterpolator : public vtkAbstractImageInterpolator
{
public:
static vtkImageSincInterpolator* New();
vtkTypeMacro(vtkImageSincInterpolator, vtkAbstractImageInterpolator);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@{
/**
* The window function to use. The default is Lanczos, which is very
* popular and performs well with a kernel width of 6. The Cosine
* window is included for historical reasons. All other windows are
* described in AH Nuttall, "Some windows with very good sidelobe
* behavior," IEEE Transactions on Acoustics, Speech, and Signal
* Processing 29:84-91, 1981.
*/
virtual void SetWindowFunction(int mode);
void SetWindowFunctionToLanczos() { this->SetWindowFunction(VTK_LANCZOS_WINDOW); }
void SetWindowFunctionToKaiser() { this->SetWindowFunction(VTK_KAISER_WINDOW); }
void SetWindowFunctionToCosine() { this->SetWindowFunction(VTK_COSINE_WINDOW); }
void SetWindowFunctionToHann() { this->SetWindowFunction(VTK_HANN_WINDOW); }
void SetWindowFunctionToHamming() { this->SetWindowFunction(VTK_HAMMING_WINDOW); }
void SetWindowFunctionToBlackman() { this->SetWindowFunction(VTK_BLACKMAN_WINDOW); }
void SetWindowFunctionToBlackmanHarris3() { this->SetWindowFunction(VTK_BLACKMAN_HARRIS3); }
void SetWindowFunctionToBlackmanHarris4() { this->SetWindowFunction(VTK_BLACKMAN_HARRIS4); }
void SetWindowFunctionToNuttall() { this->SetWindowFunction(VTK_NUTTALL_WINDOW); }
void SetWindowFunctionToBlackmanNuttall3() { this->SetWindowFunction(VTK_BLACKMAN_NUTTALL3); }
void SetWindowFunctionToBlackmanNuttall4() { this->SetWindowFunction(VTK_BLACKMAN_NUTTALL4); }
int GetWindowFunction() { return this->WindowFunction; }
virtual const char* GetWindowFunctionAsString();
//@}
/**
* Set the window half-width, this must be an integer between 1 and 16,
* with a default value of 3. The kernel size will be twice this value
* if no blur factors are applied. The total number of sinc lobes will
* be one less than twice the half-width, so if the half-width is 3 then
* the kernel size will be 6 and there will be 5 sinc lobes.
*/
void SetWindowHalfWidth(int n);
int GetWindowHalfWidth() { return this->WindowHalfWidth; }
/**
* Turn this on in order to use SetWindowParameter. If it is off,
* then the default parameter will be used for the window.
*/
void SetUseWindowParameter(int val);
void UseWindowParameterOn() { this->SetUseWindowParameter(1); }
void UseWindowParameterOff() { this->SetUseWindowParameter(0); }
int GetUseWindowParameter() { return this->UseWindowParameter; }
/**
* Set the alpha parameter for the Kaiser window function.
* This parameter will be ignored unless UseWindowParameter is On.
* If UseWindowParameter is Off, then alpha is set to be the same as n
* where n is the window half-width. Using an alpha less than n
* increases the sharpness and ringing, while using an alpha greater
* than n increases the blurring.
*/
void SetWindowParameter(double parm);
double GetWindowParameter() { return this->WindowParameter; }
/**
* Get the support size for use in computing update extents. If the data
* will be sampled on a regular grid, then pass a matrix describing the
* structured coordinate transformation between the output and the input.
* Otherwise, pass nullptr as the matrix to retrieve the full kernel size.
*/
void ComputeSupportSize(const double matrix[16], int support[3]) override;
//@{
/**
* Blur the image by widening the windowed sinc kernel by the specified
* factors for the x, y, and z directions. This reduces the bandwidth
* by these same factors. If you turn Antialiasing on, then the blur
* factors will be computed automatically from the output sampling rate.
* Blurring increases the computation time because the kernel size
* increases by the blur factor.
*/
void SetBlurFactors(double x, double y, double z);
void SetBlurFactors(const double f[3]) { this->SetBlurFactors(f[0], f[1], f[2]); }
void GetBlurFactors(double f[3])
{
f[0] = this->BlurFactors[0];
f[1] = this->BlurFactors[1];
f[2] = this->BlurFactors[2];
}
double* GetBlurFactors() VTK_SIZEHINT(3) { return this->BlurFactors; }
//@}
/**
* Turn on antialiasing. If antialiasing is on, then the BlurFactors
* will be computed automatically from the output sampling rate such that
* that the image will be bandlimited to the Nyquist frequency. This
* is only applicable when the interpolator is being used by a resampling
* filter like vtkImageReslice. Such a filter will indicate the output
* sampling by calling the interpolator's ComputeSupportSize() method,
* which will compute the blur factors at the same time that it computes
* the support size.
*/
void SetAntialiasing(int antialiasing);
void AntialiasingOn() { this->SetAntialiasing(1); }
void AntialiasingOff() { this->SetAntialiasing(0); }
int GetAntialiasing() { return this->Antialiasing; }
/**
* Turn off renormalization. Most of the sinc windows provide kernels
* for which the weights do not sum to one, and for which the sum depends
* on the offset. This results in small ripple artifacts in the output.
* By default, the vtkImageSincInterpolator will renormalize these kernels.
* This method allows the renormalization to be turned off.
*/
void SetRenormalization(int renormalization);
void RenormalizationOn() { this->SetRenormalization(1); }
void RenormalizationOff() { this->SetRenormalization(0); }
int GetRenormalization() { return this->Renormalization; }
/**
* Returns true if the interpolator supports weight precomputation.
* This will always return true for this interpolator.
*/
bool IsSeparable() override;
//@{
/**
* If the data is going to be sampled on a regular grid, then the
* interpolation weights can be precomputed. A matrix must be
* supplied that provides a transformation between the provided
* extent and the structured coordinates of the input. This
* matrix must perform only permutations, scales, and translation,
* i.e. each of the three columns must have only one non-zero value.
* A new extent is provided for out-of-bounds checks.
* THIS METHOD IS THREAD SAFE.
*/
void PrecomputeWeightsForExtent(const double matrix[16], const int extent[6], int newExtent[6],
vtkInterpolationWeights*& weights) override;
void PrecomputeWeightsForExtent(const float matrix[16], const int extent[6], int newExtent[6],
vtkInterpolationWeights*& weights) override;
//@}
/**
* Free the precomputed weights. THIS METHOD IS THREAD SAFE.
*/
void FreePrecomputedWeights(vtkInterpolationWeights*& weights) override;
protected:
vtkImageSincInterpolator();
~vtkImageSincInterpolator() override;
/**
* Update the interpolator.
*/
void InternalUpdate() override;
/**
* Copy the interpolator.
*/
void InternalDeepCopy(vtkAbstractImageInterpolator* obj) override;
//@{
/**
* Get the interpolation functions.
*/
void GetInterpolationFunc(
void (**doublefunc)(vtkInterpolationInfo*, const double[3], double*)) override;
void GetInterpolationFunc(
void (**floatfunc)(vtkInterpolationInfo*, const float[3], float*)) override;
//@}
//@{
/**
* Get the row interpolation functions.
*/
void GetRowInterpolationFunc(
void (**doublefunc)(vtkInterpolationWeights*, int, int, int, double*, int)) override;
void GetRowInterpolationFunc(
void (**floatfunc)(vtkInterpolationWeights*, int, int, int, float*, int)) override;
//@}
/**
* Build the lookup tables used for the interpolation.
*/
virtual void BuildKernelLookupTable();
/**
* Free the kernel lookup tables.
*/
virtual void FreeKernelLookupTable();
int WindowFunction;
int WindowHalfWidth;
float* KernelLookupTable[3];
int KernelSize[3];
int Antialiasing;
int Renormalization;
double BlurFactors[3];
double LastBlurFactors[3];
double WindowParameter;
int UseWindowParameter;
private:
vtkImageSincInterpolator(const vtkImageSincInterpolator&) = delete;
void operator=(const vtkImageSincInterpolator&) = delete;
};
#endif