Где центрировать ядро при использовании FFTW для свертки изображений?
=====================================================================

Я пытаюсь использовать FFTW для свертки изображения.

Сначала, чтобы проверить, работает ли система должным образом, я выполнил fft, затем обратный fft, и мог получить точно такое же изображение.

Затем, сделав небольшой шаг вперед, я использовал тождественное ядро (т.е. kernel [0] [0] = 1, тогда как все остальные компоненты равны 0). Я взял компонентное произведение между изображением и ядром (оба в частотной области), затем сделал обратное FFT. Теоретически я должен быть в состоянии получить идентичное изображение обратно. Но результат, который я получил, очень даже не похож на исходное изображение. Я подозреваю, что это как-то связано с тем, где я центрирую свое ядро перед тем, как переместить его в частотную область (поскольку я помещаю «1» в kernel [0] [0], это в основном означает, что я центрировал положительную часть в верхний левый). Может ли кто-нибудь просветить меня о том, что здесь идет не так?

**the indexes** выборок должно быть от -n / 2 ... 0 ... n / 2 -1, поэтому, если размерность нечетная, центр вокруг середины. Если размерность четная, отцентрируйте ее так, чтобы до нового 0 у вас было на одну выборку больше, чем после нового 0.

Например. -4, -3, -2, -1, 0, 1, 2, 3 для ширины / высоты 8 или -3, -2, -1, 0, 1, 2, 3 для ширины / высоты 7 ,

The FFT is relative to the middle, in its scale there are negative points.  

In the memory the points are 0...n-1, but the FFT treats them as -ceil(n/2)...floor(n/2), where 0 is -ceil(n/2) and n-1 is floor(n/2)

**The identity matrix** является матрицей нулей с 1 в 0,0 месте (центр - в соответствии с вышеуказанной нумерацией). (В пространственной области.)

В частотной области единичная матрица должна быть постоянной (все действительные значения 1 или 1 / (N * M) и все мнимые значения 0).

Если вы не получите этот результат, тогда матрице идентификации может потребоваться заполнение по-разному (влево и вниз, а не вокруг всех сторон) - это может зависеть от реализации FFT.

Центр**each dimension** отдельно (это центрирование индекса, без изменений в реальной памяти).

Вам, вероятно, понадобится**pad the image** (после центрирования) на целую степень 2 в каждом измерении (2 ^ n * 2 ^ m, где n не должно равняться m).

Pad relative to FFT's 0,0 location (to center, not corner) by copying existing pixels into a new larger image, using center-based-indexes in both source and destination images (e.g. (0,0) to (0,0), (0,1) to (0,1), (1,-2) to (1,-2))

Предполагая, что ваше БПФ использует обычные ячейки с плавающей точкой, а не сложные ячейки,**the complex image** должен иметь размер 2 * ceil (2 / n) * 2 * ceil (2 / m), даже если вам не нужна полная мощность 2 (так как он имеет половину выборок, но выборки сложные).

Если ваше изображение имеет**more than one color channel**сначала вам нужно изменить его, чтобы канал был наиболее значимым в субпиксельном порядке, а не наименее значимым. Вы можете изменить форму и площадку за один раз, чтобы сэкономить время и пространство.

Не забывайте**FFTSHIFT** после IFFT. (Поменять квадранты.)  

Результат IFFT равен 0 ... n-1. Вы должны взять пиксели floor (n / 2) + 1..n-1 и переместить их до 0 ... floor (n / 2).  

Это делается путем копирования пикселей в новое изображение, копирования этажа (n / 2) +1 в ячейку памяти 0, этажа (n / 2) +2 в ячейку памяти 1, ..., n-1 в память- Этаж местоположения (n / 2), затем 0 к ceil-местоположению памяти (n / 2), 1 к ceil-местоположению памяти (n / 2) +1, ..., floor (n / 2) к местоположению памяти n -1.

Когда ты**multiply in the frequency domain**Помните, что сэмплы являются сложными (одна ячейка реальная, а другая воображаемая), поэтому вы должны использовать сложное умножение.

Результат может нуждаться в делении на N ^ 2 * M ^ 2, где N - размер n после заполнения (и аналогично для M и m). - Вы можете сказать это путем (a. Просмотра значений частотной области матрицы тождества, b. Сравнения результата с вводом.)



 что ваше понимание ядра Identity может быть неверным. Ядро идентификации должно иметь 1 в центре двумерного ядра, а не 0, 0.

Например, для 3 x 3 у вас есть следующие настройки:

Так должно быть

Проверьте это также

[Что такое "ничего не делать"? сверточное ядро](https://stackoverflow.com/questions/5824704/what-is-the-do-nothing-convolution-kernel)

также посмотрите здесь, внизу страницы 3.

<http://www.fmwconcepts.com/imagemagick/digital_image_filtering.pdf>