Parent Topic: Theory

Resampling

Resampling is a process that involves the extraction and interpolation of grey levels from pixel locations in the original uncorrected image. There are several methods of interpolation which can be applied: nearest neighbour, bilinear interpolation, cubic convolution, 8 point Sin(x)/x, and 16 point Sin(x)/x.

During bilinear interpolation, cubic convolution and sin(x)/x, the last pixel and/or scanline will be reused to produce the grey level values for the georeferenced image if the uncorrected pixel window used to calculate the corrected matrix grey level value falls outside the bounds of the uncorrected image at its corner edges. This reuse of pixel values can have the effect of producing image edges which are darker or lighter than the interior of the image.

In GCPWorks, the Resampling type can be set in the ``Disk to Disk Registration'', or the ``Pre-registration Checking'' panel.

See Also: Pre-Registration Checking, Disk to Disk Registration

Nearest Neighbour
Nearest neighbour interpolation determines the grey level from the closest pixel to the specified input coordinates, and assigns that value to the output coordinates. This method is considered the most efficient in terms of computation time. Because it does not alter the grey level value, a nearest neighbour interpolation is preferred if subtle variations in the grey levels need to be retained, if classification will follow the registration, or if a classified image is to be resampled.

Nearest neighbour interpolation introduces a small error into the newly registered image. The image may be offset spatially by up to 1/2 a pixel, causing a jagged or blocky appearance if there is much rotation or scale change.

Bilinear Interpolation
Bilinear interpolation determines the grey level from the weighted average of the four closest pixels to the specified input coordinates, and assigns that value to the output coordinates. This method generates an image of smoother appearance that nearest neighbour, but the grey level values are altered in the process, resulting in blurring or loss of image resolution. Because of these changes in the grey level values, any image classification processes should be performed before the interpolation. Bilinear interpolation requires 3 to 4 times the computation time of the nearest neighbour method.

Cubic Convolution
Cubic convolution determines the grey level from the weighted average of the 16 closest pixels to the specified input coordinates, and assigns that value to the output coordinates. This method is closer to the perfect sin(x)/x resampler than nearest neighbour or bilinear interpolation. The image is slightly sharper than that produced by bilinear interpolation, and it does not have the disjointed appearance produced by nearest neighbour interpolation. Because the grey level values are altered by this method, any image classification processes should be performed before the interpolation. Cubic convolution requires about 10 times the computation time required by the nearest neighbour method.

Sin(x)/x 8pt and 16pt
8pt determines the grey level from the weighted average of the 64 closest pixels to the specified input coordinates and assigns the value to the output coordinates. 16pt does the same, using the 256 closest pixels. The image is sharper than that produced by bilinear interpolation, and it does not have the disjointed appearance produced by nearest neighbour interpolation. Because the grey level values are altered by this method, any image classification processes should be performed before the interpolation. Sin(x)/x with an 8 x 8 window requires about 20 to 40 times the computation time required by the nearest neighbour method. Sin(x)/x with a 16 x 16 window requires 40 to 80 times the computation time required by the nearest neighbour method.

Resampling Example
All the different types of resampling have the following in common:

1. For a given pixel and scanline, transform from the CENTRE of the pixel and scanline. For example, for output pixel 10, scanline 13, transform from the centre (i.e. pixel 9.5, line 12.5). For this discussion, output pixel 9.5, line 12.5 gets transformed to input pixel 0.7, line 1.2.

2. Round up the resulting decimal transformed pixel, line by 1/2 an input pixel and 1/2 an input scanline.

 Rounded transformed pixel = 0.7 + 0.5 = 1.2
 Rounded transformed line  = 1.2 + 0.5 = 1.7
3. Drop the fractional part from the rounded pixel, line from step 2 to determine the input pixel, scanline. This pixel, scanline will be be noted as "X" in the following diagrams.

 Truncated integer pixel   = 1
 Truncated integer line    = 1
4. If the truncated pixel, line from Step 3 is outside the input image dimensions no further processing is required for the output pixel, so go back to Step 1 to process the next pixel of the output scanline.

If the truncated pixel, scanline from Step 3 lies within the input image, continue on to Step 5 for further processing.

5. Save the fractional part of the rounded pixel, line as the "distances":

 Xdistance = (Rounded transformed pixel from Step 2) -
             (Truncated integer   pixel from Step 3)
           = 1.2 - 1 = 0.2

 Ydistance = (Rounded transformed line  from Step 2) -
             (Truncated integer   line  from Step 3)
           = 1.7 - 1 = 0.7
