不锋利的面具如何工作?

Bob*_*man 11 algorithm graphics image-processing

我最近一直在玩图像处理,我想知道非锐化掩码算法是如何工作的.我正在查看Gimp的源代码及其实现,但到目前为止,我仍然对它的实际工作方式一无所知.我需要为我正在进行的项目实现它,但我想真正理解我正在使用的算法.

jas*_*p85 28

我不确定它是如何工作的,但是遇到了几个非常好的页面来理解它.基本上它是这样的:

  1. 与锐化图像相反的是什么?一个模糊的.我们知道如何模糊图像.复制原始图像并执行一些高斯模糊处理.这是大多数USM对话框中的Radius滑块.
  2. 好吧,如果我们减去模糊性,我们应该留下高对比度的部分!想想看:如果你模糊了天空,它仍然看起来像天空.减去像素,你得到天空 - 天空= 0.如果你模糊可乐标志,你会得到一个模糊的可乐标志.减去它,你就会留下边缘.差异也是如此
  3. 是什么让事情看起来更清晰?对比.再次复制原始图像并增加对比度.增加对比度的数量是大多数USM对话框中的" 数量"或" 强度"滑块.
  4. 最后把它们放在一起.此时你有三件事:

    1. 原始图像的高对比度版本
    2. 模糊图像与原始图像的差异(此图层大多为黑色).该图层是非锐化蒙版
    3. 原本的

    算法如下:从非锐化掩模中查看一个像素并找出其亮度(亮度).如果亮度为100%,请使用高对比度图像中的此像素值.如果为0%,请使用原始图像中的此像素值.如果介于两者之间,请使用一些加权混合两个像素的值.(可选)仅在像素值变化超过一定量时更改像素值(这是大多数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;
}
Run Code Online (Sandbox Code Playgroud)

注意:我不是图形专家,但这是我从我找到的页面中学到的东西.自己阅读并确保你同意我的发现,但实施上述内容应该很简单,所以试一试!

参考


Jam*_*mes 10

关键是空间频率的概念.高斯滤波器仅传递空间频率,因此如果您执行以下操作:

2*(原始图像) - (高斯滤波图像)

那么它在空间频域的作用是:

(2*所有频率) - (低频)=(2*高频)+(1*低频).

因此,实际上,"非锐化掩模"正在增强图像的高频分量---高斯滤波器尺寸的精确参数以及减去图像时的权重决定了滤波器的确切属性.


Don*_*nie 5

非锐化通常实现为检测边缘的卷积核.该卷积的结果被添加回原始图像以增加边缘对比度,这增加了额外"清晰度"的错觉.

所使用的确切内核在人与人和应用程序之间有很大不同.他们中的大多数都有这种一般格式:

    -1 -1 -1
g = -1  8 -1
    -1 -1 -1
Run Code Online (Sandbox Code Playgroud)

有些人将对角线留下来,有时候你会获得更高的重量,并且整个内核都会缩放,有些人会尝试不同的重量.它们最终都具有相同的效果,它只是一个玩的问题,直到找到一个你最喜欢的结果.

给定输入图像I,输出定义为: out = I + c(I * g),其中*是2D卷积运算符,并且c是一些缩放常数,通常高于0.5和小于,1因此您可以避免超出必要的频道.