Как использовать предварительное умножение во время свертки изображения для решения проблемы альфа-выхода за обрез?

Я пытаюсь применить размытие рамки к прозрачному изображению, и у меня появляется "темный ореол" по краям .

Джерри Хакстейбл имеет краткое упоминание о проблеме и очень хорошую демонстрацию, показывающую, что проблема возникает:

enter image description here

Но я, хоть убей, не могу понять, как " pre -множенная альфа "может решить проблему. А теперь очень простой пример. У меня есть изображение 3x3, содержащее один красный и один зеленый пиксели:

enter image description here

На самом деле оставшиеся пиксели прозрачны:

enter image description here

Теперь мы применим к изображению размытие 3x3 Box Blur. Для простоты мы Я рассчитываю только новое значение центрального пикселя. Принцип работы блочного размытия заключается в том, что поскольку у нас есть 9-позиционный квадрат (3x3, называемый ядром), мы берем 1/9 каждого пикселя в ядре и складываем его:

enter image description here

Итак

finalRed =   1/9 * red1 + 1/9 * red2 + 1/9 * red3+ ... + 1/9 * red9
finalGreen = 1/9*green1 + 1/9*green2 + 1/9*green3+ ... + 1/9*green9
finalBlue =  1/9* blue1 + 1/9* blue2 + 1/9* blue3+ ... + 1/9* blue9
finalAlpha = 1/9*alpha1 + 1/9*alpha2 + 1/9*alpha3+ ... + 1/9*alpha9

В этом очень упрощенном виде Например, вычисления становятся очень простыми:

finalRed =   1/9 * 255
finalGreen = 1/9 * 255
finalBlue =  0
finalAlpha = 1/9*255 + 1/9*255

Это дает мне окончательное значение цвета:

finalRed =   28
finalGreen = 28
finalBlue =  0
finalAlpha = 56 (22.2%)

enter image description here

Этот цвет слишком темный. Когда я выполняю размытие прямоугольника 3px на том же изображении 3x3 пикселя в Photoshop, я получаю то, что ожидал:

enter image description here

Что более четкое при отображении поверх белого:

enter image description here


На самом деле я выполняю размытие поля на растровом изображении, содержащем прозрачный текст, и текст приобретает характерную темноту по краям:

enter image description here

Я начинаю с растрового изображения GDI + в формате PixelFormat32bppARGB


Как использовать "предварительно умноженную альфа" при применении ядра свертки 3x3?

Любой ответ должен включать новый forumla, поскольку:

final = 1/9*(pixel1+pixel2+pixel3...+pixel9)

Я получаю неправильный ответ.


Изменить: Более простой пример:

Я выполню эта математика со значениями цвета и альфа в диапазоне 0..1:

enter image description here

Я собираюсь применить фильтр свертки размытия прямоугольника к среднему пикселю:

ARGB'
      = 1/9 * (0,1,0,1) + 1/9 * (0,0,0,0) + 1/9 * (0,0,0,0) + 
        1/9 * (0,1,0,1) + 1/9 * (0,0,0,0) + 1/9 * (0,0,0,0) + 
        1/9 * (0,1,0,1) + 1/9 * (0,0,0,0) + 1/9 * (0,0,0,0);

      = (0, 0.11, 0, 0.11) + (0,0,0,0) + (0,0,0,0) +
        (0, 0.11, 0, 0.11) + (0,0,0,0) + (0,0,0,0) +
        (0, 0.11, 0, 0.11) + (0,0,0,0) + (0,0,0,0)

      = (0, 0.33, 0, 0.33)

Что дает довольно прозрачный темно-зеленый цвет.

enter image description here

Что это не то, что я ожидаю увидеть. И для сравнения Photoshop Box Blur:

enter image description here

Если я предполагаю, что (0, 0,33, 0, 0,33) - это предварительно умноженная альфа, и не умножая ее, я получаю:

(0, 1, 0, 0.33)

enter image description here

Что выглядит правильно для моего непрозрачного примера; но я не знаю, что делать, когда начинаю задействовать частично прозрачные пиксели.

См. также

13
задан Ian Boyd 10 February 2011 в 19:02
поделиться