13 void Fftw::init(unsigned width, unsigned height)
22 #if defined(ASYNC) || defined(OPENMP)
27 std::cout << "FFT: FFTW" << std::endl;
29 std::cout << "FFT: cuFFTW" << std::endl;
33 void Fftw::set_window(const cv::Mat &window)
38 ComplexMat Fftw::forward(const cv::Mat &input)
40 cv::Mat complex_result(m_height, m_width / 2 + 1, CV_32FC2);
44 std::unique_lock<std::mutex> lock(fftw_mut);
45 fftw_plan_with_nthreads(2);
48 fftw_plan_with_nthreads(omp_get_max_threads());
51 plan_f = fftwf_plan_dft_r2c_2d(m_height, m_width,
52 reinterpret_cast<float*>(input.data),
53 reinterpret_cast<fftwf_complex*>(complex_result.data),
55 fftwf_execute(plan_f);
56 }else{fftwf_execute_dft_r2c(plan_f,reinterpret_cast<float*>(input.data),reinterpret_cast<fftwf_complex*>(complex_result.data));}
58 return ComplexMat(complex_result);
61 ComplexMat Fftw::forward_window(const std::vector<cv::Mat> &input)
63 int n_channels = input.size();
64 cv::Mat in_all(m_height * n_channels, m_width, CV_32F);
65 for (int i = 0; i < n_channels; ++i) {
66 cv::Mat in_roi(in_all, cv::Rect(0, i*m_height, m_width, m_height));
67 in_roi = input[i].mul(m_window);
69 cv::Mat complex_result(n_channels*m_height, m_width/2+1, CV_32FC2);
71 float *in = reinterpret_cast<float*>(in_all.data);
72 fftwf_complex *out = reinterpret_cast<fftwf_complex*>(complex_result.data);
75 int n[] = {(int)m_height, (int)m_width};
76 int howmany = n_channels;
77 int idist = m_height*m_width, odist = m_height*(m_width/2+1);
78 int istride = 1, ostride = 1;
79 int *inembed = NULL, *onembed = NULL;
82 std::unique_lock<std::mutex> lock(fftw_mut);
83 fftw_plan_with_nthreads(2);
86 fftw_plan_with_nthreads(omp_get_max_threads());
88 plan_fw = fftwf_plan_many_dft_r2c(rank, n, howmany,
89 in, inembed, istride, idist,
90 out, onembed, ostride, odist,
92 fftwf_execute(plan_fw);
93 }else{fftwf_execute_dft_r2c(plan_fw,in,out);}
95 ComplexMat result(m_height, m_width/2 + 1, n_channels);
96 for (int i = 0; i < n_channels; ++i)
97 result.set_channel(i, complex_result(cv::Rect(0, i*m_height, m_width/2+1, m_height)));
102 cv::Mat Fftw::inverse(const ComplexMat &inputf)
104 int n_channels = inputf.n_channels;
105 cv::Mat real_result(m_height, m_width, CV_32FC(n_channels));
106 std::vector<std::complex<float>> vec = inputf.get_p_data();
107 fftwf_complex *in = reinterpret_cast<fftwf_complex*>(vec.data());
108 float *out = reinterpret_cast<float*>(real_result.data);
113 int n[] = {(int)m_height, (int)m_width};
114 int howmany = n_channels;
115 int idist = m_height*(m_width/2+1), odist = 1;
116 int istride = 1, ostride = n_channels;
117 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
120 std::unique_lock<std::mutex> lock(fftw_mut);
121 fftw_plan_with_nthreads(2);
124 fftw_plan_with_nthreads(omp_get_max_threads());
127 plan_if = fftwf_plan_many_dft_c2r(rank, n, howmany,
128 in, inembed, istride, idist,
129 out, onembed, ostride, odist,
131 fftwf_execute(plan_if);
132 }else{fftwf_execute_dft_c2r(plan_if,in,out);}
136 int n[] = {(int)m_height, (int)m_width};
137 int howmany = n_channels;
138 int idist = m_height*(m_width/2+1), odist = 1;
139 int istride = 1, ostride = n_channels;
140 int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
143 std::unique_lock<std::mutex> lock(fftw_mut);
144 fftw_plan_with_nthreads(2);
147 fftw_plan_with_nthreads(omp_get_max_threads());
150 plan_ir = fftwf_plan_many_dft_c2r(rank, n, howmany,
151 in, inembed, istride, idist,
152 out, onembed, ostride, odist,
154 fftwf_execute(plan_ir);
155 }else{fftwf_execute_dft_c2r(plan_ir,in,out);}
158 return real_result/(m_width*m_height);
163 fftwf_destroy_plan(plan_f);
164 fftwf_destroy_plan(plan_fw);
165 fftwf_destroy_plan(plan_if);
166 fftwf_destroy_plan(plan_ir);