9 #if !defined(ASYNC) && !defined(OPENMP) && !defined(CUFFTW)
10 #define FFTW_PLAN_WITH_THREADS() fftw_plan_with_nthreads(m_num_threads);
12 #define FFTW_PLAN_WITH_THREADS()
20 Fftw::Fftw(int num_threads)
21 : m_num_threads(num_threads)
25 void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales, bool big_batch_mode)
29 m_num_of_feats = num_of_feats;
30 m_num_of_scales = num_of_scales;
31 m_big_batch_mode = big_batch_mode;
33 #if (!defined(ASYNC) && !defined(CUFFTW))|| defined(OPENMP)
38 std::cout << "FFT: FFTW" << std::endl;
40 std::cout << "FFT: cuFFTW" << std::endl;
42 //FFT forward one scale
44 cv::Mat in_f = cv::Mat::zeros(m_height, m_width, CV_32FC1);
45 ComplexMat out_f(m_height, m_width / 2 + 1, 1);
46 plan_f = fftwf_plan_dft_r2c_2d(m_height, m_width,
47 reinterpret_cast<float*>(in_f.data),
48 reinterpret_cast<fftwf_complex*>(out_f.get_p_data()),
51 //FFT forward all scales
52 if (m_num_of_scales > 1 && m_big_batch_mode) {
53 cv::Mat in_f_all = cv::Mat::zeros(m_height*m_num_of_scales, m_width, CV_32F);
54 ComplexMat out_f_all(m_height, m_width / 2 + 1, m_num_of_scales);
55 float *in = reinterpret_cast<float*>(in_f_all.data);
56 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(out_f_all.get_p_data());
58 int n[] = {(int)m_height, (int)m_width};
59 int howmany = m_num_of_scales;
60 int idist = m_height*m_width, odist = m_height*(m_width/2+1);
61 int istride = 1, ostride = 1;
62 int *inembed = NULL, *onembed = NULL;
64 FFTW_PLAN_WITH_THREADS();
65 plan_f_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany,
66 in, inembed, istride, idist,
67 out, onembed, ostride, odist,
70 //FFT forward window one scale
72 cv::Mat in_fw = cv::Mat::zeros(m_height * m_num_of_feats, m_width, CV_32F);
73 ComplexMat out_fw(m_height, m_width / 2 + 1, m_num_of_feats);
74 float *in = reinterpret_cast<float*>(in_fw.data);
75 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(out_fw.get_p_data());
77 int n[] = {(int)m_height, (int)m_width};
78 int howmany = m_num_of_feats;
79 int idist = m_height*m_width, odist = m_height*(m_width/2+1);
80 int istride = 1, ostride = 1;
81 int *inembed = NULL, *onembed = NULL;
83 FFTW_PLAN_WITH_THREADS();
84 plan_fw = fftwf_plan_many_dft_r2c(rank, n, howmany,
85 in, inembed, istride, idist,
86 out, onembed, ostride, odist,
89 //FFT forward window all scales all feats
90 if (m_num_of_scales > 1 && m_big_batch_mode) {
91 cv::Mat in_all = cv::Mat::zeros(m_height * (m_num_of_scales*m_num_of_feats), m_width, CV_32F);
92 ComplexMat out_all(m_height, m_width / 2 + 1, m_num_of_scales*m_num_of_feats);
93 float *in = reinterpret_cast<float*>(in_all.data);
94 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(out_all.get_p_data());
96 int n[] = {(int)m_height, (int)m_width};
97 int howmany = m_num_of_scales*m_num_of_feats;
98 int idist = m_height*m_width, odist = m_height*(m_width/2+1);
99 int istride = 1, ostride = 1;
100 int *inembed = NULL, *onembed = NULL;
102 FFTW_PLAN_WITH_THREADS();
103 plan_fw_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany,
104 in, inembed, istride, idist,
105 out, onembed, ostride, odist,
108 //FFT inverse one scale
110 ComplexMat in_i(m_height,m_width,m_num_of_feats);
111 cv::Mat out_i = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_feats));
112 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i.get_p_data());
113 float *out = reinterpret_cast<float*>(out_i.data);
115 int n[] = {(int)m_height, (int)m_width};
116 int howmany = m_num_of_feats;
117 int idist = m_height*(m_width/2+1), odist = 1;
118 int istride = 1, ostride = m_num_of_feats;
119 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
121 FFTW_PLAN_WITH_THREADS();
122 plan_i_features = fftwf_plan_many_dft_c2r(rank, n, howmany,
123 in, inembed, istride, idist,
124 out, onembed, ostride, odist,
127 //FFT inverse all scales
128 if (m_num_of_scales > 1 && m_big_batch_mode) {
129 ComplexMat in_i_all(m_height,m_width,m_num_of_feats*m_num_of_scales);
130 cv::Mat out_i_all = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_feats*m_num_of_scales));
131 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i_all.get_p_data());
132 float *out = reinterpret_cast<float*>(out_i_all.data);
134 int n[] = {(int)m_height, (int)m_width};
135 int howmany = m_num_of_feats*m_num_of_scales;
136 int idist = m_height*(m_width/2+1), odist = 1;
137 int istride = 1, ostride = m_num_of_feats*m_num_of_scales;
138 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
140 FFTW_PLAN_WITH_THREADS();
141 plan_i_features_all_scales = fftwf_plan_many_dft_c2r(rank, n, howmany,
142 in, inembed, istride, idist,
143 out, onembed, ostride, odist,
146 //FFT inver one channel one scale
147 if(!m_big_batch_mode) {
148 ComplexMat in_i1(m_height,m_width,1);
149 cv::Mat out_i1 = cv::Mat::zeros(m_height, m_width, CV_32FC1);
150 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i1.get_p_data());
151 float *out = reinterpret_cast<float*>(out_i1.data);
153 int n[] = {(int)m_height, (int)m_width};
155 int idist = m_height*(m_width/2+1), odist = 1;
156 int istride = 1, ostride = 1;
157 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
159 FFTW_PLAN_WITH_THREADS();
160 plan_i_1ch = fftwf_plan_many_dft_c2r(rank, n, howmany,
161 in, inembed, istride, idist,
162 out, onembed, ostride, odist,
165 //FFT inver one channel all scales
166 if (m_num_of_scales > 1 && m_big_batch_mode) {
167 ComplexMat in_i1_all(m_height,m_width,m_num_of_scales);
168 cv::Mat out_i1_all = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_scales));
169 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i1_all.get_p_data());
170 float *out = reinterpret_cast<float*>(out_i1_all.data);
172 int n[] = {(int)m_height, (int)m_width};
173 int howmany = m_num_of_scales;
174 int idist = m_height*(m_width/2+1), odist = 1;
175 int istride = 1, ostride = m_num_of_scales;
176 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
178 FFTW_PLAN_WITH_THREADS();
179 plan_i_1ch_all_scales = fftwf_plan_many_dft_c2r(rank, n, howmany,
180 in, inembed, istride, idist,
181 out, onembed, ostride, odist,
186 void Fftw::set_window(const cv::Mat &window)
191 ComplexMat Fftw::forward(const cv::Mat &input)
193 ComplexMat complex_result;
194 if(m_big_batch_mode && input.rows == (int)(m_height*m_num_of_scales)){
195 complex_result.create(m_height, m_width / 2 + 1, m_num_of_scales);
196 fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast<float*>(input.data),
197 reinterpret_cast<fftwf_complex*>(complex_result.get_p_data()));
199 complex_result.create(m_height, m_width / 2 + 1, 1);
200 fftwf_execute_dft_r2c(plan_f, reinterpret_cast<float*>(input.data),
201 reinterpret_cast<fftwf_complex*>(complex_result.get_p_data()));
203 return complex_result;
206 ComplexMat Fftw::forward_raw(float *input, bool all_scales)
212 ComplexMat Fftw::forward_window(const std::vector<cv::Mat> &input)
214 int n_channels = input.size();
215 cv::Mat in_all(m_height * n_channels, m_width, CV_32F);
216 for (int i = 0; i < n_channels; ++i) {
217 cv::Mat in_roi(in_all, cv::Rect(0, i*m_height, m_width, m_height));
218 in_roi = input[i].mul(m_window);
221 if(n_channels > (int) m_num_of_feats)
222 result.create(m_height, m_width/2 + 1, n_channels,m_num_of_scales);
224 result.create(m_height, m_width/2 + 1, n_channels);
226 float *in = reinterpret_cast<float*>(in_all.data);
227 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(result.get_p_data());
229 if (n_channels <= (int) m_num_of_feats)
230 fftwf_execute_dft_r2c(plan_fw, in, out);
232 fftwf_execute_dft_r2c(plan_fw_all_scales, in, out);
237 cv::Mat Fftw::inverse(const ComplexMat &input)
239 int n_channels = input.n_channels;
240 cv::Mat real_result(m_height, m_width, CV_32FC(n_channels));
241 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(input.get_p_data());
242 float *out = reinterpret_cast<float*>(real_result.data);
245 fftwf_execute_dft_c2r(plan_i_1ch, in, out);
246 else if(m_big_batch_mode && n_channels == (int) m_num_of_scales)
247 fftwf_execute_dft_c2r(plan_i_1ch_all_scales, in, out);
248 else if(m_big_batch_mode && n_channels == (int) m_num_of_feats * (int) m_num_of_scales)
249 fftwf_execute_dft_c2r(plan_i_features_all_scales, in, out);
251 fftwf_execute_dft_c2r(plan_i_features, in, out);
253 return real_result/(m_width*m_height);
256 float* Fftw::inverse_raw(const ComplexMat &input)
263 fftwf_destroy_plan(plan_f);
264 fftwf_destroy_plan(plan_fw);
265 fftwf_destroy_plan(plan_i_features);
266 fftwf_destroy_plan(plan_i_1ch);
268 if (m_big_batch_mode) {
269 fftwf_destroy_plan(plan_f_all_scales);
270 fftwf_destroy_plan(plan_i_features_all_scales);
271 fftwf_destroy_plan(plan_fw_all_scales);
272 fftwf_destroy_plan(plan_i_1ch_all_scales);