0

I am trying to implement the spectral approach to get the saliency of an image with CImg, but I'm having trouble getting there. This might seems like a repost from this question (spectral residual saliency detection in C++ with CImg) but I think I got right the two mistakes from this question (atan2 and FFT arguments).

Here's my code:

int main(int argc, char * argv[]) {

    const char * input_file = "img/pic.png";

    CImg<float> input = CImg<float>(input_file);
    const CImg<float> mask(3,3,1,1,1.0f/9.0f);

    resize_fft(input); // Resize for fft
    CImg<float> gray = any2gray(input); // to single channel grayscale

    CImgList<float> fft = gray.get_FFT();

    CImg<float> amp = (fft[0].get_pow(2) + fft[1].get_pow(2)).get_sqrt();
    CImg<float> amp_log = (amp + 1.0f).get_log().get_normalize(0, 255);

    CImg<float> phase = fft[1].get_atan2(fft[0]);
    CImg<float> residual = amp_log - amp_log.get_convolve(mask);
    CImg<float> real = residual.get_exp();
    CImg<float>::FFT(real, phase, true);

    real.save("img/001.png");
    real.normalize(0, 255).save("img/002.png");

    return 1;
}

Both save pictures 001 and 002 end up being noise-like picture, like still in the frequency space. I don't what's something wrong with what I'm doing, if yuo guys can help me ?

Thanks.

Community
  • 1
  • 1
user3360437
  • 87
  • 1
  • 7

1 Answers1

0

Firstly, It is obvious that you forget to smooth real with Gaussian filter.

Secondly, the line CImg<float>::FFT(real, phase, true); is suspectable. I don't know about CImg library but I can understand what you are expressing. When you do inverse fft, I think that both the real part and the imaginary part are wrong. The formulae in the paper are kind of misleading, reading the matlab code is clearer.
If you are familiar with complex number, you will find that getting variable phase is not necessary here.
The pseudo code replacing the line are here:

fft[0] = fft[0] ./ amp .* residual;
fft[1] = fft[1] ./ amp .* residual;
//Inverse Fourier Transform
CImg<float>::FFT(fft[0], fft[1], true);
real = fft[0].get_pow(2) + fft[1].get_pow(2);
real.get_convolve(Gaussian filter with sigma = 8)

All the operators with left dot mean element-wise operation.

Daniel
  • 2,195
  • 3
  • 14
  • 24