Размывание поля в C#
Размывание поля В этой статье мы изучим, как реализовать для изображения эффект размывания поля в C#. Размывание поля выполняется с помощью свертки изображения, понятия, которое относится к широкому диапазону фильтров изображений. Свертка Свертка — это линейная операция в сигнале и ядре. В данном случае сигнал — это изображение, а ядро — это фильтр. В частности, при дискретной обработке изображений свертка — это скалярное произведение всех точек в сигнале и в ядре. Очень простой пример: сигнал: [1, 2, 3, 4] ядро: [5, 6, 7] свертка: [1 * 5 + 2 * 6 + 3 * 7, 2 * 5 + 3 * 6 + 4 * 7, 3 * 5 + 4 * 6 + 0 * 7, 4 * 5 + 0 * 6 + 0 * 7] Это очень простой пример, но он показывает основы сворачивания. Обратите внимание, что он воспринимает значительное число операций, в данном случае для наших простых 4x1, свернутых с 3x1, потребовалось 12 умножений и 8 сложений. Это важно учитывать. Также следует отметить, что вблизи границы мы выходим за пределы сигнала, чтобы выполнить свертку должным образом, поэтому вычисления выполняются со значениями 0. Дополнение нулями — это только один из многих возможных способов устранения этой проблемы. Ядро поля Чтобы размыть изображение, нам потребуется применить двумерную (2D) свертку (поскольку изображения имеют высоту и ширину). Вопрос в том, как будет выглядеть ядро. В случае правого ядра можно просто свернуть его с любым изображением для размывания. Чтобы получить ядро, потребуется несколько углубиться в процесс свертки. Как было описано выше, каждый пиксель — это скалярное произведение ядра и области вокруг этого пикселя. Другими словами, ядро будет указывать, как один пиксель должен объединяться с пикселями вокруг него. Далее приводится пример ядра: [0, 0, 0] [0, 1, 0] [0, 0, 0] Предположим, что при применении ядра к изображению оно располагается в центре каждого пикселя. Что произойдет? Абсолютно ничего. Это ядро приведет к значению, полностью состоящему из текущего пикселя (значение 1), и в нем не будет ничего от соседних пикселей (значение 0). (Кстати, такое ядро называется разностным). Давайте рассмотрим другое ядро: [0, 0, 0 ] [0, 0.5, 0.5] [0, 0, 0 ] Подумаем об этом секунду. В данном случае полученный в результате пиксель является комбинацией половины значения текущего пикселя и половиной значения его соседа справа. Это размывание, поскольку каждый пиксель равномерно распределяется с соседним. Если мы применим аналогичное ядро к каждому отдельному пикселю, то получим нечто, очень похожее на усреднение значений пикселей с соседними. Усреднение уменьшает яркость всего изображения, таким образом мы получаем размывание. Итак, мы окончательно получаем ядро размывания поля: [1/9, 1/9, 1/9] [1/9, 1/9, 1/9] [1/9, 1/9, 1/9] Это ядро будет равномерно распределять значения каждого пикселя в изображении. Как можно управлять величиной размывания? С помощью размера ядра. Большое ядро будет усреднять большую область, таким образом сильнее уменьшая яркость. Маленькое ядро будет размывать гораздо меньше. Завершающие примечания Демонстрационное приложение использует класс FastBitmap, который инкапсулирует логику для более быстрой обработки изображений в C#. Следует также отметить, что существуют две функции размытия, BoxBlur и FastBoxBlur. Разница между ними в том, что BoxBlur применяет одно ядро размытия поля, как описано выше. FastBoxBlur использует свойство свертки, называемое разделяемостью фильтров, которое, если кратко объяснить, означает, что мы можем разделить одно ядро поля на два меньших. Затем две свертки последовательно применяются с этими меньшими фильтрами. Результат будет тот же, но общее число операций гораздо меньше. Также следует знать, что размывание поля — это только одно из многих размываний. Распространенное размывание называется гауссовым размыванием и работает точно таким же способом (включая разделяемость фильтра для ускорения). Единственное различие состоит в том, что каждый пиксель не равномерно распределяется со всеми своими соседями; пиксели, расположенные ближе к центру, имеют больший вес. |
Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.