23 #ifndef _SEFRAMEWORK_CONVOLUTION_DFT_H
24 #define _SEFRAMEWORK_CONVOLUTION_DFT_H
45 template<
typename T = SeFloat,
class TPadding = PaddedImage<T, Reflect101Coordinates>>
105 auto context = Euclid::make_unique<ConvolutionContext>();
108 context->m_padded_width = model_ptr->getWidth() +
m_kernel->getWidth() - 1;
109 context->m_padded_height = model_ptr->getHeight() +
m_kernel->getHeight() - 1;
116 context->m_total_size = context->m_padded_width * context->m_padded_height;
119 context->m_real_buffer.resize(context->m_total_size);
120 context->m_complex_buffer.resize(context->m_total_size);
121 context->m_kernel_transform.resize(context->m_total_size);
125 context->m_real_buffer, context->m_complex_buffer);
127 context->m_complex_buffer, context->m_real_buffer);
130 padKernel(context->m_padded_width, context->m_padded_height, context->m_real_buffer.begin());
150 template <
typename ...Args>
153 Args... padding_args)
const {
158 auto padded = TPadding::create(image_ptr,
160 std::forward<Args>(padding_args)...);
174 float re = a.real() * b.real() - a.imag() * b.imag();
175 float im = a.real() * b.imag() + a.imag() * b.real();
184 auto wpad = (context->
m_padded_width - image_ptr->getWidth()) / 2;
186 for (
int y = 0;
y < image_ptr->getHeight(); ++
y) {
187 for (
int x = 0;
x < image_ptr->getWidth(); ++
x) {
188 image_ptr->setValue(
x,
y,
206 template <
typename ...Args>
208 auto context =
prepare(image_ptr);
224 if (width % 2 == 0) center.
m_x--;
225 if (height % 2 == 0) center.m_y--;
232 auto chunk = img->getChunk(0, 0, img->getWidth(), img->getHeight());
233 for (
int y = 0;
y < chunk->getHeight(); ++
y) {
234 for (
int x = 0;
x < chunk->getWidth(); ++
x) {
235 *out++ = chunk->getValue(
x,
y);
246 #endif // _SEFRAMEWORK_CONVOLUTION_DFT_H