Click here to Skip to main content
Licence CPOL
First Posted 22 Dec 2010
Views 7,217
Downloads 280
Bookmarked 18 times

Hartley Transform of an Image in C#

By | 22 Dec 2010 | Article
Implementation of 2D Discrete Hartley Transform of an Image in C#

FHT-small.png

Background

This article discusses an application of 2D Hartley transform of Image analysis in frequency domain. You can use this code for 2D Discreet Hartley transform on matrices or images.

Using the Code

I am using ALGLIB (www.alglib.net) for evaluating 1D Hartley transform. This function is used to evaluate 2D FHT.

private double[,] FHT2DForward(double[,] c, int nx, int ny)
{
    int i, j;
    int m;//Power of 2 for current number of points
    double[] real;
    double[,] output;
    output = c; // Copying Array
    // Transform the Rows 
    real = new double[nx];
    for (j = 0; j < ny; j++)
    {
for (i = 0; i < nx; i++)
{
    real[i] = c[i, j];
}
// Calling 1D FFT Function for Rows
//Finding power of 2 for current number of points e.g. for nx=512 m=9
m = (int)System.Math.Log((double)nx, 2);
fht.fhtr1d(ref real, nx);
for (i = 0; i < nx; i++)
{
    output[i, j] = real[i];
}
    }
    // Transform the columns  
    real = new double[ny];
    for (i = 0; i < nx; i++)
    {
for (j = 0; j < ny; j++)
{
    real[j] = output[i, j];
}
// Calling 1D FFT Function for Columns
//Finding power of 2 for current number of points e.g. for nx=512 m=9
m = (int)System.Math.Log((double)ny, 2);
fht.fhtr1d(ref real, ny);
for (j = 0; j < ny; j++)
{
    output[i, j] = real[j];

}
    }
    // return(true);
    return (output);
}

private double[,] FHT2DInverse(double[,] c, int nx, int ny)
{
    int i, j;
    int m;//Power of 2 for current number of points
    double[] real;
    double[,] output;
    output = c; // Copying Array
    // Transform the Rows 
    real = new double[nx];
    for (j = 0; j < ny; j++)
    {
for (i = 0; i < nx; i++)
{
    real[i] = c[i, j];
}
// Calling 1D FFT Function for Rows
//Finding power of 2 for current number of points e.g. for nx=512 m=9
m = (int)System.Math.Log((double)nx, 2);
fht.fhtr1dinv(ref real, nx);
for (i = 0; i < nx; i++)
{
    //  c[i,j].real = real[i];
    //  c[i,j].imag = imag[i];
    output[i, j] = real[i];
}
    }
    // Transform the columns  
    real = new double[ny];
    for (i = 0; i < nx; i++)
    {
for (j = 0; j < ny; j++)
{
    //real[j] = c[i,j].real;
    //imag[j] = c[i,j].imag;
    real[j] = output[i, j];
}
// Calling 1D FFT Function for Columns
//Finding power of 2 for current number of points e.g. for nx=512 m=9
m = (int)System.Math.Log((double)ny, 2);

fht.fhtr1dinv(ref real, ny);
for (j = 0; j < ny; j++)
{
    //c[i,j].real = real[j];
    //c[i,j].imag = imag[j];
    output[i, j] = real[j];
}
    }
    // return(true);
    return (output);
}

