Ядра Гаусса отделимы, что означает, что вы можете сначала сделать горизонтальный проход, затем вертикальный проход (или наоборот).Это превращает O (N ^ 2) в O (2N).Это работает для всех разделяемых фильтров, не только для размытия (не все фильтры являются разделяемыми, но многие из них есть, а некоторые "хороши как").
Или, в частном случаефильтра размытия (гауссового или нет), который представляет собой все виды «взвешенных сумм», вы можете воспользоваться интерполяцией текстур, которая может быть быстрее для небольших размеров ядра (но определенно не для больших размеров ядра).
РЕДАКТИРОВАТЬ: изображение для метода "линейной интерполяции"
РЕДАКТИРОВАТЬ (по запросу Джерри Коффина), чтобы суммировать комментарии:
В текстуре "В"метод фильтра, линейная интерполяция будет производить взвешенную сумму смежных текселей в соответствии с обратным расстоянием от местоположения образца до центра текселя.Это делается с помощью аппаратного текстурирования, бесплатно.Таким образом, 16 пикселей могут быть суммированы за 4 выборки.Фильтрация текстур может быть использована в дополнение к разделению ядра.
В изображении примера, в левом верхнем углу, ваш образец (кружок) попадает в центр текселя.То, что вы получаете, аналогично «ближайшему» фильтрованию, вы получаете значение этого текселя.Справа вверху вы находитесь посередине между двумя текселями, в результате получается среднее значение 50/50 между ними (изображено более светлым шейдером синего цвета).В правом нижнем углу вы выбираете между 4 текселями, но несколько ближе к верхнему левому.Это дает вам средневзвешенное значение всех 4, но с весом, смещенным к верхнему левому (самый темный оттенок синего цвета).
Следующие предложения любезно предоставлены datenwolf (см. Ниже):
"Другой метод, который я хотел бы предложить, - это использование в пространстве Фурье, где свертка превращается в простое произведение сигнала, преобразованного Фурье, и ядра, преобразованного Фурье. Хотя преобразование Фурье на самом GPU довольно утомительно для реализацииПо крайней мере, с использованием шейдеров OpenGL. Но это довольно легко сделать в OpenCL. На самом деле, я реализую такие вещи с помощью OpenCL, сейчас большая часть обработки изображений в моем 3D-движке происходит в OpenCL.
OpenCL был специально разработан дляработает на графических процессорах. Быстрое преобразование Фурье на самом деле является примером кода в статье OpenCL в Википедии: en.wikipedia.org/wiki/OpenCL, и да, выигрыш в производительности огромен. FFT выполняется с максимум O (n log n),обратное то же самое. Представление Фурье ядра фильтра можетбыть предварительно вычисленным.Это FFT -> умножение на ядро -> IFFT, которое сводится к O (n + 2n log n) операциям.Обратите внимание, что фактическая свертка там просто O (n).
В случае сепарабельной конечной свертки, подобной гауссовому размытию, решение для разделения превзойдет метод Фурье.Но в случае обобщенных, возможных неразделимых ядер, методы Фурье, вероятно, являются самым быстрым из доступных методов.OpenCL прекрасно интегрируется с OpenGL, например, вы можете использовать буферы OpenGL (текстуры и вершины) как для ввода, так и для вывода программ OpenCL. "