'fftw3 2D, how to normalize array of double for IDCT?
I have 2d array in python and a function that converts numbers by the IDCT. It works right. But I have to do the same in C ++ using a library fftw3. And I get wrong answer. It is not entirely wrong, if I remove the norm parameter from the python program, I get the same result. That is, on Python, the array is normalized, but on fftw3 it is not. How can I normalize it? The documentation only mentions that it needs to be done and no examples or explanations.
I tried to multiply and divide the input array in C ++ by 2 and by sqrt(2), by 4 (my N) and sqrt(N), but the result is not the same. I tried to divide it at the sqrt(2 / N). And I tried to apply multiplication and division only to the first row and column, but to no avail.
I tried to pass input_ and output_ as &input_[0], &output_[0].
Python OK example
from scipy import fftpack
import numpy as np
def idct2(f):
"""
Inverse Discrete Cosine Transform in 2D.
"""
return np.transpose(fftpack.idct(np.transpose(fftpack.idct(f, norm = "ortho")), norm = "ortho"))
data = [[110, 199, 22, 282],
[30, 125, 239, 34],
[79, 288, 174, 67],
[175, 243, 134, 256]]
idct2(data)
# result
>>> array([[ 553.27655635, -132.45254006, 3.51123029, -101.4290401 ],
[-219.14317857, -8.74853673, 16.90900348, 29.57007596],
[ 158.6797074 , -64.29020845, 239.1297417 , -90.10660479],
[ 51.81024507, 32.73855308, 89.2027567 , -118.65776132]])
C++ wrong code:
#include <fftw3.h>
#include <vector>
#include <fstream>
#include <iostream>
int main() {
std::vector<double> input_;
input_.resize(16);
std::vector<double> output_;
output_.resize(16);
input_ = {110, 199, 22, 282,
30, 125, 239, 34,
79, 288, 174, 67,
175, 243, 134, 256};
fftw_plan plan = fftw_plan_r2r_2d(4, 4, input_.data(), output_.data(), FFTW_REDFT01,FFTW_REDFT01, FFTW_ESTIMATE);
fftw_execute(plan);
// result to file
std::ofstream out("file.txt");
for(size_t i=0; i<output_.size(); ++i) {
out << output_[i] << std::endl;
}
// result
/*
3936.9 -1128.71 -346.486 -817.328
-1947.04 156.35 56.1195 526.088
826.69 -536.84 1585.03 -680.182
82.0488 349.704 495.927 -798.277
*/
return 0;
}
Any ideas?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
