Лапласианская пирамида на базе графического процессора

Я реализовал метод смешивания изображений для бесшовного смешивания, используя простой C++. Теперь я хочу преобразовать этот код для GPU (используя шейдеры OpenGL ES 2 для мобильных устройств). По сути, этот метод создает гауссовы и лапласовские пирамиды для каждого изображения, которые затем комбинируются от низкого разрешения к верхнему (см. также статью «Пирамида Лапласа как компактный код изображения» Берта и др., 1983).

Моя проблема в том, что уровни лапласовской пирамиды могут иметь отрицательные значения, но мои устройства не поддерживают текстуры типа float или integer (например, с использованием расширения ORB_texture_float).

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

  1. Как я могу эффективно реализовать такую ​​пирамиду для графического процессора?
  2. Можно ли рассчитать уровень пирамиды Гаусса/Лапласа без повторения предыдущих уровней?

С уважением,

РЕДАКТИРОВАТЬ Кажется, что нет "хорошего" способа полностью вычислить лапласовские пирамиды на графическом процессоре, за исключением использования двух проходов (один для знаков, один для значений), которые не поддерживают ни знаковые типы (для экземпляр ARB_texture_float) или типы больше байта, когда диапазон данных изображения находится между [0..255]. Моя лапласианская пирамида отлично работает на графических процессорах с расширением ARB_texture_float, но без расширения (и некоторых настроек для сжатия диапазона) пирамида становится «неправильной» из-за сжатия диапазона.


person Hyndrix    schedule 24.09.2012    source источник


Ответы (1)


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

  2. да. Любой уровень в пирамиде Гаусса или Лапласа имеет решение в закрытой форме, основанное на значении сигмы, которое вы хотите вычислить. Рассмотрим базовый случай пирамиды LoG, вычисленной с интервалами сигма = (2/3). Первый уровень пирамиды имеет сигму 2/3 и создается простой сверткой с фильтром LoG 5x5 с сигмой 2/3. Вторая свертка с тем же фильтром создает изображение LoG с сигмой 4/3, и, наконец, третья имеет сигму 6/3 или 2, поэтому мы подвергаем изображение субдискретизации для создания следующего целочисленного уровня пирамиды. Если вы хотите вычислить LoG изображения с сигмой 2, уровни с сигмой 2/3 и 4/3 не нужны — просто выполните субдискретизацию изображения один раз и выполните свертку с фильтром LoG с сигмой 1.

Если вы хотите вычислить LoG при сигма = 20, выполните четырехкратную подвыборку изображения (блоки 16 пикселей становятся 1 пикселем), чтобы получить изображение сигма 16, а затем выполните свертку один раз с фильтром LoG сигма 4/3.

person Thomson Comer    schedule 24.09.2012
comment
Спасибо за подсказки. Правильно ли я понял, что я должен вычислить пирамиду Лапласа дважды (один для знаков, один для абсолютных значений)? - person Hyndrix; 24.09.2012
comment
После переосмысления вашего комментария, возможно, также удастся закодировать знаки RGB в альфа-канале (который я не использую). Это, вероятно, медленнее, чем вычисление пирамиды дважды, но экономит память, которой также не хватает на моих устройствах. - person Hyndrix; 24.09.2012
comment
Хорошая идея использовать альфа-канал, теперь вам не нужно дважды вычислять пирамиду или хранить две пирамиды. Вычислите значение Лапласа через фильтр и сохраните его в переменной со знаком. Поместите abs() подписанной переменной в r/g/b. Разделите переменную со знаком на значение, хранящееся в текстуре, добавьте 1 к результату и сохраните его в альфа-канале. Если значение в альфа-канале равно 0, исходный градиент отрицательный, если два, то градиент положительный. - person Thomson Comer; 25.09.2012