Ответ 1
Я не знал, как это работает, но натолкнулся на пару действительно хороших страниц, чтобы понять это. В основном это происходит следующим образом:
- Что противоположно заточенному изображению? Расплывчатый. Мы знаем, как размыть изображение. Дублируйте исходное изображение и выполните гауссовское размытие. Это ползунок Radius в большинстве диалогов USM.
- Хорошо, если мы вычитаем размытость, нам следует оставить детали, которые являются высококонтрастными! Подумайте об этом: если вы размываете небо, оно по-прежнему выглядит как небо. Вычтите пиксели, и вы получите sky-sky = 0. Если вы размываете логотип Coke, вы получаете размытый логотип Coke. Вычтите его, и вы останетесь с краями. Так что разница
- Что заставляет вещи выглядеть острее? Контраст. Дублируйте исходное изображение снова и увеличивайте контрастность. Сумма, на которую вы увеличиваете контраст, - это ползунок "Сумма" или "Интенсивность" в большинстве диалогов USM.
-
Наконец, все вместе. На данный момент у вас есть три вещи:
- Высококонтрастная версия исходного изображения.
- Разница размытого изображения и вашего оригинала (этот слой в основном черный). Этот слой является нерезкой маской
- Оригинальный
Алгоритм выглядит следующим образом: Посмотрите на пиксель от нерезкой маски и узнайте его яркость (яркость). Если яркость 100%, используйте значение из высококонтрастного изображения для этого пикселя. Если это 0%, используйте значение из исходного изображения для этого пикселя. Если он где-то посередине, смешайте значения двух пикселей, используя некоторый вес. При желании измените только значение пикселя, если оно изменится более чем на определенную величину (это ползунок Threshold в большинстве диалогов USM).
Поместите все это вместе, и у вас есть ваше изображение!
Здесь некоторый псевдокод:
color[][] usm(color[][] original, int radius, int amountPercent, int threshold) {
// copy original for our return value
color[][] retval = copy(original);
// create the blurred copy
color[][] blurred = gaussianBlur(original, radius);
// subtract blurred from original, pixel-by-pixel to make unsharp mask
color[][] unsharpMask = difference(original, blurred);
color[][] highContrast = increaseContrast(original, amountPercent);
// assuming row-major ordering
for(int row = 0; row < original.length; row++) {
for(int col = 0; col < original[row].length; col++) {
color origColor = original[row][col];
color contrastColor = highContrast[row][col];
color difference = contrastColor - origColor;
float percent = luminanceAsPercent(unsharpMask[row][col]);
color delta = difference * percent;
if(abs(delta) > threshold)
retval[row][col] += delta;
}
}
return retval;
}
Примечание. Я не специалист по графике, но это то, что я смог изучить на страницах, которые я нашел. Прочитайте их самостоятельно и убедитесь, что вы согласны с моими выводами, но выполнение вышеописанного должно быть достаточно простым, так что сделайте снимок!