0

CImg output i am getting
Desired FFT ouptut.Checked using ImageJ

#include "CImg.h"
using namespace cimg_library;

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

    const char * input_file = "Lenna.png";

    CImg<unsigned char> * input = new CImg<unsigned char>(input_file);

    //resize_fft(*input); //Resize the image for the FFT
    //CImg<unsigned char> gray = any2gray(*input); //to single-channel grayscale image
    //free(input);


    CImgList<unsigned char> fft = input->get_FFT();
    CImg<unsigned char>::FFT(fft[0], fft[1], false);
    fft[0].save("fft.jpg");

    return 1;
}

I tried this code . But i am getting noise image.Anybody could help me to get the desired fft image? i am running on Linux. i have posted the images above.

SVJ
  • 51
  • 5
  • I haven't tried this and am only guessing, but I would imagine you'll need to convert to `float` somewhere along the line to hold the range of your FFT data - it isn't going to fit in an `unsigned char`. – Mark Setchell Mar 17 '21 at 11:32
  • should i convert all the unisgned char to float? – SVJ Mar 17 '21 at 11:55
  • Wow. This is a poor design choice in CImg. It makes no sense to compute the FFT using integer values. From [the very sparse docs](https://cimg.eu/reference/structcimg__library_1_1CImg.html#a6250e4b1cab628d8d26a4c6059b84dac) it seems that the function does the computation in-place. So any `T` that is not a float type will produce wrong results. Why this is even possible is beyond me. – Cris Luengo Mar 17 '21 at 13:38
  • You might be better off using [`get_FFT`](https://cimg.eu/reference/structcimg__library_1_1CImg.html#a086e004d89528c4d5f777fefbc3272f9), which returns the transformed image in an appropriate type. – Cris Luengo Mar 17 '21 at 13:41
  • @CrisLuengo i am getting segmentation fault converting unsigned char to float. – SVJ Mar 18 '21 at 02:05
  • @CrisLuengo get_FFT() outputs two images fft[0], fft[1] . both are showing noise. – SVJ Mar 18 '21 at 02:13
  • You're probably saving the floating-point output images as JPEG or PNG or whatever, which would cast them to uint8 because those formats only store 8 bits per sample. The whole point here is that the FFT outputs values that are outside the range of an 8-bit integer. – Cris Luengo Mar 18 '21 at 07:07
  • Could you pls guide me how to change the code? – SVJ Mar 18 '21 at 08:28

1 Answers1

0

Several things wrong here in your code:

  1. By (mathematical) definition, result of a FFT is a float-valued image. There is no way you can accurately store a FFT image into a CImgList<unsigned char>. Use a CImgList<float> or CImgList<double> instead when defining your fft variable. Your current fft is defined as a CImgList<unsigned char>, there is no way CImg can store float-values inside.

  2. CImg<T>::get_FFT() always returns a CImgList<float> or a CImgList<double>, depending on the original type T (if T is unsigned char, result will be a CImgList<float> probably). But if you write

CImgList<unsigned char> fft = input->get_FFT();

then, of course the result of get_FFT() is rounded back to unsigned char, which is not what you want.

So, the correct code would be :

 CImg<unsigned char> input(input_file); // (note: No need for a pointer here).
 CImgList<float> fft = input.get_FFT();

At this point, fft[0] is the real part of the FFT, and fft[1] the imaginary part of the FFT. Note that it does not correspond to the classical Fourier visualization of images you'll find on the web, which are actually displayed as the centered module of the FFT (less often with the phase), e.g.

https://cs.appstate.edu/ret/imageJ/PClabs/imlab/FFT/gif/imj-fft1.gif

Getting this requires additional steps to transform the complex-valued FFT you get as this scalar image representation (which is actually good only for visualization, not for actual computations in the Fourier space, as you lose half of the data of the FFT).

Oh, and before saying any library you use has a lack of design, ask yourself if there is something that maybe you have not understood. Looking at your code makes me think that you still have a lot to learn before having a relevant opinion on how to design a programming library.