python - 保持白度的不对称混合/颜色插值
问题描述
我正在使用一个正在做一种奇怪的颜色插值的软件。我发现它非常令人愉快,因为它似乎以比我在 sRGB 空间中使用天真的 alpha 混合插值更好的方式保留了输入图像的白度:
white = np.ones((1,3), dtype=np.float32)
blue = (white * np.array([0, 0, 1])).astype(np.float32)
white * alpha + (1 - alpha) * blue
对于这些,我们不想阅读所有内容。以下是我想要复制的主要结果:
如果我使用黑色叠加层(0、0、0)、渐变和重新照明设置为 50%,则从软件输出。基本上,就像我在黑色叠加层上设置了从深色 (0, 0, 0) 到灰色 (127, 127, 127) 的蒙版:
现在,这里变得棘手了。如果我有一个红色叠加层 (1, 0, 0),一个渐变和一个重新设置为 50%,我得到了这个:
所以在这里,这不仅仅是我用我的渐变设置我的叠加蒙版(你可以尝试它或使用 Photoshop,你会发现它还有更多的东西......)
注意:如果两次实验,梯度应该相同。
更多信息:
我想复制软件的结果并在 python 中编写我自己的脚本,这样我就可以处理大量的图像。
以下是我使用该软件得到的一些输出:
10% of blue (0, 0, 1) and 90% of white (1, 1, 1) give: 0.94117647 0.90980392 1.
20% of blue (0, 0, 1) and 80% of white (1, 1, 1) give: 0.8745, 0.8335, 0.996
30% of blue (0, 0, 1) and 70% of white (1, 1, 1) give: 0.80784314 0.72941176 1.
10% of red (1, 0, 0) and 90% of white (1, 1, 1) give: 1, 0.9254902, 0.90980392
20% of red (1, 0, 0) and 80% of white (1, 1, 1) give: 1, 0.8509, 0.8156
30% of red (1, 0, 0) and 70% of white (1, 1, 1) give: 0.99607843, 0.76862745, 0.7254902
10% of green (0, 1, 0) and 90% of white (1, 1, 1) give: 0.94117647, 0.99607, 0.92941176
20% of green (0, 1, 0) and 80% of white (1, 1, 1) give: 0.8745, 1, 0.84705
30% of green (0, 1, 0) and 70% of white (1, 1, 1) give: 0.81176471, 0.99607843, 0.78039216
0% of black (0, 0, 0) and 100% of white (1, 1, 1) give: 1, 1, 1
10% of black (0, 0, 0) and 90% of white (1, 1, 1) give: 0.89803922, 0.89803922, 0.89803922
20% of black (0, 0, 0) and 80% of white (1, 1, 1) give: 0.79607843, 0.79607843, 0.79607843
30% of black (0, 0, 0) and 70% of white (1, 1, 1) give: 0.79607843, 0.70196078, 0.70196078
40% of black (0, 0, 0) and 60% of white (1, 1, 1) give: 0.60392157, 0.60392157, 0.60392157
50% of black (0, 0, 0) and 50% of white (1, 1, 1) give: 0.50588235, 0.50588235, 0.50588235
例如第一行的意思是:如果我取 10% 的蓝色(和 90% 的白色?),软件在 rgb 颜色空间中的输出是:[0.94117647 0.90980392 1.] 这看起来有点奇怪,因为红色和绿色通道不对称下降......
我已经尝试了几件事。就像使用 OpenCV 转换 HSV、HSL、LAB、Luv 中的颜色一样,但我在这些空间中找不到真正的“线性插值”。最有希望的空间似乎是LAB或Luv,因为我们可以看到几乎是线性的偏移,但它不是,因此如果我的叠加层是蓝色的,它不会保留白度,而是会变成洋红色
以下是一些值:
blue in rgb colorspace is [255, 0, 0], in LAB: [82, 207, 20]
white in rgb colorspace is [255, 255, 255], in LAB: [255, 128, 128]
现在软件给了我:
10% of blue (+90% of white?) in LAB space: [238, 135, 118]
20% of blue (+80% of white?) in LAB space: [221, 141, 108]
30% of blue (+70% of white?) in LAB space: [202, 149, 97]
40% of blue (+60% of white?) in LAB space: [185, 156, 86]
50% of blue (+50% of white?) in LAB space: [169, 163, 76]
所以,我们可以看到它看起来几乎是线性的,但它仍然不够。例如,如果我们在 LAB 空间中对白色和蓝色的亮度进行线性插值,亮度似乎几乎是线性的:255 * 0.8 + 82 * 0.2 = 220.4。软件给了我们:221。所以它非常好,但实际上这并不总是成立:例如对于a通道: 128*0.8 + 207 * 0.2 = 143.8 而软件给使用141。
这可能是由于四舍五入,但实际上使用 float32 我们可以看到更大的差异。
奇怪的是,当我们使用灰度图像时,软件的变换实际上在 rgb 颜色空间中是线性的:
0% of black (0, 0, 0) and 100% of white (1, 1, 1) give: 1, 1, 1
10% of black (0, 0, 0) and 90% of white (1, 1, 1) give: 0.89803922, 0.89803922, 0.89803922
20% of black (0, 0, 0) and 80% of white (1, 1, 1) give: 0.79607843, 0.79607843, 0.79607843
30% of black (0, 0, 0) and 70% of white (1, 1, 1) give: 0.79607843, 0.70196078, 0.70196078
40% of black (0, 0, 0) and 60% of white (1, 1, 1) give: 0.60392157, 0.60392157, 0.60392157
50% of black (0, 0, 0) and 50% of white (1, 1, 1) give: 0.50588235, 0.50588235, 0.50588235
有人知道它可能是哪种混合/插值吗?
*注意:仅对于较低或较高的百分比值,结果看起来有点像 Photoshop 中的“照片滤镜”,但实际上并非如此,而且没有人知道“照片滤镜”在 Photoshop 中的工作原理(我在Imagemagick,Photopea,...但它与 Photoshop 的结果相去甚远)
我希望色彩科学专家能给我和提示:)
谢谢
解决方案
推荐阅读
- laravel - 在 Laravel 中重新加载自定义 .env 文件后如何更改存储设置?
- java - 使用 MongoDb Java 驱动程序有办法动态获取过滤器功能
- python - 为特定行中的列列表赋值
- javascript - 如何在 JavaScript 中的嵌套数组中插入键值对
- python - 有没有办法通过 xlwings 垂直写入单元格?
- reactjs - TypeError: Class extends value undefined is not a constructor or null while running next.js
- f# - Saturn 的 .NET SDK 要求
- security - 使 PHP-FPM security.limit_extensions 不区分大小写
- yocto - tegra-minimal-initramfs.bb 是否有任何补丁来防止此错误?
- r - 从 R 中的不同文本中提取元素