-
Notifications
You must be signed in to change notification settings - Fork 9
/
DCTPatch.hpp
144 lines (125 loc) · 4.02 KB
/
DCTPatch.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* DCTPatch.hpp
*
* Created on: 11/feb/2015
* Author: nicola
*/
#ifndef DCTDENOISING_DFTPATCH_HPP_
#define DCTDENOISING_DFTPATCH_HPP_
#include <fftw3.h>
#include <cassert>
#include <complex>
namespace imgutils {
/*! \brief DCTPatch object
*
* DCTPatch contains a patch and its DCT transform,
* and allows to convert back and forth between the two
*/
class DCTPatch {
public:
DCTPatch(int rows, int columns, int channels = 1);
// disable copy constructor
DCTPatch(const DCTPatch&) = delete;
DCTPatch& operator=(const DCTPatch&) = delete;
// default move constructor
DCTPatch(DCTPatch&&) = default;
DCTPatch& operator=(DCTPatch&&) = default;
~DCTPatch();
void ToFreq();
void ToSpace();
int rows() const { return rows_; }
int columns() const { return columns_; }
int channels() const { return channels_; }
float& space(int col, int row, int chan = 0);
float& freq(int col, int row, int chan = 0);
private:
float *space_;
float *freq_;
fftwf_plan plan_forward_;
fftwf_plan plan_backward_;
const int rows_, columns_, channels_;
const float norm_factor_;
};
/*! \brief Access the spatial representation of the patch
*
* Returns pixel value
*/
inline float& DCTPatch::space(int col, int row, int chan) {
assert(0 <= col && col < columns_);
assert(0 <= row && row < rows_);
assert(0 <= chan && chan < channels_);
return space_[chan * rows_ * columns_ + row * columns_ + col];
}
/*! \brief Access the DCT representation of the patch
*
* Returns freq coefficient
*/
inline float& DCTPatch::freq(int col, int row, int chan) {
assert(0 <= col && col < columns_);
assert(0 <= row && row < rows_);
assert(0 <= chan && chan < channels_);
return freq_[chan * rows_ * columns_ + row * columns_ + col];
}
inline DCTPatch::DCTPatch(int rows, int columns, int channels)
: rows_(rows), columns_(columns), channels_(channels),
norm_factor_(std::sqrt(.25f / (rows * columns))) {
int N = rows * columns * channels;
space_ = reinterpret_cast<float *>(fftwf_malloc(sizeof(float) * N));
freq_ = reinterpret_cast<float *>(fftwf_malloc(sizeof(float) * N));
int n[] = {rows, columns};
fftwf_r2r_kind dct2[] = {FFTW_REDFT10, FFTW_REDFT10};
fftwf_r2r_kind idct2[] = {FFTW_REDFT01, FFTW_REDFT01};
#pragma omp critical
{
plan_forward_ = fftwf_plan_many_r2r(2, n, channels, space_, NULL, 1,
rows * columns, freq_, NULL, 1,
rows * columns, dct2,
FFTW_MEASURE | FFTW_DESTROY_INPUT);
plan_backward_ = fftwf_plan_many_r2r(2, n, channels, freq_, NULL, 1,
rows * columns, space_, NULL, 1,
rows * columns, idct2,
FFTW_MEASURE | FFTW_DESTROY_INPUT);
}
}
inline DCTPatch::~DCTPatch() {
fftwf_free(space_);
fftwf_free(freq_);
fftwf_destroy_plan(plan_forward_);
fftwf_destroy_plan(plan_backward_);
}
/*! \brief Computes the isometric DCT(Type2) of space, stores result in freq
*/
inline void DCTPatch::ToFreq() {
fftwf_execute(plan_forward_);
// normalize coefficients
for (int ch = 0; ch < channels_; ++ch) {
for (int row = 0; row < rows_; ++row) {
freq(0, row, ch) /= sqrt(2.f);
for (int col = 0; col < columns_; ++col) {
freq(col, row, ch) *= norm_factor_;
}
}
for (int col = 0; col < columns_; ++col) {
freq(col, 0, ch) /= sqrt(2.f);
}
}
}
/*! \brief Computes the isometric iDCT(Type3) of freq, stores result in space
*/
inline void DCTPatch::ToSpace() {
// normalize coefficients
for (int ch = 0; ch < channels_; ++ch) {
for (int row = 0; row < rows_; ++row) {
freq(0, row, ch) *= sqrt(2.f);
for (int col = 0; col < columns_; ++col) {
freq(col, row, ch) *= norm_factor_;
}
}
for (int col = 0; col < columns_; ++col) {
freq(col, 0, ch) *= sqrt(2.f);
}
}
fftwf_execute(plan_backward_);
}
} /* namespace imgutils */
#endif // DCTDENOISING_DFTPATCH_HPP_