15,122,559 members
Articles / Programming Languages / C#
Article
Posted 22 Dec 2010

31.9K views
20 bookmarked

# Hartley Transform of an Image in C#

Rate me:
Implementation of 2D Discrete Hartley Transform of an Image in C#

## 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.

C#
```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)),
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

## Share

 First Prev Next
 My vote of 4 Philip Liebscher14-Aug-13 13:16 Philip Liebscher 14-Aug-13 13:16
 What is the Hartley Transform Good For ? MicroImaging29-Dec-10 8:55 MicroImaging 29-Dec-10 8:55
 I understand that the image is transferred from the 2D space domain into some kind of frequency domain, but what good is this transferrance ? I understand that I can then perform convolutions with simple multiplications, but from my understanding the Conversion from 2D to H Space is NLog(N) then the multiplication of the convolution is going to be N^2 anyway, and the conversion from H space to 2D space will be another NLog(N) operations for a total of N^2+2NLog(N) where as a straight convolution of the same image in 2D space is still only N^2 operations with a bunch of additions. Maybe I am wrong in my order of magnitude analysis ?
 Re: What is the Hartley Transform Good For ? Dr. Vinayak Ashok Bharadi29-Dec-10 19:56 Dr. Vinayak Ashok Bharadi 29-Dec-10 19:56
 Re: What is the Hartley Transform Good For ? Phil Atkin4-Jan-11 0:45 Phil Atkin 4-Jan-11 0:45
 ask for help jinyanmei26-Dec-10 23:21 jinyanmei 26-Dec-10 23:21
 suggestion Pranay Rana23-Dec-10 0:27 Pranay Rana 23-Dec-10 0:27