GIMP 中低、中或高色调减淡或加深的实现是什么?

信息处理 图像处理 颜色 软件实现
2021-12-28 02:56:44

在 GIMP 和 Photoshop 中,您可以使用 DODGE/BURN 工具来增强阴影或高亮区域的颜色,否则这些区域会偏黑或偏白。我凭经验发现这个过滤器对于我正在实施的计算机视觉任务来说是一个很好的预处理步骤。

我在Andy Finnell - How to implement dodge and burn tools中发现,有 6 个公式可以简单地将 RGB 值映射到其他 RGB 值,而与通道或像素位置无关。根据链接,转换是y=x+0.25*sin(x)为了躲避中间调。

但是,我无法使用 gimp 源代码(gimpoperationdodgemode.c 的摘录)验证这一点:

gboolean
gimp_operation_dodge_mode_process_pixels (gfloat              *in,
                                      gfloat              *layer,
                                      gfloat              *mask,
                                      gfloat              *out,
                                      gfloat               opacity,
                                      glong                samples,
                                      const GeglRectangle *roi,
                                      gint                 level)
{
  const gboolean has_mask = mask != NULL;

  while (samples--)
    {
      gfloat comp_alpha, new_alpha;

      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
      if (has_mask)
    comp_alpha *= *mask;

      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;

      if (comp_alpha && new_alpha)
    {
      gint   b;
      gfloat ratio = comp_alpha / new_alpha;

      for (b = RED; b < ALPHA; b++)
        {
          gfloat comp = in[b] / (1.0 - layer[b]);
          comp = MIN (comp, 1.0);

          out[b] = comp * ratio + in[b] * (1.0 - ratio);
        }
    }
      else
    {
      gint b;

      for (b = RED; b < ALPHA; b++)
        {
          out[b] = in[b];
        }
    }

      out[ALPHA] = in[ALPHA];

      in    += 4;
      layer += 4;
      out   += 4;

      if (has_mask)
    mask++;
    }

  return TRUE;
}

代码的本质将归结为这两行。另一个代码用于处理画笔的透明度并迭代像素和颜色通道。

gfloat comp = in[b] / (1.0 - layer[b]);
comp = MIN (comp, 1.0);

建议所有色调的通用公式以及 y = x / (1- f(x)). 我无法将 layer[b] 的值追溯到任何合理的东西,因此不知道f(x)应该是什么。

此外,关于闪避和燃烧的维基百科页面,以及关于色调映射的一般页面,只提到了原理,而没有提到任何公式。

闪避和刻录滤镜有不同的定义吗?y=g(x)gimp 工具以公式的形式定义是什么?

1个回答

它基本上使用摄影师所说的“阴影蒙版”/“高光蒙版”。

如果图像在 [0, 1] 范围内,“Highlight Mask”实际上就是像素的值。
“Shadow Mask”是相反的,即1 - Highlight Mask。

使用此掩码作为结果与原件的线性插值器。

正式化它将是:

O[p]=M[p]A(I[p])+(1M[p])I[p]

在哪里p是像素坐标(这是一个像素操作),M[]是掩码(Low、Mid 或 High,我们很快就会将其正式化),I[]是输入图像,O[]是输出图像和A()是操作(从链接的源获得的 Doidge 或 Burn)。

整个诀窍是面具。我们使用它来定位低、中或高亮度值。
假设Y[p]是像素的亮度值,我们可以将掩码构建为:

  • 高的 -M[p]=Y[p].
  • 低的 -M[p]=1Y[p].
  • 医学-M[p]=4(Y[p])2+4Y[p].

以上假设数据的计算在[0, 1]范围内。