10 fftwf_plan Fftw::create_plan_fwd(uint howmany) const
12 cv::Mat mat_in = cv::Mat::zeros(howmany * m_height, m_width, CV_32F);
13 ComplexMat mat_out(m_height, m_width / 2 + 1, howmany);
14 float *in = reinterpret_cast<float *>(mat_in.data);
15 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(mat_out.get_p_data());
18 int n[] = {(int)m_height, (int)m_width};
19 int idist = m_height * m_width, odist = m_height * (m_width / 2 + 1);
20 int istride = 1, ostride = 1;
21 int *inembed = NULL, *onembed = NULL;
23 return fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, FFTW_PATIENT);
26 fftwf_plan Fftw::create_plan_inv(uint howmany) const
28 ComplexMat mat_in(m_height, m_width / 2 + 1, howmany);
29 cv::Mat mat_out = cv::Mat::zeros(howmany * m_height, m_width, CV_32F);
30 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(mat_in.get_p_data());
31 float *out = reinterpret_cast<float *>(mat_out.data);
34 int n[] = {(int)m_height, (int)m_width};
35 int idist = m_height * (m_width / 2 + 1), odist = m_height * m_width;
36 int istride = 1, ostride = 1;
37 int *inembed = nullptr, *onembed = nullptr;
39 return fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, FFTW_PATIENT);
42 void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales)
44 Fft::init(width, height, num_of_feats, num_of_scales);
46 #if !defined(CUFFTW) && defined(BIG_BATCH)
49 fftw_plan_with_nthreads(omp_get_max_threads());
51 int np = sysconf(_SC_NPROCESSORS_ONLN);
52 fftw_plan_with_nthreads(np);
57 std::cout << "FFT: FFTW" << std::endl;
59 std::cout << "FFT: cuFFTW" << std::endl;
63 plan_f = create_plan_fwd(1);
64 plan_fw = create_plan_fwd(m_num_of_feats);
65 plan_i_1ch = create_plan_inv(1);
68 plan_f_all_scales = create_plan_fwd(m_num_of_scales);
69 plan_fw_all_scales = create_plan_fwd(m_num_of_scales * m_num_of_feats);
70 plan_i_all_scales = create_plan_inv(m_num_of_scales);
74 void Fftw::set_window(const MatDynMem &window)
76 Fft::set_window(window);
80 void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result)
82 Fft::forward(real_input, complex_result);
84 if (real_input.size[0] == 1)
85 fftwf_execute_dft_r2c(plan_f, reinterpret_cast<float *>(real_input.data),
86 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
89 fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast<float *>(real_input.data),
90 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
94 void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, MatScaleFeats &temp)
96 Fft::forward_window(feat, complex_result, temp);
98 uint n_scales = feat.size[0];
99 for (uint s = 0; s < n_scales; ++s) {
100 for (uint ch = 0; ch < uint(feat.size[1]); ++ch) {
101 cv::Mat feat_plane = feat.plane(s, ch);
102 cv::Mat temp_plane = temp.plane(s, ch);
103 temp_plane = feat_plane.mul(m_window);
107 float *in = temp.ptr<float>();
108 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(complex_result.get_p_data());
111 fftwf_execute_dft_r2c(plan_fw, in, out);
114 fftwf_execute_dft_r2c(plan_fw_all_scales, in, out);
118 void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result)
120 Fft::inverse(complex_input, real_result);
122 int n_channels = complex_input.n_channels;
123 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(complex_input.get_p_data());
124 float *out = real_result.ptr<float>();
127 fftwf_execute_dft_c2r(plan_i_1ch, in, out);
130 fftwf_execute_dft_c2r(plan_i_all_scales, in, out);
132 real_result *= 1.0 / (m_width * m_height);
137 fftwf_destroy_plan(plan_f);
138 fftwf_destroy_plan(plan_fw);
139 fftwf_destroy_plan(plan_i_1ch);
142 fftwf_destroy_plan(plan_f_all_scales);
143 fftwf_destroy_plan(plan_fw_all_scales);
144 fftwf_destroy_plan(plan_i_all_scales);