I have successfully tested 1D phase correlation algorithm to determine vertical shift between two synthetic images.
When I moved to real images, however, it is not able to detect translation at all (the peak is located at 0, which is wrong result).
I have the following images:
And resulting phase correlation (Magnitude, Real, Imaginary):
The first scanline of the image is completely white, but the shift is obviously larger (20 pixels).
The expected result is white line on 20th row which happens only on synthetic images or light noise.
My algorithm is very simple - for each image column:
- Compute 1D FT of source and target image columns (
a=FT(A)
,b=FT(B)
) - Compute cross-power spectrum (
cross_power = a *. conj(b) / |a *. conj(b)|
) -*.
denotes pointwise mutliplication,conj(x)
denotes complex conjugate - Compute phase correlation (
phase = IFT(cross_power)
) - Find maximum magnitude in every column of
phase
. - Find consensus peak location (e.g. median of detected peak locations)
Can you please advise me how to improve baseline phase correlation algorithm to deal with real-world (noisy) images?
Should I rather use NCC (Normalized Cross Correlation) instead of FFT-based phase correlation?
UPDATE
I was experimenting with zero padding to rule out errors introduced by circular shifting (only simple linear shifting of images is desirable) and tested this on original images from Wikipedia:
The single peak is clearly there as it should be:
However - if I perform slight smoothing (Gaussian blur) to reduce noise and actually improve the result, the phase correlation comes out totally mangled:
Here is the enhanced version - the original peak is weaker (why??) and there appeared new peaks around zero shifts (why??):