Click here to Skip to main content
15,891,657 members
Articles / Programming Languages / C#

Discrete Haar Wavelet Transformation

Rate me:
Please Sign up or sign in to vote.
4.87/5 (32 votes)
25 Apr 2014CPOL2 min read 134.6K   11.6K   42   54
Simple application for calculating 2D Haar wavelet on images.
Image 1

Background

Haar wavelet - Wikipedia

Discrete wavelet transform - Wikipedia

The first DWT was invented by the Hungarian mathematician Alfréd Haar. For an input represented by a list of 2n numbers, the Haar wavelet transform may be considered to simply pair up input values, storing the difference and passing the sum. This process is repeated recursively, pairing up the sums to provide the next scale: finally resulting in 2n-1 differences and one final sum.

Suppose you are given N values

x = (x1, x2, … xN)

where N is even.

We take pair-wise average of numbers

sk = (x2k + x2k+1)/2 for k=0, …, N/2 -1

For example,

x = (6, 12, 15, 15, 14, 12, 120, 116) -> s = (9, 15, 13, 118)

We need second list of data d so that the original list x can be recovered from s and d.

For dk (called directed distances), we have:

dk = (x2k - x2k+1)/2 for k=0, …, N/2 -1

The process is invertible since:

sk + dk = (x2k + x2k+1)/2 + (x2k - x2k+1)/2 = x2k

sk - dk = (x2k + x2k+1)/2 - (x2k - x2k+1)/2 = x2k+1

So we map x = (x1, x2, … , xN) to (s | d) = (s1, … , sN/2 | d1, … , dN/2).

Using our example values, we have:

(6, 12, 15, 15, 14, 12, 120, 116) -> (9, 15, 13, 118 | -3, 0, 1, 2)

This process is repeated recursively for s:

(9, 15, 13, 118 | -3, 0, 1, 2) -> (12, 65.5 | -3, -52.5 | -3, 0, 1, 2)

(12, 65.5 | -3, -52.5 | -3, 0, 1, 2) -> (38.75 | -26.75 | -3, -52.5 | -3, 0, 1, 2)

So final result is:

(38.75, -26.75, -3, -52.5, -3, 0, 1, 2)

Why might people prefer the data in this form?

  • We can identify large changes in the differences portion d of the transform.
  • It is easier to quantize the data in this form.
  • The transform concentrates the information (energy) in the signal in fewer values.
  • And the obvious answer: fewer digits!!

In case of images, we need 2D FWT. First, we perform 1D FWT for all rows, and next, for all columns. For color Images, we deal with RGB components of color, and perform Haar Transform for each component separately. Any component (R G B) has values from 0 to 255 to before transformation we scale this values. For displaying image after transformation, we scale back transformed values.

Here, we process image with C# in safe and unsafe manners and of course the second way is much faster.

Using the Code

1D Discrete Haar Wavelet Transform (one iteration):

C#
public void FWT(double[] data)
{
    double[] temp = new double[data.Length];

    int h = data.Length >> 1;
    for (int i = 0; i < h; i++)
    {
        int k = (i << 1);
        temp[i] = data[k] * s0 + data[k + 1] * s1;
        temp[i + h] = data[k] * w0 + data[k + 1] * w1;
    }

    for (int i = 0; i < data.Length; i++)
        data[i] = temp[i];
}

2D Discrete Haar Wavelet Transform:

C#
public void FWT(double[,] data, int iterations)
{
    int rows = data.GetLength(0);
    int cols = data.GetLength(1);

    double[] row;
    double[] col;

    for (int k = 0; k < iterations; k++)
    {
        int lev = 1 << k;

        int levCols = cols / lev;
        int levRows = rows / lev;

        row = new double[levCols];
        for (int i = 0; i < levRows; i++)
        {
            for (int j = 0; j < row.Length; j++)
                row[j] = data[i, j];

            FWT(row);

            for (int j = 0; j < row.Length; j++)
                data[i, j] = row[j];
        }


        col = new double[levRows];
        for (int j = 0; j < levCols; j++)
        {
            for (int i = 0; i < col.Length; i++)
                col[i] = data[i, j];

            FWT(col);

            for (int i = 0; i < col.Length; i++)
                data[i, j] = col[i];
        }
    }
}

1D Inverse Discrete Haar Wavelet Transform (one iteration):

C#
public void IWT(double[] data)
{
    double[] temp = new double[data.Length];

    int h = data.Length >> 1;
    for (int i = 0; i < h; i++)
    {
        int k = (i << 1);
        temp[k] = (data[i] * s0 + data[i + h] * w0) / w0;
        temp[k + 1] = (data[i] * s1 + data[i + h] * w1) / s0;
    }

    for (int i = 0; i < data.Length; i++)
        data[i] = temp[i];
}

2D Inverse Discrete Haar Wavelet Transform:

C#
public void IWT(double[,] data, int iterations)
{
    int rows = data.GetLength(0);
    int cols = data.GetLength(1);

    double[] col;
    double[] row;

    for (int k = iterations - 1; k >= 0; k--)
    {
        int lev = 1 << k;

        int levCols = cols / lev;
        int levRows = rows / lev;

        col = new double[levRows];
        for (int j = 0; j < levCols; j++)
        {
            for (int i = 0; i < col.Length; i++)
                col[i] = data[i, j];

            IWT(col);

            for (int i = 0; i < col.Length; i++)
                data[i, j] = col[i];
        }

        row = new double[levCols];
        for (int i = 0; i < levRows; i++)
        {
            for (int j = 0; j < row.Length; j++)
                row[j] = data[i, j];

            IWT(row);

            for (int j = 0; j < row.Length; j++)
                data[i, j] = row[j];
        }
    }
}

