Быстрый способ реализации 2D свертки в C - PullRequest
5 голосов
/ 24 марта 2009

Я пытаюсь реализовать алгоритм видения, который включает в себя этап предварительной фильтрации с использованием фильтра Лапласа Гаусса 9x9. Можете ли вы указать на документ, который кратко объясняет реализацию быстрых фильтров? Я думаю, что я должен использовать БПФ для наиболее эффективной фильтрации.

Ответы [ 3 ]

10 голосов
/ 24 марта 2009

Вы уверены, что хотите использовать БПФ? Это будет преобразование целого массива, которое будет дорогим. Если вы уже выбрали сверточный фильтр 9x9, вам не нужно использовать БПФ.

Как правило, самый дешевый способ сделать свертку в C - это создать цикл, который перемещает указатель на массив, суммируя свернутые значения в каждой точке и записывая данные в новый массив. Затем этот цикл можно распараллелить, используя ваш любимый метод (векторизация компилятора, библиотеки MPI, OpenMP и т. Д.).

Относительно границ:

  • Если вы предполагаете, что значения равны 0 за пределами границ, то добавьте 4-элементную границу 0 к вашему 2d массиву точек. Это позволит избежать необходимости использования операторов if для обработки границ, которые дороги.
  • Если ваши данные переносятся по границам (то есть периодически), используйте модуль по модулю или добавьте 4-элементную границу, которая копирует противоположную сторону сетки (abcdefg -> fgabcdefgab для 2 точек). ** Примечание: это то, что вы неявно предполагаете при любом виде преобразования Фурье, включая БПФ **. Если это не так, вам нужно будет учесть это, прежде чем выполнять БПФ.

4 балла связаны с тем, что максимальное перекрытие границ ядра 9x9 составляет 4 балла за пределами основной сетки. Таким образом, для ядра 2n + 1 x 2n + 1 необходимо n точек границы.

Если вам нужно, чтобы эта свертка была действительно быстрой, и / или ваша сетка велика, рассмотрите возможность ее разбиения на более мелкие части, которые можно хранить в кеше процессора и, таким образом, вычислять намного быстрее. Это также относится к любой разгрузке GPU, которую вы, возможно, захотите сделать (они идеально подходят для такого типа вычислений с плавающей запятой).

2 голосов
/ 24 марта 2009

Вот ссылка на теорию http://hebb.mit.edu/courses/9.29/2002/readings/c13-1.pdf

А вот ссылка на fftw, довольно неплохую библиотеку FFT, которую я использовал в прошлом (проверьте лицензии, чтобы убедиться, что она подходит) http://www.fftw.org/

Все, что вы делаете, это БПФ ваш образ и ядро ​​(матрица 9x9). Умножим вместе, затем вернемся.

Тем не менее, с матрицей 9x9 вам все же может быть лучше делать это в реальных координатах (просто с двойной петлей над пикселями изображения и матрицей). Попробуйте оба пути!

1 голос
/ 13 августа 2009

На самом деле вам не нужно использовать размер FFT, достаточно большой, чтобы вместить все изображение. Вы можете сделать много меньших перекрывающихся 2d ffts. Можно выполнить поиск для «быстрой свертки», «сохранения с перекрытием», «добавления с перекрытием».

Однако для ядра 9x9. Возможно, вы не увидите большого преимущества в скорости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...