Как работает алгоритм фильтра Гаусса в OpenCV

StackOverflow https://stackoverflow.com/questions/933540

  •  06-09-2019
  •  | 
  •  

Вопрос

Я пишу свой собственный фильтр Гаусса, но он очень медленный.

Алгоритм Гаусса OpenCV намного быстрее, в 20 раз, чем мой гауссов фильтр.Я хочу переписать гауссов алгоритм OpenCV в своем проекте и не хочу включать opencv в свой проект.

Однако,

Может ли кто -нибудь дать мне описание алгоритма, исходный код OpenCV кажется слишком сложным для понимания?

Это было полезно?

Решение

У фильтра Гаусса есть свойство, позволяющее очень легко ускорить процесс:фильтр можно применять в обоих измерениях независимо.Вы определяете одномерный фильтр, работающий вертикально, и другой фильтр, работающий горизонтально, и применяете их оба;это дает тот же эффект, что и один фильтр, примененный в двух измерениях.

Кроме того, вам, вероятно, придется взглянуть на SIMD-инструкции например SSE3 доступен для вашего процессора.

Другие советы

Чтобы ответить на вторую часть вашего вопроса, размытие по Гауссу — это просто трехмерная гауссова поверхность, применяемая в качестве ядра свертки к изображению. Википедия есть отличная ссылка на сам алгоритм, но по сути вы берете значения кривой Гаусса, конвертируете их в квадратную матрицу и умножаете на каждый пиксель вашего изображения, например:

Kernel:               
[0 1 2 0 0
1 4 6 4 1      X   Iterate over every single pixel in the image
2 6 10 6 2
1 4 6 4 1
0 1 2 1 0]

(Обратите внимание, что это всего лишь образец ядра, существуют очень специфические уравнения, которые, в зависимости от ваших гауссовских переменных, вы получите разные результаты)

Чтобы ответить на часть вашего вопроса, связанную с производительностью, общая скорость этого алгоритма будет зависеть от нескольких вещей, при условии, что изображение постоянного размера.Допустим, изображение состоит из пикселей NxM, а ядро ​​свертки — пикселей PxP.Тебе придется сделать PпN*M операций.Чем больше P, тем больше операций вам придется выполнить для данного изображения.Вы можете поэкспериментировать с алгоритмом, который вы здесь используете, выполняя очень специфические математические вычисления на основе строк или столбцов.

Реализация также очень важна.Если вы хотите добиться максимальной эффективности, вам, вероятно, захочется использовать самые сложные инструкции, которые предлагает ваша архитектура.Если вы используете чип Intel x86, вам, вероятно, захочется получить лицензию на примитивы производительности Intel (IPP) и напрямую вызывать эти инструкции.IIRC, OpenCV использует IPP, когда он доступен...

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

Попробуйте проверить здесь.Вы хотите заранее определить дискретную гауссову матрицу, а затем свернуть ее с изображением.

Если ваше ядро ​​свертки относительно велико и вы реализуете прямую свертку, разница в производительности может быть связана с тем, что OpenCV реализует свертку с использованием быстрого преобразования Фурье (БПФ).

Ненавижу быть педантичным, но вы просите алгоритм, то есть точную последовательность шагов, необходимых для выполнения задачи.У вас уже есть алгоритм Гаусса.Итак, ключевой момент вашего вопроса - это когда вы о чем-то просите Быстрее, что не то же самое, что запросить алгоритм.

Чтобы ответить на Быстрее вопрос: вы хотите знать, как OpenCV оптимизирует свой код, а это очень техническая и широкая тема.Я бы рискнул предположить, что он использует язык ассемблера и функции, специфичные для графического процессора.Я бы начал с изучения ассемблера и исследования пакета CUDA, чтобы воспользоваться преимуществами вашего графического процессора.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top