Example Images

Original Image Zelda 512x512:

Image 2

Transformed Image (1 Iteration):

Image 3

Transformed Image (2 Iterations):

Image 4

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Seven Smarts
Armenia Armenia
.Net developer

Comments and Discussions

 
GeneralRe: Python version Pin
Member 1437708218-May-19 5:19
Member 1437708218-May-19 5:19 
QuestionHow to find co-efficeint in har wavelet Pin
Member 1119219329-Oct-14 23:36
Member 1119219329-Oct-14 23:36 
AnswerRe: How to find co-efficeint in har wavelet Pin
Hovhannes Bantikyan8-Nov-14 7:17
Hovhannes Bantikyan8-Nov-14 7:17 
QuestionThank you. Pin
Member 1119219329-Oct-14 23:35
Member 1119219329-Oct-14 23:35 
AnswerRe: Thank you. Pin
Hovhannes Bantikyan8-Nov-14 7:18
Hovhannes Bantikyan8-Nov-14 7:18 
GeneralThankfulness Pin
Member 1110859614-Oct-14 1:45
Member 1110859614-Oct-14 1:45 
GeneralRe: Thankfulness Pin
Hovhannes Bantikyan8-Nov-14 7:18
Hovhannes Bantikyan8-Nov-14 7:18 
QuestionHaar Wavelet definition? Pin
Mike Rosen1-Oct-14 10:00
Mike Rosen1-Oct-14 10:00 
thank you for this very accessible demonstration of using the Haar Wavelete in image processing.

I'm a little confused when I compare the results here to the results I see posted elsewhere on the internet.

The example you give of a single level, 1 dimensional transform takes this input:
{6, 12, 15, 15, 14, 12, 120, 116}

And gives these coefficients: (38.75, -26.75, -3, -52.5, -3, 0, 1, 2)

Compare that to what I see when I do the same transform in Mathematica:
dwd = DiscreteWaveletTransform[ {6, 12, 15, 15, 14, 12, 120, 116},
HaarWavelet[], 1]
dwd[All]
{{0} -> {12.7279, 21.2132, 18.3848, 166.877}, {1} -> {-4.24264, 0.,
1.41421, 2.82843}}

Can you offer any insight into the discrepancy?

Thanks,

Mike Rosen
QuestionConvert this program to C language Pin
bangdinh25-May-14 5:41
bangdinh25-May-14 5:41 
AnswerRe: Convert this program to C language Pin
Hovhannes Bantikyan29-Jun-14 2:29
Hovhannes Bantikyan29-Jun-14 2:29 
GeneralMy vote of 5 Pin
Volynsky Alex25-Apr-14 23:35
professionalVolynsky Alex25-Apr-14 23:35 
QuestionProblem in Unzip Pin
mohammadimm14-Apr-14 7:58
professionalmohammadimm14-Apr-14 7:58 
AnswerRe: Problem in Unzip Pin
Hovhannes Bantikyan25-Apr-14 3:22
Hovhannes Bantikyan25-Apr-14 3:22 
QuestionProblem with the zip file Pin
Mo DeJong22-Mar-14 10:04
Mo DeJong22-Mar-14 10:04 
AnswerRe: Problem with the zip file Pin
Eugene Cher24-Mar-14 1:16
Eugene Cher24-Mar-14 1:16 
AnswerRe: Problem with the zip file Pin
Hovhannes Bantikyan25-Apr-14 3:23
Hovhannes Bantikyan25-Apr-14 3:23 
Generalhelp plz ^^ Pin
Drokozzivic Samir14-Mar-14 6:55
Drokozzivic Samir14-Mar-14 6:55 
Questions0, s1, w0 and w1 Pin
GillesMoy12-Mar-14 4:58
GillesMoy12-Mar-14 4:58 
AnswerRe: s0, s1, w0 and w1 Pin
Hovhannes Bantikyan13-Mar-14 11:05
Hovhannes Bantikyan13-Mar-14 11:05 
GeneralRe: s0, s1, w0 and w1 Pin
GillesMoy13-Mar-14 23:09
GillesMoy13-Mar-14 23:09 
AnswerRe: s0, s1, w0 and w1 Pin
Drokozzivic Samir14-Mar-14 7:20
Drokozzivic Samir14-Mar-14 7:20 
QuestionA Problem!! Pin
AmirHossein.M.Ojvar5-Dec-13 2:02
AmirHossein.M.Ojvar5-Dec-13 2:02 
AnswerRe: A Problem!! Pin
Hovhannes Bantikyan15-Mar-14 9:22
Hovhannes Bantikyan15-Mar-14 9:22 
AnswerRe: A Problem!! Pin
Matty2222-Jul-14 1:57
Matty2222-Jul-14 1:57 
AnswerRe: A Problem!! Pin
elahe khorasani1-May-15 9:59
elahe khorasani1-May-15 9:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.