These distances will be in the range of 0.0 to less than +1.0. (A distance +1.0 or more would have selected an adjacent pixel and/or scanline.)

6. Read the input scanline and as many adjacent scanlines as required by the size of the resampling kernel, if they have not been read already and are residing in memory. If the adjacent scanlines are outside the bounds of the input image reuse the most appropriate pixels and/or scanlines. For example for Cubic Convolution resampling (a 4 x 4 resampling kernel)

     -1   0   1   2
    +---+---+---+---+
 -1 |   |   |   |   |
    +---+---+---+---+
  0 |   | X |   |   |
    +---+---+---+---+
  1 |   |   |   |   |
    +---+---+---+---+
  2 |   |   |   |   |
    +---+---+---+---+
for input pixel 1, line 1 (from Step 3), scanline 1 would be used for row 0 of the resampling kernel and reused for row -1. Row 1 of the resampling kernel would use input scanline 2. Row 2 of the resampling kernel would use input scanline 3.

As the pixels in column -1 are outside the image, the pixels from column 0 are reused for column -1.

The effect of reusing pixels and/or scanlines at the edges may show as a darkening (or lightening) of the output imagery at those columns and/or scanlines. Effectively it is giving a stronger weighting to those grey-levels in the resampling kernel.

NOTE: In the following descriptions the resampling is shown as a function. In the actual code, these functions are not used but are coded in an expanded form.

REFERENCE: John A. Richards, 1986: "Remote Sensing Digital Image Analysis, An Introduction", New York, Springer-Verlag, pages 52-55.


Nearest Neighbour
Resampling kernel (k) has the dimensions 1 pixel by 1 scanline.

      0  
    +---+
  0 | X |
    +---+
Process for the resample window:

 output = NearestNeighbour( k[0,0] )
Where the resampling function is:

 NearestNeighbour( f0 ) 
 {
   return( f0 );
 }

Bilinear Interpolation
Resampling kernel (k) has the dimensions of 2 pixels by 2 scanlines.

      0   1  
    +---+---+
  0 | X |   |
    +---+---+
  1 |   |   |
    +---+---+
Process for the resample window:

  row[0] = BilinearInterpolation( (1.0 - Xdistance), k[0,0],
                                   Xdistance       , k[0,1] )
  row[1] = BilinearInterpolation( (1.0 - Xdistance), k[1,0],
                                   Xdistance       , k[1,1] )
  output = BilinearInterpolation( (1.0 - Ydistance), row[0],
                                   Ydistance       , row[1] )
Where the resampling function is:

 BilinearInterpolation( distance0, f0, distance1, f1 ) 
 {
   return(  f0 * distance0
          + f1 * distance1 );
 }

Cubic Convolution
Resampling kernel (k) has the dimensions of 4 pixels by 4 scanlines.

     -1   0   1   2
    +---+---+---+---+
 -1 |   |   |   |   |
    +---+---+---+---+
  0 |   | X |   |   |
    +---+---+---+---+
  1 |   |   |   |   |
    +---+---+---+---+
  2 |   |   |   |   |
    +---+---+---+---+
Process for the resample window:

  row[-1] = CubicConvolution(Xdistance,k[-1,-1],k[-1,0],k[-1,1],k[-1,2])
  row[ 0] = CubicConvolution(Xdistance,k[ 0,-1],k[ 0,0],k[ 0,1],k[ 0,2])
  row[ 1] = CubicConvolution(Xdistance,k[ 1,-1],k[ 1,0],k[ 1,1],k[ 1,2])
  row[ 2] = CubicConvolution(Xdistance,k[ 2,-1],k[ 2,0],k[ 2,1],k[ 2,2])
  output  = CubicConvolution(Ydistance,row[-1],row[ 0],row[ 1],row[ 2])
Where the resampling function is:

CubicConvolution( distance, f0, f1, f2, f3 ) 
{
  return(  (   -f0 +     f1 - f2 + f3) * distance**3
         + (2.0*f0 - 2.0*f1 + f2 - f3) * distance**2
         + (   -f0          + f2     ) * distance**1
         +               f1                         );
}
NOTE: A distance of 0.0 would zero the distance**3, distance**2 and distance**1 terms, in which case f1 would be returned as is.


Parent Topic: Theory
About PCI Help Gateway