private Bitmap Displaymap(int[,] output)
{
    int i, j;
    Bitmap image = new Bitmap(output.GetLength(0), output.GetLength(1));
    BitmapData bitmapData1 = image.LockBits(new Rectangle(0, 0, output.GetLength(0),
     output.GetLength(1)),
     ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    unsafe
    {
byte* imagePointer1 = (byte*)bitmapData1.Scan0;
for (i = 0; i < bitmapData1.Height; i++)
{
    for (j = 0; j < bitmapData1.Width; j++)
    {
if (output[j, i] < 0)
{
    // Changing to Red Color
    // Changing to Green Color
    imagePointer1[0] = 0; //(byte)output[j, i];
    imagePointer1[1] = 255;
    imagePointer1[2] = 0; //(byte)output[j, i];
}
else if ((output[j, i] >= 0) && (output[j, i] < 50))
{   // Changing to Green Color
    imagePointer1[0] = (byte)((output[j, i]) * 4);  //(byte)output[j, i];
    imagePointer1[1] = 0;
    imagePointer1[2] = 0;// 0; //(byte)output[j, i];
}
else if ((output[j, i] >= 50) && (output[j, i] < 100))
{
    imagePointer1[0] = 0;//(byte)(-output[j, i]);
    imagePointer1[1] = (byte)(output[j, i] * 2);// (byte)(output[j, i]);
    imagePointer1[2] = (byte)(output[j, i] * 2);
}
else if ((output[j, i] >= 100) && (output[j, i] < 150))
{   // Changing to Green Color
    imagePointer1[0] = (byte)((output[j, i]) * 0.7);  //(byte)output[j, i];
    imagePointer1[1] = 0;// (byte)(output[j, i]);// (byte)(output[j, i]);
    imagePointer1[2] = (byte)((output[j, i]) * 0.7);   //(byte)output[j, i];
}
else if ((output[j, i] >= 150) && (output[j, i] < 255))
{   // Changing to Green Color
    imagePointer1[0] = 0;
    imagePointer1[1] = (byte)((output[j, i]) * 0.7);
    imagePointer1[2] = 0;
}

else if ((output[j, i] > 255))
{   // Changing to Green Color
    imagePointer1[0] = 0;   //(byte)output[j, i];
    imagePointer1[1] = 0; //(byte)(output[j, i]);
    imagePointer1[2] = (byte)((output[j, i]) * 0.7);
}
imagePointer1[3] = 255;
//4 bytes per pixel
imagePointer1 += 4;
    }//end for j
    //4 bytes per pixel
    imagePointer1 += (bitmapData1.Stride - (bitmapData1.Width * 4));
}//end for i
    }//end unsafe
    image.UnlockBits(bitmapData1);
    return image;// col;
}

Points of Interest

For details of the FHT you can refer to the links below:

Thanks

Thanks to the ALGLIB Project. I have just added one small level to that. All credit goes to them.

In mathematics, the Hartley transform is an integral transform closely related to the Fourier transform, but which transforms real-valued functions to real-valued functions. It was proposed as an alternative to the Fourier transform by R. V. L. Hartley in 1942, and is one of many known Fourier-related transforms. Compared to the Fourier transform, the Hartley transform has the advantages of transforming real functions to real functions (as opposed to requiring complex numbers) and of being its own inverse.

The discrete version of the transform, the Discrete Hartley transform, was introduced by R. N. Bracewell in 1983.

The two-dimensional Hartley transform can be computed by an analog optical process similar to an optical Fourier transform, with the proposed advantage that only its amplitude and sign need to be determined rather than its complex phase (Villasenor, 1994). However, optical Hartley transforms do not seem to have seen widespread use.

History

  • 22nd December, 2010: Initial post

License

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

About the Author

Dr. Vinayak Ashok Bharadi

Instructor / Trainer
Thakur College of Engineering Technology
India India

Member

I have completed PhD in Engineering from NMIMS University in DEC 2012, M E Electronics & telecommunications in Nov 2007. .
 
I am working on Multimodal Biometrics Technology My rsearch guide is Respected Dr. H B Kekre. (Prof MPSTME).

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionWhat is the Hartley Transform Good For ? PinmemberMicroImaging7:55 29 Dec '10  
AnswerRe: What is the Hartley Transform Good For ? PinmemberVinayak Bharadi18:56 29 Dec '10  
AnswerRe: What is the Hartley Transform Good For ? PinmemberPhil Atkin23:45 3 Jan '11  
Questionask for help Pinmemberjinyanmei22:21 26 Dec '10  
Generalsuggestion PinmemberPranay Rana23:27 22 Dec '10  
GeneralMy vote of 5 Pinmemberprasad024:23 22 Dec '10  

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

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 22 Dec 2010
Article Copyright 2010 by Dr. Vinayak Ashok Bharadi
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid