我知道这是一个旧帖子,但我喜欢在有机会时尽我所能回答这些问题,这样下一个人会比我有更好的帮助......
在我自己在不同环境中实现相同混合的运动中,我遇到了很多建议中提供的幼稚数学问题。除非您将 LCH 空间用于其他图像操作,否则可能不值得为此付出转换成本。你是对的; 转换涉及大量数学运算,如果要立即转换回 RGB,则需要优雅地处理色域外点。据我所知,这意味着在转换回 RGB 之前进行数据截断。在之后截断负和超大像素值转换将洗掉图像的黑白区域。问题是在转换之前截断意味着尝试计算给定 H 和 L 的最大色度。您可以预先计算并使用 LUT,但速度并没有那么快。
如果您想要一个提供良好(优于 HSL)颜色/亮度分离并且行为合理相似(用于非关键目的)的颜色模型,我建议改用 YPbPr。这是一个单一的仿射变换,所以它会更快,并且边界计算很简单,因为 RGB 色域的面保持平面。边界计算只是线平面相交数学(如果您想要更快的速度,甚至可以将这些计算纳入 LUT。同样,它不如 LAB 或 LUV 混合好;如果前景高度饱和,您可能会注意到很多,但如果速度和简单性很重要,它可能值得考虑。
值得研究的一个例子是 HuSL (www.husl-colors.org)。HuSL 是 CIELUV 的一个版本,其中色度空间被归一化为上述 RGB 色域的边界。那里可用的 WMaxima 工作表应该为您提供一些关于如何计算截断的最大色度的想法。虽然使用 HuSL 进行颜色混合比 HSL 效果更好,但归一化会扭曲色度 (S) 的表示,因此 LUV 的均匀性(我们经历所有这些分数幂运算的原因)丢失了。这里的实现也基于 CIELUV,而不是 CIELAB,尽管除非您正在进行图像编辑,否则其后果可能并不重要。
同样,如果示例有帮助,我在 Mathworks FEX 上有一个图像混合功能,它提供这些混合,以及 HuSL 和绑定的 LCHab/uv 转换工具(以及 LCHab 和 LCHuv 的最大色度 LUT)一个matlab脚本,但数学概念是一样的。
如果您根本不想处理边界色度计算,您可以考虑这样做:
- 从图像中提取亮度。只需使用您想要的任何亮度定义进行加权平均。[0.299 0.587 0.114]*[RGB]' 是 Rec.601 iirc。
- 在 HSL 中进行 HS 通道交换(GIMP 使用 HSL而不是 HSV,而不是 HSI)。转换回 RGB
- 转换为您最喜欢的亮度-色度模型(例如 YPbPr)并将 Y' 替换为原始亮度。转换回 RGB。
这基本上是在图像编辑器中使用图层的通用亮度保存技术的编程方法。这会产生令人惊讶的好结果并使用常见的转换工具。
最后,我通过使用各种颜色模型的示例混合来提供我自己的讨论:HSV、HSI、HSL、CIELAB(在转换前后有截断)和 HSL+Y 方法。另外:如果你和我一样厚,对投影 RGB 空间的几何图形进行可视化可能有助于更好地理解在 LCH 中的点之间交换色度/亮度信息时发生的情况(以及管理的必要性) OOG 色点)
我会发布更多信息的链接,但我想他们不允许像我这样的人这样做。
编辑:实际上,我刚刚意识到一些事情。如果速度和均匀性很重要,并且可以接受稍微有限的色度范围(可能用于 UI 图形或其他内容),我的 YPbPr 建议的附录可能是合适的。考虑 YPbPr 中 RGB 色域的范围:一个倾斜的立方体,围绕中性轴站在其角落。该体积的最大旋转对称子集是双锥体。截断到这个双锥体而不是立方体面比计算与立方体面的交点要快得多。混合物更均匀,但最终具有有限的最大色度。有一些 HuSL 方法以相同的原理 (HuSLp) 运行,但在 YPbPr 中执行此操作允许访问比 HuSLp 更大一部分的 RGB 空间。那里' s 实际上是在我的博客上发表的一篇关于这样做的文章(有将其与 LAB 混合进行比较的示例),尽管当时我更关心的是均匀性。直到现在我才想到圆锥相交计算的速度。