Introduction

One of annoying distortions of down-scaling is aliasing impairments. It’s a common practice to apply an anti-aliasing filter prior to down-scaling process.  Generally speaking the anti-aliasing filter is a low pass filter usually used before a signal sampler in order to reduce the signal frequency bandwidth and approximately to satisfy the Nyquist Sampling theorem. 

A good approximation of an ideal low pass filter (known as the windowed sinc approach): 

F(n) represents the n-th filter coefficient

ωco is the cutoff frequency in radians. The cutoff frequency ωco is chosen according to the scaling factor R and equal to π/R. For example, the down scaling by 2 requires a theoretical cutoff frequency of ωco = π/2

W(n) is a windows function (e.g. Hamming, Blackman, Lanczos) used for truncating the sync infinite frequency response. 

Hamming window for 0..N-1 coefficients:  

Note:

Because the anti-aliasing filter is applied on 2D image the scale factors for horizontal and vertical scaling can be different.

 

Proposed Implementation of Anti-Aliasing Filter

The anti-aliasing filter has to be applied prior to a down-scaling. 

The anti-aliasing filter is two-stages filter:  horizontal filtering is applied followed by the vertical one (or vice versa). 

I suggest using the anti-aliasing filter as 15-tap symmetrical FIR filter. Due to the symmetry only 8 coefficients needed to be specified (each of 13-bits signed, in units of 1/2048):

 

C6  C5  C4  C3  C2  C1  C0   MiddleTap   C0  C1  C2  C3  C4  C5  C6

 

The coefficient values are in units of 1/2048. The sum of the coefficients should be 2048.  The anti-aliasing coefficients are configured and can be adjusted according to video content. 

The anti-aliasing filter should be necessary applied on luma pixels. As per chroma pixels it’s possible to omit the anti-aliasing filtering due to a limited sensitivity of Human Eye to chrominance. Anyway, an option to apply anti-aliasing to both luma and chroma should be supported. 

Calculation of Coefficients

N=15, for scaling factor R and Hamming window, the coefficients n=0..14:

For example, the middle tap h7= 1/R

The next step is to convert the coefficients to units of 1/2048 as follows:

h’n=round(hn*2048)

 

The coefficients h’n are further normalized to be sure that the sum of all coefficients equal to 2048:

 

Formula A:

 

Outline of Code

Input: 

SrcImage – source image (luma or chroma) or already horizontally scaled image

SrcWidth – the width of the source image in pixels

SrcHeight – the height of the source image in pixels

DstWidth – the width of the destination image in pixels

DstHeight – the height of the destination image in pixels

Pass     –     0 – horizontal pass (the first pass), 1 – vertical pass

Coeffs –    the array  [MiddleTap   C0  C1  C2  C3  C4  C5  C6], notice that the scale factor R already involved in the calculation of coefficients. 

 

Output:

DstImage

Algorithm

 

Stage 0: Mirroring 

Input source image should be mirrored (pixels are mirrored outside picture boundaries) before application of the anti-aliasing filter. Actually the source image is extended by 8-pixels in each direction.

The input to this stage is the original image OrigImage and the output is the extended image ExtSrcImage.

 

Allocate extended image ExtSrcImage as (SrcWidth+16)x(SrcHeight+16) matrix.

// horizontal mirroring

for row=0 .. SrcHeight -1

{

     for i=0 .. 7   // left mirroring

         // ‘row+8’ is a room for vertical mirroring

        ExtSrcImage [row+8, 7-i] = OrigImage[row, i]  

     // copy

     For i=0.. SrcWidth 

    ExtSrcImage [row+8, 8+i] = OrigImage[row, i]

     

    for i=0 .. 7   // right mirroring

         // ‘row+8’ is a room for vertical mirroring

        ExtSrcImage [row+8, SrcWidth+i] = OrigImage[row, SrcWidth-i-1]  

} // end horizontal mirroring

// vertical mirroring

for col=0 .. SrcWidth -1

{

     for i=0 .. 7   // top mirroring

        ExtSrcImage [7-i, col] = OrigImage[i, col]  

     

    for i=0 .. 7   // bottom mirroring

        ExtSrcImage [SrcHeight+i,col] = OrigImage[SrcHeight-i-1,col]  

}

 

Stage 1: 

 

If horizontal scaling factor Rh is not 1 then 

    Compute filter coefficients according to the formula A 

     Apply the filtering horizontally on luma image

       

If vertical scaling Rv is not 1 then  

    Compute filter coefficients according to the formula A

    Apply the filtering vertically on luma image

         

 

14 Responses

  1. Very nice post. I just stumbled upon your weblog and wished to say that I have really enjoyed surfing around your blog posts. In any case I’ll be subscribing to your feed and I hope you write again very soon!

  2. A person essentially lend a hand to make significantly posts I’d state. This is the very first time I frequented your website page and thus far? I surprised with the analysis you made to make this actual publish extraordinary. Wonderful task!

  3. Pretty portion of content. I just stumbled upon your web site and in accession capital
    to assert that I get in fact enjoyed account your blog posts.
    Anyway I will be subscribing for your augment or even I fulfillment you
    access consistently rapidly.

Leave a Reply

Your email address will not be published. Required fields are marked *