<a id="easyimage-fourier-transform"></a>

# Fourier Transform

<a id="easyimage-fourier-transform-basics"></a>

## Basics

The Fourier transform consists in representing an image by its frequential components. You can then process the frequential components image (also called the Fourier image) to perform specific filtering.

![image](assets/images/easyimage/fourier_transform.webp)

Use the [`EFourierTransformer`](../../../doxygen_cpp/classeVision_1_1EFourierTransformer.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierTransformer.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierTransformer.html) class to perform the transformation between a spatial and a Fourier image. The Fourier image contains complex numbers and is represented by a floating point image ([`EFourierImage`](../../../doxygen_cpp/classeVision_1_1EFourierImage.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierImage.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierImage.html)).

* Use the method [`EFourierTransformer::DirectTransform`](../../../doxygen_cpp/classeVision_1_1EFourierTransformer.html#ab4e067777aa90e7b3cb0bb86b136113c) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierTransformer.html#a01865db59f93ed9ea8ad599fc87d6105) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierTransformer.html#aa0e9f3c3ca34d69f2a8c698ce022620d) to convert a spatial image to an [`EFourierImage`](../../../doxygen_cpp/classeVision_1_1EFourierImage.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierImage.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierImage.html).
* Use the method [`EFourierTransformer::InverseTransform`](../../../doxygen_cpp/classeVision_1_1EFourierTransformer.html#a3f1e83bdc1eba1dfbc7fde487432844d) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierTransformer.html#ac7f14ccf7998295b23424eb41a9224f5) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierTransformer.html#aaaac9928520db749a2ee274dc68382cc) to convert images the other way around.

#### HINT
An [`EFourierImage`](../../../doxygen_cpp/classeVision_1_1EFourierImage.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierImage.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierImage.html) may contain high values due to the nature of the applied transformation and this may be difficult to display on a screen. For an easier visualization, use [`EFourierImage::ComputeMagnitude`](../../../doxygen_cpp/classeVision_1_1EFourierImage.html#a7f23a695c126620b0fb050717539a699) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierImage.html#a7a9f67e0361235346ebb60cfc5cb8f64) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierImage.html#a7f3e78abd6cf525741f390326948b2a2) and [`EFourierImage::ComputePhase`](../../../doxygen_cpp/classeVision_1_1EFourierImage.html#afaa73ba8ab88712ab3b87cc806da6f5b) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierImage.html#a7be152aff7859482ed6b8fa22e83a696) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierImage.html#ada5295fce6fef2d3a0c5c3d30587d370) to generate an image that can be drawn or saved.

<a id="easyimage-fourier-transform-format"></a>

## Frequential Format

As the Fourier images contain redundant data, there are different possible representations:  ***Packed*** and  ***Complex Extended*** formats. The format is set and used when calling the methods of [`EFourierTransformer`](../../../doxygen_cpp/classeVision_1_1EFourierTransformer.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierTransformer.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierTransformer.html). The format of the [`EFourierImage`](../../../doxygen_cpp/classeVision_1_1EFourierImage.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierImage.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierImage.html) can be get and set using [`EFourierImage::GetFrequentialDomainFormat`](../../../doxygen_cpp/classeVision_1_1EFourierImage.html#a30b83f9368285274d28a1f0c514b4c5f) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFourierImage.html#a42c8817477d6af0a4d80a1ea57ca50dc) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFourierImage.html#aeaf674cacac7e540b60d1c52d778f5aa), but setting a different format does not trigger a conversion.

<a id="easyimage-fourier-transform-complex-extended"></a>

### The Complex Extended Format

The  ***Complex Extended*** is the simplest of these two formats.

* The only subtlety is that the complex numbers are stored in a floating point array, so the complex extended image is twice larger than the spatial image.
* Each odd column contains the imaginary part of a complex number.
* The following table is an illustration of an image in  ***Complex Extended*** format, where the complex pixel at row i and column j is: $$Re (i,j) + i × Im (i,j)$$

#### A Fourier Image in the Complex Extended Format

|               |               |    |                 |
|---------------|---------------|----|-----------------|
| $$Re(0,0)$$   | $$Im(0,0)$$   | …  | $$Im(0,w-1)$$   |
| $$Re(1,0)$$   | $$Im(1,0)$$   | …  | $$Im(1,w-1)$$   |
| …             | …             | …  | …               |
| $$Re(h-1,0)$$ | $$Im(h-1,0)$$ | …  | $$Im(h-1,w-1)$$ |

<a id="easyimage-fourier-transform-packed"></a>

### The Packed Format

The  ***Packed*** format is also called  ***Complex Conjugate Symmetrical***.

* It takes benefit of the conjugate symmetric properties of the Fourier transform of a real image to reduce the Fourier image size and to be the same as the spatial image size.
* The following table is an illustration of an image in  ***Packed*** format, where the complex pixel at row i and column j is: $$Re (i,j) + i \times Im (i,j)$$

There is a difference between images of odd and even height:

#### A Fourier Image in Packed Format, Odd Height

| $$<br/>Re(0,0)<br/>$$   | $$<br/>Re(0,1)<br/>$$   | $$<br/>Im(0,1)<br/>$$   | …   | $$<br/>Re(0,(w-1)/2)<br/>$$   | $$<br/>Im(0,(w-1)/2)<br/>$$   | $$<br/>Re(0,w/2)<br/>$$   |
|-------------------------|-------------------------|-------------------------|-----|-------------------------------|-------------------------------|---------------------------|
| $$<br/>Re(1,0)<br/>$$   | $$<br/>Re(1,1)<br/>$$   | $$<br/>Im(1,1)<br/>$$   | …   | $$<br/>Re(1,(w-1)/2)<br/>$$   | $$<br/>Im(1,(w-1)/2)<br/>$$   | $$<br/>Re(1,w/2)<br/>$$   |
| $$<br/>Im(1,0)<br/>$$   | $$<br/>Re(2,1)<br/>$$   | $$<br/>Im(2,1)<br/>$$   | …   | $$<br/>Re(2,(w-1)/2)<br/>$$   | $$<br/>Im(2,(w-1)/2)<br/>$$   | $$<br/>Im(1,w/2)<br/>$$   |
| …                       | …                       | …                       | …   | …                             | …                             | …                         |
| $$<br/>Re(h/2,0)<br/>$$ | $$<br/>Re(h-2,1)<br/>$$ | $$<br/>Im(h-2,1)<br/>$$ | …   | $$<br/>Re(h-2,(w-1)/2)<br/>$$ | $$<br/>Im(h-2,(w-1)/2)<br/>$$ | $$<br/>Re(h/2,w/2)<br/>$$ |
| $$<br/>Im(h/2,0)<br/>$$ | $$<br/>Re(h-1,1)<br/>$$ | $$<br/>Im(h-1,1)<br/>$$ | …   | $$<br/>Re(h-1,(w-1)/2)<br/>$$ | $$<br/>Im(h-1,(w-1)/2)<br/>$$ | $$<br/>Im(h/2,w/2)<br/>$$ |

#### A Fourier Image in Packed Format, Even Height

| $$<br/>Re(0,0)<br/>$$     | $$<br/>Re(0,1)<br/>$$   | $$<br/>Im(0,1)<br/>$$   | …   | $$<br/>Re(0,(w-1)/2)<br/>$$   | $$<br/>Im(0,(w-1)/2)<br/>$$   | $$<br/>Re(0,w/2)<br/>$$     |
|---------------------------|-------------------------|-------------------------|-----|-------------------------------|-------------------------------|-----------------------------|
| $$<br/>Re(1,0)<br/>$$     | $$<br/>Re(1,1)<br/>$$   | $$<br/>Im(1,1)<br/>$$   | …   | $$<br/>Re(1,(w-1)/2)<br/>$$   | $$<br/>Im(1,(w-1)/2)<br/>$$   | $$<br/>Re(1,w/2)<br/>$$     |
| $$<br/>Im(1,0)<br/>$$     | $$<br/>Re(2,1)<br/>$$   | $$<br/>Im(2,1)<br/>$$   | …   | $$<br/>Re(2,(w-1)/2)<br/>$$   | $$<br/>Im(2,(w-1)/2)<br/>$$   | $$<br/>Im(1,w/2)<br/>$$     |
| …                         | …                       | …                       | …   | …                             | …                             | …                           |
| $$<br/>Re(h/2-1,0)<br/>$$ | $$<br/>Re(h-3,1)<br/>$$ | $$<br/>Im(h-3,1)<br/>$$ | …   | $$<br/>Re(h-3,(w-1)/2)<br/>$$ | $$<br/>Im(h-3,(w-1)/2)<br/>$$ | $$<br/>Re(h/2-1,w/2)<br/>$$ |
| $$<br/>Im(h/2-1,0)<br/>$$ | $$<br/>Re(h-2,1)<br/>$$ | $$<br/>Im(h-2,1)<br/>$$ | …   | $$<br/>Re(h-2,(w-1)/2)<br/>$$ | $$<br/>Im(h-2,(w-1)/2)<br/>$$ | $$<br/>Im(h/2-1,w/2)<br/>$$ |
| $$<br/>Re(h/2,0)<br/>$$   | $$<br/>Re(h-1,1)<br/>$$ | $$<br/>Im(h-1,1)<br/>$$ | …   | $$<br/>Re(h-1,(w-1)/2)<br/>$$ | $$<br/>Im(h-1,(w-1)/2)<br/>$$ | $$<br/>Re(h/2,w/2)<br/>$$   |
* The other coefficients are obtained by using the following properties:
  * For $$i = 1,…,h-1$$ and $$j = 1,…,w-1$$:
    * $$
      Re (i,j) = Re (h-i,w-j)
      $$
    * $$
      Im (i,j) = -Im (h-i,w-j)
      $$
  * For $$j = 1,…,w-1$$:
    * $$
      Re (0,j) = Re (0,w-j)
      $$
    * $$
      Im (0,j) = -Im (0,w-j)
      $$
  * For $$i = 1,…,h-1$$:
    * $$
      Re (i,0) = Re (h-i,0)
      $$
    * $$
      Im (i,0) = -Im (h-i,0)
      $$

<a id="easyimage-fourier-transform-quick-links"></a>

## See Also

Easy to understand, ready to copy code snippets.

Frequency-selective spatial filtering for texture analysis using the Gabor wavelet.
