Я создал приложение в Qt, которое позволяет мне открывать изображение и использовать 2D FFT-преобразование с библиотекой FFTW. Проблема в том, что я не могу получить правильные значения пикселей с обратным преобразованием. Но начнем с самого начала.
Вот так выглядит моя функция FFTW, которую я использую
void FFTInterface::FFTW(int rows, int cols, QColor **imageInput,fftw_complex * in, fftw_complex * out)
{
fftw_plan g;
g = fftw_plan_dft_2d(rows, cols, in, out, FFTW_FORWARD, FFTW_MEASURE);
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
in[k][0] = imageInput[i][j].red();
in[k][1] = 0.0;
k++;
}
}
fftw_execute(g);
fftw_destroy_plan(g);
}
строки, столбцы размер изображения, imageInput массив QColor, в котором хранится значение пикселей (в оттенках серого), в а также из являются объектом fftw_complex, входных и выходных массивов.
Эта функция дает мне некоторый результат, который нужно показать. Для этого я сделал какую-то ругань. Во-первых, я использую функцию abs () для каждого значения, чтобы убедиться, что оно имеет положительное значение. После этого я масштабирую результат.
void FFTInterface::Abs(fftw_complex *out, int rows, int cols)
{
int k = 0;
for(int i = 0; i < rows; i++){
for(int j = 0; j<cols; j++){
out[k][0] = abs(out[k][0]);
out[k][1] = abs(out[k][1]);
k++;
}
}
}
void FFTInterface::Scale(fftw_complex * in,int rows, int cols)
{
float c = 255.0 / log(1+Max(in,rows,cols));
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
in[k][0] = c*log(1+in[k][0]);
in[k][1] = c*log(1+in[k][0]);
k++;
}
}
}
Этот процесс даст мне то, что мне нужно. Изображение выглядит хорошо. Но у меня есть проблема, чтобы вернуть изображение к его оригиналу.
Функция для BACKWARD как ниже
void FFTInterface::IFFTW(int rows, int cols, fftw_complex * in, fftw_complex * out)
{
fftw_plan g;
g = fftw_plan_dft_2d(rows, cols, in, out, FFTW_BACKWARD, FFTW_MEASURE);
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
in[k][1] = 0.0;
k++;
}
}
fftw_execute(g);
fftw_destroy_plan(g);
}
Я нашел где-то, что это не нормализовано (результаты ОЧЕНЬ БОЛЬШИЕ). Для нормализации я просто делю значения на N (256,512 и т. Д.) — ширину или высоту изображения (это всегда квадрат), но значения отличаются от исходных.
У вас есть идеи, где я что-то упустил? Scalling? Может мне стоит использовать другой метод fft из библиотеки? Я застрял.
Принимая абсолютное значение и масштабируя сложные компоненты с целью отображения изображения, вы изменяете данные таким образом, что обратное преобразование больше не дает исходный ввод. Чтобы избежать этой проблемы, я бы предложил вам создать копию данных, которые вы хотите отобразить, прежде чем масштабировать их. Кроме того, убедитесь, что не забыли, что входной сигнал обратного преобразования должен быть выходным сигналом прямого преобразования (или последним выходным сигналом в цепочке обработки сигналов, как может быть).
В псевдокоде вы можете сделать это так:
interface.FFTW(rows, cols, imageInput, in, out);
size_t N = rows*cols;
fftw_complex* todisplay = fftw_malloc(N);
std::copy(out, out+N, todisplay);
interface.Abs(todisplay);
interface.Scale(todisplay);
... display "todisplay" on your Qt user interface
fftw_free(todislay);
interface.IFFTW(rows, cols, out, reconstructed);
Других решений пока нет …