-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDftPatch.hpp
94 lines (81 loc) · 2.81 KB
/
DftPatch.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
* DftPatch.hpp
*
* Created on: 11/feb/2015
* Author: nicola pierazzo <[email protected]>
*/
#ifndef DA3D_DFTPATCH_HPP_
#define DA3D_DFTPATCH_HPP_
#include <fftw3.h>
#include <cassert>
#include <complex>
namespace da3d {
class DftPatch {
public:
DftPatch(int rows, int columns, int channels = 1);
~DftPatch();
void ToFreq();
void ToSpace();
int rows() const { return rows_; }
int columns() const { return columns_; }
int frows() const { return rows_; }
int fcolumns() const { return fcolumns_; }
int channels() const { return channels_; }
float& space(int col, int row, int chan = 0);
std::complex<float>& freq(int col, int row, int chan = 0);
private:
float *space_;
std::complex<float> *freq_;
fftwf_plan plan_forward_;
fftwf_plan plan_backward_;
int rows_, columns_, fcolumns_, channels_;
};
inline float& DftPatch::space(int col, int row, int chan) {
assert(0 <= col && col < columns_);
assert(0 <= row && row < rows_);
assert(0 <= chan && chan < channels_);
return space_[row * columns_ * channels_ + col * channels_ + chan];
}
inline std::complex<float>& DftPatch::freq(int col, int row, int chan) {
assert(0 <= col && col < fcolumns_);
assert(0 <= row && row < rows_);
assert(0 <= chan && chan < channels_);
return freq_[row * fcolumns_ * channels_ + col * channels_ + chan];
}
inline DftPatch::DftPatch(int rows, int columns, int channels)
: rows_(rows), columns_(columns), fcolumns_(columns / 2 + 1), channels_(channels) {
int N = rows * columns * channels;
int N_half = rows * fcolumns_ * channels;
space_ = reinterpret_cast<float *>(fftwf_malloc(sizeof(float) * N));
freq_ = reinterpret_cast<std::complex<float> *>(fftwf_malloc(
sizeof(fftwf_complex) * N_half));
int n[] = {rows, columns};
#pragma omp critical
{
plan_forward_ = fftwf_plan_many_dft_r2c(2, n, channels, space_, NULL,
channels, 1,
reinterpret_cast<fftwf_complex *>(freq_),
NULL, channels, 1, FFTW_MEASURE);
plan_backward_ = fftwf_plan_many_dft_c2r(2, n, channels,
reinterpret_cast<fftwf_complex *>(freq_),
NULL, channels, 1, space_, NULL,
channels, 1, FFTW_MEASURE);
}
}
inline DftPatch::~DftPatch() {
fftwf_free(space_);
fftwf_free(freq_);
fftwf_destroy_plan(plan_forward_);
fftwf_destroy_plan(plan_backward_);
}
inline void DftPatch::ToFreq() {
fftwf_execute(plan_forward_);
}
inline void DftPatch::ToSpace() {
fftwf_execute(plan_backward_);
for (int i = 0; i < rows_ * columns_ * channels_; ++i) {
space_[i] /= rows_ * columns_;
}
}
} /* namespace da3d */
#endif // DA3D_DFTPATCH_HPP_