9 fftwf_plan Fftw::create_plan_fwd(uint howmany) const
11 cv::Mat mat_in = cv::Mat::zeros(howmany * m_height, m_width, CV_32F);
12 ComplexMat mat_out(m_height, m_width / 2 + 1, howmany);
13 float *in = reinterpret_cast<float *>(mat_in.data);
14 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(mat_out.get_p_data());
17 int n[] = {(int)m_height, (int)m_width};
18 int idist = m_height * m_width, odist = m_height * (m_width / 2 + 1);
19 int istride = 1, ostride = 1;
20 int *inembed = NULL, *onembed = NULL;
22 return fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, FFTW_PATIENT);
25 fftwf_plan Fftw::create_plan_inv(uint howmany) const
27 ComplexMat mat_in(m_height, m_width / 2 + 1, howmany);
28 cv::Mat mat_out = cv::Mat::zeros(howmany * m_height, m_width, CV_32F);
29 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(mat_in.get_p_data());
30 float *out = reinterpret_cast<float *>(mat_out.data);
33 int n[] = {(int)m_height, (int)m_width};
34 int idist = m_height * (m_width / 2 + 1), odist = m_height * m_width;
35 int istride = 1, ostride = 1;
36 int *inembed = nullptr, *onembed = nullptr;
38 return fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, FFTW_PATIENT);
41 void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales)
43 Fft::init(width, height, num_of_feats, num_of_scales);
48 fftw_plan_with_nthreads(omp_get_max_threads());
50 fftw_plan_with_nthreads(4);
55 std::cout << "FFT: FFTW" << std::endl;
57 std::cout << "FFT: cuFFTW" << std::endl;
61 plan_f = create_plan_fwd(1);
62 plan_fw = create_plan_fwd(m_num_of_feats);
63 plan_i_1ch = create_plan_inv(1);
66 plan_f_all_scales = create_plan_fwd(m_num_of_scales);
67 plan_fw_all_scales = create_plan_fwd(m_num_of_scales * m_num_of_feats);
68 plan_i_all_scales = create_plan_inv(m_num_of_scales);
72 void Fftw::set_window(const MatDynMem &window)
74 Fft::set_window(window);
78 void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result)
80 Fft::forward(real_input, complex_result);
82 if (real_input.size[0] == 1)
83 fftwf_execute_dft_r2c(plan_f, reinterpret_cast<float *>(real_input.data),
84 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
87 fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast<float *>(real_input.data),
88 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
92 void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, MatScaleFeats &temp)
94 Fft::forward_window(feat, complex_result, temp);
96 uint n_scales = feat.size[0];
97 for (uint s = 0; s < n_scales; ++s) {
98 for (uint ch = 0; ch < uint(feat.size[1]); ++ch) {
99 cv::Mat feat_plane = feat.plane(s, ch);
100 cv::Mat temp_plane = temp.plane(s, ch);
101 temp_plane = feat_plane.mul(m_window);
105 float *in = temp.ptr<float>();
106 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(complex_result.get_p_data());
109 fftwf_execute_dft_r2c(plan_fw, in, out);
112 fftwf_execute_dft_r2c(plan_fw_all_scales, in, out);
116 void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result)
118 Fft::inverse(complex_input, real_result);
120 int n_channels = complex_input.n_channels;
121 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(complex_input.get_p_data());
122 float *out = real_result.ptr<float>();
125 fftwf_execute_dft_c2r(plan_i_1ch, in, out);
128 fftwf_execute_dft_c2r(plan_i_all_scales, in, out);
130 real_result *= 1.0 / (m_width * m_height);
135 fftwf_destroy_plan(plan_f);
136 fftwf_destroy_plan(plan_fw);
137 fftwf_destroy_plan(plan_i_1ch);
140 fftwf_destroy_plan(plan_f_all_scales);
141 fftwf_destroy_plan(plan_fw_all_scales);
142 fftwf_destroy_plan(plan_i_all_scales);