有人可以解释一下Photoshop中“黑白”调整层背后的算法吗?
我必须使用 C++ 为应用程序重现它,该应用程序强调图像中的非红色/洋红色(ish)像素(具有类似百分比的可配置容差),并且该资源显示了我期望的行为。
仍然无法重现它,但我找到了一个线索:
每个像素最多由两个控件定义,一个加法 (RGB) 和一个减法 (CMY)。
有人可以解释一下Photoshop中“黑白”调整层背后的算法吗?
我必须使用 C++ 为应用程序重现它,该应用程序强调图像中的非红色/洋红色(ish)像素(具有类似百分比的可配置容差),并且该资源显示了我期望的行为。
仍然无法重现它,但我找到了一个线索:
每个像素最多由两个控件定义,一个加法 (RGB) 和一个减法 (CMY)。
每个(彩色)图像都由 RGB 分量组成。当您仅在 RED 组件中为所有像素添加(或减少)一个常数值时,您将看到相当于将 RED 选项卡向右移动的效果,并且以相同的方式将 RED 组件减少一个常数将产生相反的效果。
同样,您可以按所述固定值递增/递减每个组件。如果您将所有 RGB 分量增加/减少相同的值,这将等同于亮度的变化(基本上您正在添加/删除白色)。
青色、蓝色、品红色 - 对应于 CMYK 颜色空间中的这种转换。(但我想,这个颜色空间中的蓝色对应于青色和黄色的混合。所以这有点棘手。转换对所有人来说基本相同。
最后一个元素 Tint: { Hue and Saturation } 对应相同的操作,但在这里,图像首先在 HSV 模型中转换,然后单独添加/减去 HUE 和饱和度。
我不知道表盘标记与相应数字的确切关系,但您可以通过尝试实际值来弄清楚。
我在 MATLAB 中完美地复制了算法(基于@Ivan Kuckir的回答):
function [ mO ] = ApplyBlackWhiteFilter( mI, vCoeffValues )
FALSE = 0;
TRUE = 1;
OFF = 0;
ON = 1;
numRows = size(mI, 1);
numCols = size(mI, 2);
dataClass = class(mI);
numCoeff = size(vCoeffValues, 1);
hueRadius = 1 / numCoeff;
vHueVal = [0:(numCoeff - 1)] * hueRadius;
mHsl = ConvertRgbToHsl(mI);
mO = zeros(numRows, numCols, dataClass);
vCoeffValues = numCoeff * vCoeffValues;
for jj = 1:numCols
for ii = 1:numRows
hueVal = mHsl(ii, jj, 1);
lumCoeff = 0;
% For kk = 1 we're dealing with circular distance
diffVal = min(abs(vHueVal(1) - hueVal), abs(1 - hueVal));
lumCoeff = lumCoeff + (vCoeffValues(1) * max(0, hueRadius - diffVal));
for kk = 2:numCoeff
lumCoeff = lumCoeff + (vCoeffValues(kk) * max(0, hueRadius - abs(vHueVal(kk) - hueVal)));
end
mO(ii, jj) = mHsl(ii, jj, 3) * (1 + lumCoeff);
end
end
end
请注意,从vPhotoshopValues
to的转换vCoeffValues
应按vCoeffValues = (vPhotoshopValues - 50) ./ 50
.
由于 Photoshop 值在 [-200, 300] 中,并且应该使用 . 线性映射到 [-5, 5] 中50 -> 0
。
这是与 Photoshop 的比较:
最大误差在 [0, 255] 范围内小于 1。
完整代码可在我的StackExchange Signal Processing Q688 GitHub 存储库中找到。