My overall aim is to compare the edges of two images by comparing their Fourier Transforms (FFT) and to calculate one number as a key performance indicator that describes how much they are similar to each other.

My first step was to convert the image into grayscale and fill an array with the last pixel row. The content of the array can be treated as a signal with numbers between 0 and 255.

example with size=437:

''' [193 190 186 181 175 181 177 170 164 159 158 159 160 179 175 172 164 153 152 151 142 123 169 165 166 170 171 168 166 167 170 173 174 175 166 167 ... 69 98 52 88 83 52] '''

  1. Is it right that when two FFTs are compared, the coherence should be used as a statistical instrument?

  2. The coherence is calculated by dividing the cross-spectral density between the two signals x and y by the product of their auto-spectral density. The Wiener–Khinchin theorem states that the power spectral density of a stationary random process is the FFT of the corresponding autocorrelation function. So by applying the coherence function onto my signal arrays (containing the grayscale pixel information), I automatically apply a FFT onto my signal?

  3. The coherence is a number defined between 0 and 1 and describes the correlation between two signals. The function matplotlib.mlab.cohere(x, y) returns two arrays: The frequencies for the elements in Cxy and the coherence vector. How do I get one key performance indicator out of my coherence vector?

  4. Could someone please explain the parameters for the matplotlib.mlab.cohere(x, y) function so that I can apply them correctly?

  5. Must the two signals have the same size?

I will be thankful if someone can answer even one of the questions.


If the goal is to get a metric for similarity, consider using direct correlation rather than mapping to the frequency domain to then perform a comparison (which I would then again recommend from that domain to also do as a subsequent direct correlation computation).

Assuming no time-shift, the Pearson Correlation Coefficient is ideal for this application in obtaining a single metric to show how similarly in a linear relationship two waveforms may be to each other, with a result that would be normalized between $\pm 1$. For this purpose as the edge of each the images as a single column vector given as $x[n]$ and $y[n]$ each with $N$ samples, the correlation coefficient is computed with:

$$\rho =\frac{\sigma_{xy}}{\sigma_{x} \sigma_{y}} = \frac{\displaystyle\sum_{n=0}^{N-1}(x[n]-\bar x)(y[n]-\bar y)}{\sqrt{\displaystyle\sum_{n=0}^{N-1}(x[n]-\bar x)^2\sum_{n=0}^{N-1}(y[n]-\bar y)^2}}$$

Where $\bar x$ and $\bar y$ are the mean of $x[n]$ and $y[n]$ respectively. What the above formula is doing, to describe simply, is first removing the average value (mean) of the two vectors, multiplying the two sample by sample and summing that result, and then normalizing that sum by dividing by the standard deviation of $x$ and the standard deviation of $y$.

The DFT (for which the FFT is an algorithm) is itself a correlation, as a correlation to each frequency basis vector for purpose of mapping to the frequency domain. So with that approach the OP would be correlating each waveform to a common reference (the frequency basis vectors) and then from that would still need to somehow compare the two results. Mapping to the frequency domain is useful when we want to consider the frequency characteristics specifically, or perform subsequent mathematical operations which may be simplified in the frequency domain (such as multiplication in place of convolution). There is no such simplification in the correlation coefficient computation as given above, so therefore it is my recommendation to compare (correlate) the sample domain vectors directly, assuming an indication of linear similarity would be a useful metric.

Importantly if there is a possibility that the two images along the column being used for comparison are similar but with a shifted offset from each other within the column used, then a cross correlation function instead would be of interest, since that computes the correlation for every sample offset between the two columns. For this I do recommend using an FFT for efficiency in computation, which will result in a circular correlation result and is computed as follows:

$$\text{xcorr} = \text{ifft}\{ \text{fft}\{x\} \text{fft}\{y\}^* \}$$

Where $\text{fft{}}$ and $\text{ifft{}}$ represent the fft and inverse fft computations, and $(\cdot)^*$ indicates a complex conjugation.

This will result in $N$ samples showing a comparative correlation for every possible sample offset $n$. The result can be similarly normalized if desired (useful if multiple images are all being compared) by dividing by $N$ as well as the standard deviations of $x$ and $y$


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.