Linear Methods for Image Interpolation
Data Structures | Defines | Functions | Variables
linterp.c File Reference

Linear interpolation. More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fftw3.h>
#include "basic.h"
#include "linterp.h"
#include "lkernels.h"
Include dependency graph for linterp.c:

Go to the source code of this file.

Data Structures

struct  scalescanfilter

Defines

#define CLAMP(X, A, B)   (((X) < (A)) ? (A) : (((X) > (B)) ? (B) : (X)))
 Clamp X to [A, B].

Functions

int LinInterp2d (float *Dest, const float *Src, int SrcWidth, int SrcHeight, float *X, float *Y, int NumSamples, float(*Kernel)(float), float KernelRadius, int KernelNormalize, boundaryhandling Boundary)
 2D linear interpolation (arbitrary resampling)
int MakeScaleRotationGrid (float **X, float **Y, int *GridWidth, int *GridHeight, int SrcWidth, int SrcHeight, float Scale, float Theta)
 Make a sampling grid for scaling and rotating an image.
int LinScale2d (float *Dest, int DestWidth, float XStart, float XStep, int DestHeight, float YStart, float YStep, const float *Src, int SrcWidth, int SrcHeight, int NumChannels, float(*Kernel)(float), float KernelRadius, int KernelNormalize, boundaryhandling Boundary)
 Scale image with a compact support interpolation kernel.
int FourierScale2d (float *Dest, int DestWidth, float XStart, int DestHeight, float YStart, const float *Src, int SrcWidth, int SrcHeight, int NumChannels, double PsfSigma, boundaryhandling Boundary)
 Scale image with Fourier zero padding.

Variables

int(* ExtensionMethod [3])(int, int)
 Boundary extension methods.

Detailed Description

Linear interpolation.

Author:
Pascal Getreuer <getreuer@gmail.com>

This file implements LinInterp2d for interpolating at arbitrary sample locations with a compactly supported interpolation kernel, LinScale2d for interpolating on a uniform grid of sample locations with a compactly supported interpolation kernel, and FourierScale2d for interpolating on a uniform grid using Fourier interpolation.

Copyright (c) 2010-2011, Pascal Getreuer All rights reserved.

This program is free software: you can use, modify and/or redistribute it under the terms of the simplified BSD License. You should have received a copy of this license along this program. If not, see <http://www.opensource.org/licenses/bsd-license.html>.

Definition in file linterp.c.


Define Documentation

#define CLAMP (   X,
  A,
 
)    (((X) < (A)) ? (A) : (((X) > (B)) ? (B) : (X)))

Clamp X to [A, B].

Definition at line 34 of file linterp.c.


Function Documentation

int FourierScale2d ( float *  Dest,
int  DestWidth,
float  XStart,
int  DestHeight,
float  YStart,
const float *  Src,
int  SrcWidth,
int  SrcHeight,
int  NumChannels,
double  PsfSigma,
boundaryhandling  Boundary 
)

Scale image with Fourier zero padding.

Parameters:
Destpointer to memory for holding the interpolated image
DestWidthoutput image width
XStartleftmost sample location (in input coordinates)
DestHeightoutput image height
YStartuppermost sample location (in input coordinates)
Srcthe input image
SrcWidth,SrcHeight,NumChannelsinput image dimensions
PsfSigmaGaussian PSF standard deviation
Boundaryboundary handling
Returns:
1 on success, 0 on failure.

The image is first mirror folded with half-sample even symmetry to avoid boundary artifacts, then transformed with a real-to-complex DFT.

The interpolation is computed so that Dest[m + DestWidth*n] is the interpolation of Input at sampling location (XStart + m*SrcWidth/DestWidth, YStart + n*SrcHeight/DestHeight) for m = 0, ..., DestWidth - 1, n = 0, ..., DestHeight - 1, where the pixels of Src are located at the integers.

Definition at line 705 of file linterp.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int LinInterp2d ( float *  Dest,
const float *  Src,
int  SrcWidth,
int  SrcHeight,
float *  X,
float *  Y,
int  NumSamples,
float(*)(float)  Kernel,
float  KernelRadius,
int  KernelNormalize,
boundaryhandling  Boundary 
)

2D linear interpolation (arbitrary resampling)

Parameters:
Destpointer to destination array
Srcpointer to source array
SrcWidth,SrcHeightdimensions of the source data
X,Ythe sampling locations
NumSamplesthe number of samples
Kernelthe interpolation kernel to use
KernelRadiusthe radius of support of the kernel
KernelNormalizeif nonzero, weights are normalized to sum to 1
Boundaryboundary handling
Returns:
1 on success, 0 on failure.

