10 #define FFTW_PLAN_WITH_THREADS() fftw_plan_with_nthreads(m_num_threads);
12 #define FFTW_PLAN_WITH_THREADS() fftw_plan_with_nthreads(omp_get_max_threads());
14 #define FFTW_PLAN_WITH_THREADS()
22 Fftw::Fftw(int num_threads)
23 : m_num_threads(num_threads)
27 void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales)
31 m_num_of_feats = num_of_feats;
32 m_num_of_scales = num_of_scales;
34 #if defined(ASYNC) || defined(OPENMP)
39 std::cout << "FFT: FFTW" << std::endl;
41 std::cout << "FFT: cuFFTW" << std::endl;
45 cv::Mat in_f = cv::Mat::zeros(m_height, m_width, CV_32FC1);
46 ComplexMat out_f(m_height, m_width / 2 + 1, 1);
47 plan_f = fftwf_plan_dft_r2c_2d(m_height, m_width,
48 reinterpret_cast<float*>(in_f.data),
49 reinterpret_cast<fftwf_complex*>(out_f.get_p_data()),
54 cv::Mat in_fw = cv::Mat::zeros(m_height * m_num_of_feats, m_width, CV_32F);
55 ComplexMat out_fw(m_height, m_width / 2 + 1, m_num_of_feats);
56 float *in = reinterpret_cast<float*>(in_fw.data);
57 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(out_fw.get_p_data());
59 int n[] = {(int)m_height, (int)m_width};
60 int howmany = m_num_of_feats;
61 int idist = m_height*m_width, odist = m_height*(m_width/2+1);
62 int istride = 1, ostride = 1;
63 int *inembed = NULL, *onembed = NULL;
65 FFTW_PLAN_WITH_THREADS();
66 plan_fw = fftwf_plan_many_dft_r2c(rank, n, howmany,
67 in, inembed, istride, idist,
68 out, onembed, ostride, odist,
73 cv::Mat in_all = cv::Mat::zeros(m_height * (num_of_scales*m_num_of_feats), m_width, CV_32F);
74 ComplexMat out_all(m_height, m_width / 2 + 1, num_of_scales*m_num_of_feats);
75 float *in = reinterpret_cast<float*>(in_all.data);
76 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(out_all.get_p_data());
78 int n[] = {(int)m_height, (int)m_width};
79 int howmany = num_of_scales*m_num_of_feats;
80 int idist = m_height*m_width, odist = m_height*(m_width/2+1);
81 int istride = 1, ostride = 1;
82 int *inembed = NULL, *onembed = NULL;
84 FFTW_PLAN_WITH_THREADS();
85 plan_fw_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany,
86 in, inembed, istride, idist,
87 out, onembed, ostride, odist,
92 ComplexMat in_i(m_height,m_width,m_num_of_feats);
93 cv::Mat out_i = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_feats));
94 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i.get_p_data());
95 float *out = reinterpret_cast<float*>(out_i.data);
97 int n[] = {(int)m_height, (int)m_width};
98 int howmany = m_num_of_feats;
99 int idist = m_height*(m_width/2+1), odist = 1;
100 int istride = 1, ostride = m_num_of_feats;
101 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
103 FFTW_PLAN_WITH_THREADS();
104 plan_i_features = fftwf_plan_many_dft_c2r(rank, n, howmany,
105 in, inembed, istride, idist,
106 out, onembed, ostride, odist,
111 ComplexMat in_i1(m_height,m_width,1);
112 cv::Mat out_i1 = cv::Mat::zeros(m_height, m_width, CV_32FC1);
113 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i1.get_p_data());
114 float *out = reinterpret_cast<float*>(out_i1.data);
116 int n[] = {(int)m_height, (int)m_width};
118 int idist = m_height*(m_width/2+1), odist = 1;
119 int istride = 1, ostride = 1;
120 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
122 FFTW_PLAN_WITH_THREADS();
123 plan_i_1ch = fftwf_plan_many_dft_c2r(rank, n, howmany,
124 in, inembed, istride, idist,
125 out, onembed, ostride, odist,
130 void Fftw::set_window(const cv::Mat &window)
135 ComplexMat Fftw::forward(const cv::Mat &input)
137 cv::Mat complex_result(m_height, m_width / 2 + 1, CV_32FC2);
139 fftwf_execute_dft_r2c(plan_f,reinterpret_cast<float*>(input.data),reinterpret_cast<fftwf_complex*>(complex_result.data));
141 return ComplexMat(complex_result);
144 ComplexMat Fftw::forward_window(const std::vector<cv::Mat> &input)
146 int n_channels = input.size();
147 cv::Mat in_all(m_height * n_channels, m_width, CV_32F);
148 for (int i = 0; i < n_channels; ++i) {
149 cv::Mat in_roi(in_all, cv::Rect(0, i*m_height, m_width, m_height));
150 in_roi = input[i].mul(m_window);
152 ComplexMat result(m_height, m_width/2 + 1, n_channels);
154 float *in = reinterpret_cast<float*>(in_all.data);
155 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(result.get_p_data());
157 if (n_channels <= 44)
158 fftwf_execute_dft_r2c(plan_fw, in, out);
160 fftwf_execute_dft_r2c(plan_fw_all_scales, in, out);
165 cv::Mat Fftw::inverse(const ComplexMat &inputf)
167 int n_channels = inputf.n_channels;
168 cv::Mat real_result(m_height, m_width, CV_32FC(n_channels));
169 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(inputf.get_p_data());
170 float *out = reinterpret_cast<float*>(real_result.data);
173 fftwf_execute_dft_c2r(plan_i_features, in, out);
175 fftwf_execute_dft_c2r(plan_i_1ch, in, out);
177 return real_result/(m_width*m_height);
182 fftwf_destroy_plan(plan_f);
183 fftwf_destroy_plan(plan_fw);
184 fftwf_destroy_plan(plan_fw_all_scales);
185 fftwf_destroy_plan(plan_i_features);
186 fftwf_destroy_plan(plan_i_1ch);