CImg — значимость со спектральным подходом

Я пытаюсь реализовать спектральный подход, чтобы получить заметность изображения с помощью CImg, но у меня проблемы с этим. Это может показаться репостом этого вопроса (обнаружение спектральной остаточной значимости в C++ с CImg), но я думаю, что правильно понял две ошибки из этого вопроса (аргументы atan2 и FFT).

Вот мой код:

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;
}

Оба сохраненных изображения 001 и 002 в конечном итоге представляют собой шумоподобное изображение, как бы неподвижное в частотном пространстве. Я не понимаю, что не так с тем, что я делаю, если вы, ребята, можете мне помочь?

Спасибо.


person user3360437    schedule 28.01.2016    source источник


Ответы (1)


Во-первых, очевидно, что вы забыли сгладить real фильтром Гаусса.

Во-вторых, строка CImg<float>::FFT(real, phase, true); вызывает подозрение. Я не знаю о библиотеке CImg, но я могу понять, что вы выражаете. Когда вы делаете inverse fft, я думаю, что и действительная, и мнимая части неверны. Формулы в документе вводят в заблуждение, читая код Matlab понятнее.
Если вы знакомы с комплексными числами, вы обнаружите, что получение переменной phase не является здесь необходимо.
Псевдокод, заменяющий строку, находится здесь:

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)

Все операторы с левой точкой означают поэлементную операцию.

person Daniel    schedule 12.07.2016