This routine implements the computation Dest[k] = sum_m sum_n Src[m,n] Kernel(X[k] - m) Kernel(Y[k] - n), k = 0, ..., NumSamples-1. The source image Src is interpolated at points (X[0],Y[0]), (X[1],Y[1]), ... (X[NumSamples-1],Y[NumSamples-1]). Src should be in row-major order as Src[m + SrcWidth*n] = (m,n)th pixel value, m = 0, ..., SrcWidth-1, n = 0, ..., SrcHeight-1. Dest should have space for at least NumSamples elements. The pixels of Src are logically positioned at the integers with the upper-left corner (Src[0]) corresponding to (0,0). In other words, if X[k] = m and Y[k] = n, then Dest[k] = Src[m + SrcWidth*n]. If (X[k],Y[k]) is outside of [0,SrcWidth-1] x [0,SrcHeight-1], then Src is extrapolated with half-sample even symmetry.

Kernel should be a function with the calling syntax float Kernel(float x). Kernel should be zero (or approximately zero) for |x| >= KernelRadius.

If KernelNormalize is nonzero, the computation includes a normalizing denominator, Dest[k] = 1/Z[k] sum_m sum_n Src[m,n] Kernel(X[k] - m) Kernel(Y[k] - n), where Z[k] is Z[k] = sum_m sum_n Kernel(X[k] - m) Kernel(Y[k] - n). The normalization ensures that the interpolation exactly reproduces constant functions. Normalization is needed for example with the Lanczos kernels, which do not reproduce constants.

This normalization is equivalent to, but more efficient than, applying LinInterp2d with the normalized kernel NormalizedKernel(x) = Kernel(x) / sum_n Kernel(x - n). On the other hand, if Kernel is already normalized, it is slightly more efficient to use KernelNormalize = 0.

Definition at line 146 of file linterp.c.

Here is the caller graph for this function:

int LinScale2d ( float *  Dest,
int  DestWidth,
float  XStart,
float  XStep,
int  DestHeight,
float  YStart,
float  YStep,
const float *  Src,
int  SrcWidth,
int  SrcHeight,
int  NumChannels,
float(*)(float)  Kernel,
float  KernelRadius,
int  KernelNormalize,
boundaryhandling  Boundary 
)

Scale image with a compact support interpolation kernel.

Parameters:
Destpointer to memory for holding the interpolated image
DestWidthwidth of the output image
XStartleftmost sampling location (in input coordinates)
XStepthe length between successive samples (in input coordinates)
DestHeightheight of the output image
YStartuppermost sampling location (in input coordinates)
YStepthe length between successive samples (in input coordinates)
Srcthe input image
SrcWidth,SrcHeight,NumChannelsinput image dimensions
Kernelinterpolation kernel function to use
KernelRadiuskernel support radius
KernelNormalizeif nonzero, filter rows are normalized to sum to 1
Boundaryboundary handling
Returns:
1 on success, 0 on failure.

This is a generic linear interpolation routine to scale an image using any compactly supported interpolation kernel. The kernel is applied separably along both dimensions. Half-sample even symmetric extension is used to handle the boundaries.

The interpolation is computed so that Dest[m + DestWidth*n] is the interpolation of Src at sampling location (XStart + m*XStep, YStart + n*YStep) for m = 0, ..., DestWidth - 1, n = 0, ..., DestHeight - 1, where the pixels of Src are located at the integers.

The implementation follows the approach taken in ffmpeg's swscale library. First a "scanline filter" is constructed, a sparse matrix such that multiplying with a row of the input image produces an interpolated row in the output image. Similarly a second matrix is constructed for interpolating columns. The interpolation itself is then essentially two sparse matrix times dense matrix multiplies.

Definition at line 463 of file linterp.c.

Here is the caller graph for this function:

int MakeScaleRotationGrid ( float **  X,
float **  Y,
int *  GridWidth,
int *  GridHeight,
int  SrcWidth,
int  SrcHeight,
float  Scale,
float  Theta 
)

Make a sampling grid for scaling and rotating an image.

Parameters:
X,Yarray of sample locations
GridWidth,GridHeightthe dimensions of the sampling grid
SrcWidth,SrcHeightthe size of the source image
Scalethe scale factor (> 1 for finer resolution)
Thetarotation angle (counter clockwise)
Returns:
1 on success, 0 on failure.

This routine creates sampling locations (X[0],Y[0]), (X[1],Y[1]), ... (X[N-1],Y[N-1]), where the number of samples is N = GridWidth*GridHeight, such that interpolating the source image at these locations produces an scaled and rotated version of the image of size GridWidth by GridHeight.

The memory for X and Y is allocated by this routine. It is the responsibility of the caller to call Free(X), Free(Y) to release this memory when done.

Definition at line 252 of file linterp.c.

Here is the caller graph for this function:


Variable Documentation

int(* ExtensionMethod[3])(int, int)
Initial value:
    {ConstExtension, HSymExtension, WSymExtension}

Boundary extension methods.

Definition at line 95 of file linterp.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines