ImageMagick 示例 -
颜色修改
- 索引
-
ImageMagick 示例前言和索引
-
将颜色转换为灰度
-
图像级别调整
-
使用直方图修改进行调整
(更改图像的直方图)
-
DIY 级别调整
(通用色调运算符)
-
对图像的中间色调进行色调处理
(通用色调运算符)
-
全局颜色修改器
-
使用查找表重新着色图像
为了探索这些技术,我们需要一个测试图像... 不用担心我是如何生成这个图像的,这对于练习并不重要。我确实设计了它,使其包含一系列颜色、透明度和其他功能,特别是为了让 IM 在使用时得到充分锻炼。 |
![]() |
generate_test
”。
![]() ![]() |
警告:以下颜色处理过程通常假设图像使用线性颜色空间。然而,大多数图像都是使用 sRGB 或伽马校正颜色空间保存的,因此为了使结果正确,应该首先应用颜色空间校正。 |
将颜色转换为灰度
灰度图像在许多用途下都非常有用,例如,进一步处理原始图像或用于背景合成。将图像转换为灰度的最佳方法是直接让 IM 将图像转换为灰度 颜色空间 表示。请注意,蓝色比红色暗得多,这是因为权重匹配了它们的强度,因为它们看起来像是人眼看到的。也就是说,“红色
”的颜色比看起来更暗的“蓝色
”要亮得多。这等效于使用 'rec709luma ' 转换公式,使用专用 “-grayscale ” 运算符(在 IM v6.8.3-10 中添加)。
|
![]() |
rec709luma
' 值只是许多灰度化公式中的一种,这些公式被定义为 “-intensity
” 设置(见下文)使用。例如,以下是另一个常见的灰度化公式 'rec601luma '
|
![]() |
然而,还有许多其他方法和'灰度'的含义...
例如,您可以使用 调节运算符 将图像中的所有颜色都滤掉,将所有颜色饱和度级别设置为零。
|
![]() |
亮度
' 值。但是,使用“-define modulate:colorspace
”,您可以指定其他要使用的颜色空间模型。请参阅以下 在其他颜色空间中调节。请注意,我在测试图像中使用的中心彩色圆盘的 IM '绿色
' 颜色实际上不是纯绿色,例如彩虹中使用的绿色,而是由新的 SVG - 可缩放矢量图形 标准定义的半亮绿色。如果您需要纯 RGB 绿色,可以使用颜色 'lime
'。有关更多详细信息,请参阅 颜色名称冲突。另一种方法是使用 FX DIY 运算符 对三个通道进行平均,以获得灰度的纯数学意义。
|
![]() |
![]() ![]() |
sRGB 通道值的平均值也等效于 'OHTA ' 颜色空间(红色通道)的强度通道。或 HSI 的 'I' 通道。颜色空间。 |
另一种技术是简单地将三个通道加在一起(一种称为曼哈顿距离的颜色度量),虽然生成的图像不会由于“量子舍入”效应而丢失信息,但您可能会丢失有关最亮颜色的信息。不幸的是,您也会丢失透明度通道。
|
![]() |
您可以使用相同的添加通道技术来控制各个颜色通道的权重。例如,以下是一个您可以使用的 DIY 公式...
|
![]() |
如果您想要在 “-fx ” 运算符中获得相同的含义,也可以使用 'intensity'。
|
![]() |
然而,由于解释了 FX DIY 运算符,它可能会运行得非常慢。对于更复杂的运算,您可以使用更简单的 评估运算符,“-evaluate ”。例如,以下是一个 2/5/3 比例的灰度图像,但同样,我没有尝试保留原始图像的透明度通道。
-recolor ” 颜色矩阵运算符,它允许您指定三个颜色通道的权重。
一种更有趣的方法是从各种 颜色空间 表示的图像中提取不同的亮度含义,以提取相应的 颜色通道。有关示例,请参阅 来自颜色空间表示的灰度通道。 图像级别调整您可以对图像进行的最基本形式的调整称为“级别”调整。这基本上意味着获取各个 RGB 颜色值(甚至 alpha 通道值)并调整它们,以便拉伸或压缩这些值。由于仅调整通道值,因此最好在灰度图像上演示它们,而不是彩色图像。但是,如果您以相同的量调整图像的所有颜色通道,则可以使用它们处理彩色图像,以增强或调整图像。不要将此与我们将在下面下一节示例中讨论的更自动的级别调整形式混淆,即 归一化调整。此函数将执行完全相同的操作,而不管图像的实际内容是什么。图像的亮度或暗度无关紧要,也不管其是蓝色还是黄色色调。操作对实际图像内容视而不见。![]() gnuplot ” 图表(如右图所示),我使用一个特殊的脚本 “im_graph ” 来生成它。该图表有一条红线,它将给定的原始 'x' 值(代表最上面的渐变的灰度值)映射到显示的 'y' 值。生成的彩色渐变也显示在输入线性渐变下方。右侧显示的图表是 IM “-noop ” 运算符的图表,该运算符实际上不对图像执行任何操作。因此,每个图像的颜色值都直接映射到完全相同的值,没有改变。因此,较低的渐变与较高的渐变相同。 图像反转你可以进行的最简单、最基本的全局级别调整是反转图像,使用“-negate ”图像操作符。本质上,这会将白色变为黑色,黑色变为白色,并调整所有颜色以匹配。也就是说,它会将红色变为其互补色青色,蓝色变为黄色,等等。你可以通过下面显示的映射图看到这一点,因为我在“测试”图像和标准 IM “玫瑰”内置图像上使用了“-negate ”操作符。注意映射图图像中的较低梯度现在被反转了,因此黑色和白色被交换了,并且在反转的“测试”图像中出现了相同的反转。
在内部,反转实际上相当愚蠢。它独立地处理三个颜色通道,默认情况下忽略 alpha 通道。如果不是这样,你将得到一个非常愚蠢的结果,像这样...图像被反转了,你可以通过半透明的颜色梯度看到这一点。但由于透明度通道也被反转了,你丢失了图像中的所有不透明颜色。这就是“-channel ”的默认设置是“RGB ”的原因。有关更多信息,请参见 颜色通道。你可以将反转限制在一个通道上,例如绿色通道。这可能看起来不太有用,但在某些情况下它至关重要。“-negate ”操作符实际上是它自己的逆运算。对具有相同“-channel ”设置的图像进行两次反转会相互抵消。反转在图像处理中非常常见,尤其是在处理灰度图像时,作为其他处理选项之前或之后的步骤。因此,我建议你尝试一下,并在进行任何操作时牢记它,因为使用反转图像可以解决一些原本难以解决的问题。 直接级别调整“-level ”操作符是更通用的级别调整操作符。你基本上需要提供两个值,一个“黑点”和一个“白点”,以及一个可选的第三个值(伽马调整),我将在 稍后讨论。它的作用是将图像中等于或小于“黑点”的任何颜色值映射为黑色(或 0 值)。类似地,任何等于或比“白点”更亮的色值将被映射为白色(或最大值)。这两个点之间的颜色然后被线性“拉伸”以填充完整的色值范围。这样做的效果是提高对比度,增强图像中的颜色。例如,这里是我们测试图像的 25% 对比度增强,使用与图表显示的相同值。由于你通常会从 0% 和 100% 调整黑色和白色点相同的值,因此你只需指定“黑点”即可。白点将被调整相同的值向内移动。
请注意,25% 对任何图像来说都是一个巨大的对比度增强,但它清楚地显示了它的作用。你不必同时改变“黑色”和“白色”点。相反,只调整颜色范围的一端是完全允许的。例如,我们可以制作一个非常亮或非常暗的玫瑰图像。
但是,我再次警告你,给定范围之外的颜色会被“裁剪”或“燃烧”,因此将不再可用于以后的图像处理。这是使用“-level ”操作符的最大问题。
![]()
但是,这种降对比度图像的方法非常不准确,不建议使用,除非你的 IM 版本低于 6.4.2,在这种情况下你无法使用新的 反转级别操作符. ![]() -level ”操作符来反转图像(如上面所示,只需交换给定的“黑色”和“白色”点值,使用“-level 100%,0 ”。
![]() -level ”对图像进行阈值化与使用具有该值的 阈值操作符 是一样的。右侧显示的映射图显示了“-level 50%,50% ”操作的结果及其对灰度梯度的影响。
请注意,与“ -threshold ”不同,当使用默认的“-channel ”设置时,图像不会自动转换为灰度图像。使用级别对图像进行线性修改的通用性质使得“-level ”操作符非常适合一般的灰度图像修改和蒙版调整。再加上你可以修改单个通道(使用“-channel ”设置)而不是整个图像,使其成为 IM 用户可用的最佳颜色修改操作符之一。
反向级别调整-- 降对比度图像从 IM 版本 6.4.2 开始,级别操作符 已扩展为提供“反转”形式“+level ”(注意“加号”)。或者,你可以使用操作符的原始“-level ”形式,但在给定的级别参数中添加“! ”(对于旧的 API 接口)。该变体的参数完全相同,但它不是拉伸值以将“黑点”和“白点”映射到“黑色”和“白色”,而是将“黑色”和“白色”映射到给定的点。换句话说,“+level ”是“-level ”的精确反转。例如,这里我们将“黑色”映射到 25% 灰色,将白色映射到 75% 灰色,使用两种指定“反转”形式的方法,以非常精确的方式降对比度图像。
如果你将上面的“+level 25% ”操作与我们之前显示的负降对比度“-level -25% ”操作符进行比较,你会发现它们并不相同。“加号”版本产生了一个更强的降对比度图像(它更灰),但它通过将值映射到你给操作符的精确值来实现这一点,而不是“减号”形式使用的“假想”值。这种精确值使用非常重要,也是添加操作符“加号”形式的原因之一。当然,25% 再次是一个非常大的值,不建议在典型的图像处理工作中使用。请注意,“-level ”和“+level ”实际上在给定相同参数时是完全相反的。也就是说,一个将值映射到范围极端,而另一个从范围极端映射。例如,这里我们使用“+level ”压缩图像的颜色,然后使用“-level ”再次解压缩它们,以恢复接近原始外观的图像。
这两张图像看起来非常相似,由于我使用的是高 质量 的“Q16”版本 IM,你很难注意到任何差异。但是,值可能并不完全相同,因为你实际上已经将图像的颜色值压缩到更小的整数范围内,然后又恢复了它们。在极端情况下,这会导致 量子舍入效应。按照相反的顺序进行这两个操作(拉伸,然后压缩颜色值)会导致 量子裁剪效应。“+level ”操作符的另一个有用方面是,你可以将图像中的所有颜色值完全压缩到相同的灰度级别。
通过根据每个通道的特定颜色的值指定级别,你可以有效地将灰度梯度转换为特定的颜色梯度。但是,这很难计算和执行。因此,还提供了一个“-level-colors ”操作符,它允许你使用特定颜色而不是“级别”值来指定黑点和白点。请参见下面的 按颜色划分级别。 级别伽马调整以上两个“-level ”变体也允许你使用第三个设置。“伽马”调整值。默认情况下,它设置为 1.0 ' 的值,它不会对生成的图像进行任何中间色调调整,而是生成从旧图像到新图像的值的纯线性映射。但是,通过将此值增大,你会使生成的线弯曲,从而使图像变亮,而缩小该值会使图像变暗。例如,这里我只使用“伽马”设置来调整图像的中间色调的亮度和暗度。
![]() ![]() ![]() ![]() ![]() ![]() ![]() 1.0 不会对图像进行任何“伽马”更改。但是,特殊的“2.0 ”值(见上文)可用于获取图像归一化颜色的平方根。“-level ”的两个版本都以相同的方式处理“伽马”。这意味着你可以将“黑色”和“白色”端点的级别调整与非线性“伽马”调整结合起来。你也可以只调整图像的单个通道。例如,这里我们在蓝色通道的黑色端给图像添加了微妙的色调,同时使用伽马来保留图像的中间色调色级。
此特定示例可用于对气象卫星照片进行着色,其中只有海洋是纯黑色,而陆地则更灰。此蓝色通道调整的其他替代方案在下面的 DIY 数学非线性调整 中给出。 伽马操作调整也提供了“-gamma ”运算符,它与“-level ”运算符中的“gamma”设置具有完全相同的效果。但是它允许您为每个单独的通道调整“gamma”调整级别。它真正的用途是在对图像执行线性运算之前调整图像的“gamma”函数。有关更多详细信息,请参见人类颜色感知和伽马校正。我们还可以使用此函数以不同的方式为每个单独的 RGB 通道增亮图像。
-evaluate POW 2.2 ”实际上会执行“-gamma 0.45455 ”(0.45455 等于 1/2.2) 操作,这与“-gamma 2.2 ”相反。“ -gamma ”的一个不太明显的用途是将特定图像通道归零(参见归零颜色通道)。或者将图像完全涂成“黑色”、“白色”或其他主要颜色(参见主要彩色画布)。按颜色级别调整“-level-colors ”运算符已添加到 IM v6.2.4-1 中。本质上,它与我们上面讨论的级别运算符完全相同,但每个通道的值指定为颜色值。也就是说,“-level-colors ”选项将给定颜色映射到“黑色”和“白色”,并将所有其他颜色线性拉伸到它们之间。这有效地从图像中去除了给定的颜色范围。虽然这有效,但它并不特别有用,因为它容易在某些通道具有相同值的颜色中失败。例如,“DodgerBlue ”和“White ”颜色在蓝色通道中具有相同的颜色值。因此,“-level-colors DodgerBlue,White ”可能并不总是将这些颜色映射到黑色和白色。在这种情况下,更好的技术是提取具有最大差异的通道(如红色)的灰度图像,并对该通道进行级别调整或归一化。警告:注意“透明”颜色。另一方面,运算符的加号形式“ +level-colors ”非常有用,因为它会将“黑色”和“白色”颜色映射到给定的值,将所有其他颜色线性压缩以适合您提供的两种颜色。例如,让我们将“black ”和“white ”映射到“green ”和“gold ”...如您所见,灰度梯度被重新映射到以给定颜色为边界的梯度,虽然灰度范围之外的颜色也会被修改,但它们也会遵循指定的颜色范围的基本风格。这使得“+level-colors ”运算符非常有用,尤其是在映射灰度图像时。如果您只提供一个颜色名称,但包含逗号,则缺失的颜色将根据需要默认为“black ”或“white ”。
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 如果您只指定一种颜色,没有任何“逗号”分隔符,则该颜色将用于黑色和白色点。这意味着图像中的所有颜色将被重置为该颜色。(根据当前“ -channel ”设置限制)。
-fill DodgerBlue -colorize 100% ”对图像着色的结果相同(见下文)。如果您还希望设置图像的透明度设置,则需要将“-channel ”设置为包含透明度通道,或者使用“-alpha opaque ”或“-alpha off ”将Alpha 通道设置为完全不透明。
![]() ![]() ![]() ![]() ![]() +level-colors ”是一种梯度颜色替换,一种线性着色运算符,也可以完全重置颜色。 S 型非线性对比度在关于“图像处理基础”(第 44 页)的 PDF 文档中,他们提出了一种使用线性对比度控制(级别)的替代方法,其中一种使用伽马校正被称为“S 型非线性对比度控制”。结果是在整个颜色范围内产生非线性的平滑对比度变化(数学上的“S 型函数”),保留白色和黑色,这对于照片颜色调整来说要好得多。论文中的确切公式非常复杂,甚至有错误,但本质上需要两个调整值。对比度函数的中心阈值(通常位于“50% ”),以及对比度因子(“10 ”非常高,“0.5 ”非常低)。
-fx ”中实现上述公式,结果是“10 ”的非常高的对比度值和“50% ”的阈值。这些值已被滚动到浮点常量中,以加快函数速度。
10 ”是一个非常重的对比度因子。事实上,任何高于此值的都可被认为更像是模糊阈值操作,而不是对比度增强。有关使用此运算符的实际示例,请参见高级“凝胶”效果示例,其中它用于锐化添加到形状区域颜色的亮区。其他对比度运算符![]() ![]() -contrast and +contrast Rather useless minor contrast adjustment operator -threshold Threshold the image, any value less than or equal to the given value is set to 0 and anything greater is set to the maximum value. Note that like level, this is a channel operator, but if the default 'channel setting' is used only the gray-scale intensity of the image is thresholded producing a black and white image. magick rose: -threshold 45% x: You can force normal channel behaviour, where each channel is thresholded individually buy using "-channel All" magick rose: -channel All -threshold 45% x: -black-threshold -white-threshold This is like -threshold except that only one side of the threshold value is actually modified. For example, here anything that is darker than 30% is set to black. magick rose: -black-threshold 30% x: magick rose: -white-threshold 50% x: These operators however do not seem to be channel effected, so may only be suitable for gray-scale images! 使用直方图修改进行调整本节由Fred Weinhaus和 Anthony Thyssen 共同完成。什么是直方图?直方图是一种特殊的图形。它只是将图像中像素的颜色级别按固定数量的“箱”进行排序,每个“箱”跨越一定范围的值。因此,每个“箱”都包含一个计数,表示图像中落在该范围内的颜色级别(像素值)的数量。结果是对构成图像的颜色值的分布的表示,从左侧的黑色到右侧的白色。
![]() ![]() ![]() ![]() ![]() ![]() -contrast ”是一个简单的水平型算子,它只为图像添加了一点点对比度。结果是直方图本身被更多地扩展,使其更好地覆盖了所有可能的颜色范围。您还可以从前后直方图中看到,由于拉伸的方式,颜色最终也会在“箱”之间出现间隙和孔洞。具体来说,它会创建一个“直方图”,其中所有颜色都被放置到“箱”中。这些“箱装”的颜色随后作为一个整体被修改,导致图像颜色被分组在一起。这不是处理图像颜色的一种特别好的方法。然而,此算子是盲目工作的,它不知道图像内容或颜色分布。因此,在没有一些用户控制的情况下无法进行,因为算子很容易让它应用于任何图像,使其变得更差,而不是更好。在本节中,我们将研究图像处理算子,它们将图像的直方图作为其决策过程的一部分进行检查。然后,它使用此研究的结果来修改图像,以增强图像颜色分布的某些质量。由于这些算子利用了来自正在处理的图像的实际信息,因此它们通常可以更全局地应用于许多图像,而用户只需进行很少的检查。此类算子包括自动线性“水平”型算子,如“-normalize ”、“-contrast-stretch ”和“-linear-stretch ”,但也包括非线性算子,如“-equalize ”,以及其他可能最终被包含在 ImageMagick 中的算子,例如Fred Weinhaus 的脚本,“redist”。直方图拉伸最简单的技术,就像前面的例子一样,只是将图像的直方图向外拉伸以改善颜色范围。但是,他们不是盲目地为水平操作选择黑点和白点,而是根据图像直方图选择点。基本上,他们从每个端点向内计数每个直方图箱中的颜色值数量,直到达到某个阈值。然后,这些点将用作直方图(水平)拉伸的黑点和白点。需要图表基本上,直方图计数提供了拉伸将强制转换为黑和白的灰度级值。这意味着图像中所有落在从纯黑到选定黑点箱对应的灰度级的箱子范围内的像素最终都会变成纯黑。同样地,图像中所有落在从纯白到白点箱对应的灰度级的箱子范围内的像素最终都会变成纯白。然而,落在这些点之外的像素将被拉伸到可能的颜色值范围之外,因此它们将被简单地设置为范围限制。也就是说,这些像素被“裁剪”,“刻入”,因为它们被转换为纯黑或纯白的极端颜色值。因此,如果选择黑点和白点的“阈值”限制设置得太高,您将在图像中获得大量的黑白色区域,结果直方图在极端箱中具有大量的计数(高条)。严重刻入的例子 - 中国象棋图像?“拉伸”算子总结... -contrast-stretch 和 -linear-stretch 都生成一个直方图(使用 1024 个箱子)来确定要拉伸的颜色位置。因此它不是“精确的”。另一个区别是“零”的处理方式,以及 -linear-stretch 实际上执行 -level 操作来进行拉伸,而 -contrast-stretch 使用直方图箱值进行颜色替换拉伸(这会引入 1024 量化舍入效应。-normalize 在内部使用 -contrast-stretch。一个数学上完美的归一化拉伸算子是 -auto-level。虽然完美的“仅白点”或“仅黑点”版本是可能的,但目前还没有实现。自动水平 - 完美的数学归一化“-auto-level ”查找图像中最大和最小值,用于将图像拉伸到完整的量子范围。直方图拉伸到值范围之外,不会导致任何值被“裁剪”或“刻入”。“-channel ”设置将确定所有通道是否以相同的方式“同步”拉伸(使用所有通道的最大值和最小值),还是分别拉伸(每个通道作为一个独立的实体)。目前,完全透明像素的隐藏颜色也用于确定水平,这会导致透明度出现问题。这被认为是一个错误。FUTURE: We actually need three modes of operation... synced color channels with 'alpha' (and 'read') masking. synced channels (as defined by channel) (current default) individual separate channels (currently if -channel is set by user)它是一个纯粹的数学直方图拉伸,就像手动水平算子一样。也就是说,最小值将被调整为零,最大值将被调整为量子范围,并且使用线性方程来调整图像中的所有其他值。它不使用“直方图箱”或其他方法可能用于确定要使用的水平或其他直方图调整的“值分组”。 归一化“-normalize ”算子是这三个算子中最简单的。它只是扩展灰度直方图,使其占据灰度值的完整动态范围,同时在直方图的低端(黑色)裁剪或刻入 2%,在高端(白色)裁剪或刻入 1%。也就是说,图像中最暗的灰色的 2% 将变为黑色,最亮的灰色的 1% 将变为白色。这在大多数图像中不是很大的损失,总的结果是图像的对比度(强度范围)将被自动最大化。这里需要一个理想化的图表!使用中国象棋的例子?这里,我们创建一个灰度渐变,并将其扩展到完整的黑白色范围。
![]() ![]() ![]()
-normalize ”纯粹作为灰度算子工作。也就是说,每个红色、绿色、蓝色和 alpha 通道都会根据“-channel ”设置独立地扩展。从 IM 版本 6.2.5-5 开始,如果只给出默认的“+channel ”设置,那么“-normalize ”将把所有颜色通道捆绑在一起,并以相同的量归一化它们。这确保了图像中的像素颜色不会发生偏移。但是,这也意味着您可能不会获得纯白色或黑色像素。例如,这里我们在我们的归一化测试图像中添加了一些额外的颜色(从蓝色到深蓝的渐变)。
![]() ![]() ![]() -normalize ”将所有通道一起最大化,因此一个通道具有零值,另一个通道具有最大值。也就是说,没有生成黑色像素,因为所有添加的蓝色颜色已经在“红色”和“绿色”通道中包含“零”值。因此,图像的下界没有扩展。
red ”和“green ”通道被增亮了,而“blue ”通道只被稍微暗淡了。这让我们想到一个重要的问题。
归一化和其他直方图算子实际上是灰度算子, 实际上,“在使用彩色图像时需要谨慎。 -normalize ”只是更通用的“-contrast-stretch ”的一个子集,它具有黑点 2% 和白点 = 1% 的默认值。那么“-contrast-stretch ”是什么?对比度拉伸“-contrast-stretch ”算子(在 IM v6.2.6 中添加)类似于“-normalize ”,不同之处在于它允许用户指定将被裁剪或刻入的像素数量。也就是说,它为您提供了一些控制,用于选择用于直方图拉伸的“黑点”和“白点”。因此,用户指定图像中最暗灰色的计数(或百分比计数)变为黑色,以及最亮灰色的计数变为白色。例如,这将用它们的极端值(白色和黑色)替换最上面的和最下面的 15% 的颜色,并相应地拉伸剩余的 70% 的颜色。最终结果是尝试改善图像的整体对比度。您还可以轻松地看到上面渐变顶部的“刻入”和“裁剪”效果,因为这些灰色被拉伸到颜色范围的限制之外。
-threshold-black ”)。“-contrast-stretch ”的一个重要方面是使用零作为黑点和白点阈值计数。在这种情况下,“-contast-stretch 0 ”将定位图像直方图中的最小和最大 bin。由于计数实际上从这些 bin 开始,因此结果只是将最小和最大 bin 拉伸到全黑和全白。这将导致对比度拉伸,最小或可能为零的裁剪量,所有这些“bin”中的值都将变为 0 和最大值。
直方图重新分配直方图重新分布是一种非线性技术,它重新分布直方图中的 bin 以实现某种特定形状。两种最常见的形状是均匀(平坦)和高斯(钟形),尽管双曲线和瑞利也是其他类型的分布,也已被使用。均衡 - 均匀直方图重新分布对于均匀分布的情况,直方图 bin 被移位、间隔和组合,以便平均而言,直方图在整个范围内具有平坦或恒定的高度。这称为直方图均衡。IM 函数“-equalize ”就是这么做的。不幸的是,它分别对每个通道进行操作,而不是对所有通道应用相同的操作。因此,当它应用于 RGB 色彩空间时,可能会发生颜色偏移。以下是在使用 IM 函数 -equalize 进行直方图均衡的示例。请注意每个通道独立均衡带来的颜色平衡偏移。
![]() ![]() ![]() ![]() ![]() ![]()
![]() ![]() ![]()
![]() ![]() ![]() ![]() ![]() ![]() -equalize ”运算符有何不同。具体来说,所有颜色都保留,没有您之前看到的颜色偏移。该脚本的作用是对灰度直方图进行操作,然后将其应用于所有颜色通道,以便所有颜色保持在一起。为了与 IM“-equalize ”直方图进行比较,让我们也在这里显示灰度直方图结果。请注意,重新分布的直方图似乎比 IM 均衡的直方图更平坦(平坦或均匀)。
![]() ![]() ![]() 高斯重新分配均衡直方图并不是更改图像直方图分布的唯一方法。实际上,它通常不太有用,除非在计算机视觉应用中。以下是一张相同的图像,但经过变换,使其直方图具有高斯(钟形)分布。这里使用的值是 60% 灰色平均值,在该平均值的任一侧都有 60 个 sigma 滚降。
![]() ![]() ![]() ![]() ![]() ![]() 直方图重新分配方法那么这种类型的直接直方图调整是如何工作的呢?基本上,它计算当前图像和所需分布的直方图。然后,它计算出每个“bin”的灰度级值需要如何更改,以便 bin 中的计数最符合所需的分布。某些 bin 可能被移到更暗的地方,而另一些 bin 可能被移到更亮的地方。这实际上是一个相当复杂的过程,所以让我们逐步进行。首先,我们需要从 ImageMagick 获取实际的直方图数据,而不是直方图的图形图像。请注意,数据来自所有颜色值,并组合成灰度。这样做是为了将所有通道一起分布,并将图像的整体亮度调整为遵循所需的曲线。
![]() ![]() ![]() tr ”的程序,简称为“translate”)。然后将这些原始数据提供给另一个名为“awk ”的实用程序,用于收集每个bin的实际直方图计数。为了便于查看结果,我还将直方图计数处理成梯度图像(通过NetPBM,PGM文本灰度图像文件格式),并使用“im_profile ”脚本将其显示为折线图。本质上,这只是生成直方图图像的不同方法,不过这次是直接从数字数据文件生成。现在我们已将直方图数据存储在文本文件中,我们还需要将我们希望重新分布数据匹配的函数的直方图。在这种情况下,它是一个均值为153(60% 灰色)和标准差为60的正态分布。这两个值均以直方图“bins”的256个范围表示。
![]()
![]()
![]() ![]() ![]() ![]() ![]() ![]()
![]() ![]() ![]()
DIY 色阶调整数学线性直方图调整上面显示的各种基本形式的色阶调整线性调整图像的颜色。这些更改也可以用数学方法应用。例如,通过将图像乘以特定颜色,我们将所有纯白色区域设置为该颜色。因此,让我们读取我们的图像,创建一个包含我们想要颜色的图像,然后使用IM自由格式的“-fx ”或DIY 操作符将原始图像乘以此颜色。让“-fx ”从第二个“v ”图像中读取颜色,这使得更改颜色变得容易,而无需将颜色转换成RGB值以用于数学计算。如果您使用的是像“Gimp ”和“Photoshop ”这样花哨的图形图像处理软件包,上面的操作将通过调整图像的直方图曲线来应用于图像。
![]() gnuplot ”生成的图形(请参阅脚本“im_histogram ”),该图形显示了对三个RGB通道中的一个通道进行的操作的数学公式。原始颜色(绿线)线性重新映射到较暗的颜色(红线)。线性着色黑色也很简单。例如,要将“黑色 ”线性映射到类似金色的颜色“rgb(204,153,51) ”(同时将“白色 ”保留为“白色 ”),将需要以下数学公式...result = 1-(1-color)*(1-intensity)此公式否定颜色,将图像乘以否定后的所需颜色,然后再次否定图像。结果是给灰度级的黑色端着色,保持白色不变。 为了参考,上面也显示了重新映射公式的“ gnuplot ”直方图图形。使用稍微复杂的公式,您可以线性替换灰度级的“黑色 ”和“白色 ”两端特定的颜色。
![]() ![]() ![]() ![]() ![]() -size 1x2 gradient:color1-color2 ”仅用于为“-fx ”公式生成一个双色像素图像以供参考。第一个颜色替换白色,第二个颜色替换黑色,而所有其他颜色都在白色和黑色之间进行插值。与灰度级运算符一样,每个RGB通道都被视为独立的灰度级通道,尽管每个通道的线性插值不同。顺便说一下,这完全等同于按颜色进行色阶调整运算符“+level-colors ”
数学非线性直方图调整虽然线性颜色调整很重要,并且有更快的可行方法,但许多情况下线性“色阶”调整并不符合要求,而这正是“-fx ”DIY 操作符变得更有用的地方。嗯,线性调整的另一种公式是“-fx 'v.p{0,1}+(v.p{0,0}-v.p{0,1})*u' ”,它具有将“u ”替换为单个随机函数“f(u) ”以产生非线性颜色变化的优点。这允许您做更多有趣的事情。例如,在最后一个示例中,如果要将所有颜色推向“黑色 ”侧,从而使图像成为更“砖红 ”的颜色,会怎么样。
![]() ![]() ![]() ![]() ![]() u^2 ”这样的二次公式将直方图的黑色端着色为“.25 ”蓝色。只有蓝色通道需要修改,因此该值直接插入公式中。
但是,虽然这产生了合理的结果,但它确实使中间色调灰色略微变暗,产生了病态的淡黄色。为了避免这种情况,可以使用“指数”函数,以更好地控制着色过程。
同样,该图显示了如何修改蓝色通道以使黑色具有独特的深蓝色色调。第二个值(“4.9 ”)是衰减回线性“+u ”图的值。该值越小,衰减越慢,调整越接近线性。该值越大,衰减越剧烈。可能需要根据不同的颜色值调整该值,因此这不是一个适合一般黑色着色的通用公式,但非常适合为天气地图着色。总的来说,如果您能够用数学公式表达您想要的颜色调整,那么您可以使用“-fx ”操作符来实现您想要的结果。 '曲线' 调整![]() gnuplot ”,“fudgit ”,“mathematica ”和“matlab ”,以及更多数学软件包。以下是使用“gnuplot ”从四个控制点生成公式的一种方法,该方法是大多数Linux发行版以及Windows上可以安装的标准附加软件包。
|
![]() ![]() |
请注意,用于曲线拟合的参数数量(上面的“a ”到“d ”)必须等于您提供的控制点数量。因此,如果您想要五个控制点,则需要在函数中包含另一个“e ”项。如果您的直方图曲线经过固定的控制点 0,0 和1,1 ,则您实际上只需要两个参数,因为“d ”将等于“0 ”,而“c ”将等于“1-a-b ”。 |
gnuplot
”生成的图像中所见,生成的函数完美地拟合了控制点。此外,由于它生成了一个“-fx
”样式公式,因此可以直接用作IM参数。例如...
|
![]() |
im_fx_curves
”的 shell 脚本,用于调用“gnuplot
”并输出给定控制点的更美观的曲线方程。Gabe Schaffer 还提供了一个 Perl 版本(使用下载的“Math::Polynomial
”库模块),名为“im_fx_curves.pl
”,用于执行相同的操作。任一脚本都可以使用。例如,这是一个具有 5 个控制点的不同曲线...然而,FX 函数非常慢。但从 IM 6.4.8-9 版本开始,您现在可以直接将拟合多项式表达式的系数传递到 多项式函数方法 中。您可以使用“im_fx_curves
”和特殊的“-c
”选项生成以逗号分隔的系数列表...
例如,让我们将这些曲线应用到我们的测试图像...
|
![]() |
着色图像
均匀着色图像
通常,着色图像可以通过将图像与颜色混合一定比例来实现。可以使用 评估操作符 或 混合图像 技术来完成,但这些方法并不简单。幸运的是,我们可以使用“-colorize
”图像操作符,通过更简单的方法将均匀颜色混合到图像中。此操作符将当前“-fill
”颜色混合到当前图像序列中的所有图像中。原始图像的 Alpha 通道保留,仅颜色通道被修改。例如,为了使图像变亮(灰度或其他),我们使用“-colorize
”将一定比例的白色混合到图像中,使其变亮,但不会完全饱和。类似地,我们可以使用“black
”填充颜色使图像变暗。要使图像的两端向中间色调变灰,可以使用特定的灰色填充颜色。颜色“gray50
”是 RGB 颜色光谱的正中间颜色。这也经常用作“去对比度”的方法,例如 反向色阶调整操作符 提供的功能,但控制程度较低。 “-colorize
”操作符还允许您分别为三个颜色通道指定溶解百分比。这对于以特殊方式线性地使图像变暗(或变亮)非常有用。![]() ![]() |
在 IM v6.7.9 之前,“-colorize ”操作符不会修改 Alpha 通道。从该版本开始,如上所述,它现在统一着色所有像素,包括完全透明的像素。 |
“-colorize ”操作符的一个常见用途是简单地替换现有图像中的所有颜色(着色“100% ”),但保留图像的透明度(Alpha)形状,以便生成彩色蒙版。但是,从 IM v6.7.9 版本开始,您需要通过禁用 Alpha 通道来保护 Alpha 通道免受此操作符的影响,然后重新启用 Alpha 通道。(有关更多详细信息,请参见 Alpha 开启)。例如...
|
![]() |
如果没有这种保护,colorize 会将画布完全空白为给定颜色...
|
![]() |
-alpha opaque
”或“-alpha off
”操作,以确保生成的图像完全符合您预期的空白图像。请注意,您可以使用 按颜色进行色阶调整 操作符用单个颜色而不是颜色范围更快地空白画布。另请参见 空白画布。 中间色调颜色色调
虽然 着色操作符 应用“-fill
”颜色以线性着色图像中的所有颜色,但“-tint
”操作符应用“-fill
”颜色,以仅着色图像的中间色调颜色。该操作符是一个灰度操作符,颜色由给定的百分比(0 到 200)进行调节或增强。为了限制其效果,它还使用数学公式进行调整,因此它不会影响黑色和白色,但会对每个颜色通道的中间色调颜色产生最大影响。“-tint 100
”基本上会使完美的灰色颜色着色,使其成为填充颜色强度的二分之一。较低的值将使它着色为更暗的颜色,而较高的值将使它着色为更接近该颜色的完美匹配。测试图像中的绿色不是真正的 RGB 绿色,而是缩放矢量图形“green
”,其亮度仅为真正的绿色颜色的一半。因此,它也是一种中间色调颜色,因此受到“-tint
”操作符的影响,变得更暗,与测试图像中的红色和蓝色色点不同。您还可以通过使用以逗号分隔的百分比列表来着色各个颜色分量。例如“-tint 30,40,20,10
”。但这可能很难使用,可能需要一些试验才能正确使用。最好指定您想要的完美的 50% 灰色的颜色。![]() ![]() |
![]() -tint ”操作符通过某种方式获取给定的颜色和百分比,然后根据以下公式调整图像中的各个颜色,根据“-fill ”颜色的强度。(见右图)f(x)=(1-(4.0*((x-0.5)*(x-0.5))))
或者,您可以使用更底层的操作符来自己动手操作此类操作,请参见 FX 操作符 以及 评估和函数操作符。 |
-shade
”输出的结果(参见 阴影叠加突出显示图像),例如 3D 子弹图像 中的示例。您还可以使用“-tint
”来使图像的中间色调颜色变亮或变暗。这有点类似于图像的“伽马调整”,但并不完全相同。例如,使用大于 100 的着色值和“white
”颜色会使中间色调变亮。而小于 100 的值会使颜色变暗。
![]() ![]() |
目前,纯中间色调灰色颜色不会映射到“-fill ”颜色。百分比参数不是“混合百分比”,而更像是“亮度百分比”。例如,它对“黑色”填充颜色根本不起作用。 我不知道它为什么是这样设计的,也不知道它背后的历史。但是,它确实使着色灰度图像时的最终颜色的精确控制变得非常尴尬。 使用下面的 叠加合成着色 将提供更精确(尽管非常线性,而不是抛物线)的中间色调灰色的颜色着色。 |
棕褐色调色
一种特殊的摄影重新着色技术,“-sepia-tone
”基本上是将图像转换为灰度,并将所有中间色调着色为特殊的棕色。
|
![]() |
Goldenrod
”。最常见的用途是生成 双色调效果,以生成“旧式”照片(参见维基百科上的 棕褐色调)。例如,在这里我 着色 增强对比度的灰度玫瑰图像,使用各种颜色,以实现类似的棕褐色效果。您应该使用哪种颜色取决于您要寻找的确切效果。
|
![[IM Output]](rose_grey.jpg)

![[IM Output]](sepia_goldenrod.jpg)
![[IM Output]](sepia_gold.jpg)
![[IM Output]](sepia_khaki.jpg)
![[IM Output]](sepia_wheat.jpg)
|
![]() |
双色调效果
“双色调”是一种印刷方法,您将图像的灰度(黑色油墨)与其他颜色混合,以在预算有限或印刷设备有限的情况下获得更好的效果。例如,今天您看到的所有旧照片都呈现出棕褐色调的原因是,棕褐色油墨保存了下来,没有随着时间的推移而退化或褪色。其他“黑白”图像格式褪色成无用。请参见上面的 棕褐色调操作符。另一种称为“蓝晒”的双色调技术(更常被称为“蓝图”)已成为制作原始黑白建筑图纸的大尺寸副本的一种广泛使用的方法。请记住,这种技术是在激光和复印(以及施乐)发明之前很久就使用了。有关更多信息,请参见维基百科条目 双色调,以及 假双色调与真双色调。上面的 着色操作符 确实生成了双色调效果的合理仿制品,就像它在上面为棕褐色效果所做的那样。
|
![[IM Output]](rose_grey.jpg)

![[IM Output]](duotone_blue.jpg)
![[IM Output]](duotone_darkcyan.jpg)
![[IM Output]](duotone_goldenrod.jpg)
![[IM Output]](duotone_firebrick.jpg)
Black
”、“Chocolate
”和“LemonChiffon
”颜色来创建非常不寻常的双色调。是的,黑点颜色通常保留为黑色,这就是为什么它通常被称为双色调的原因。
magick -size 1x1 xc:Black xc:Chocolate xc:LemonChiffon \ +append duotone_clut.gif magick -size 20x256 gradient: -rotate 90 duotone_clut.gif \ -interpolate Bicubic -clut duotone_gradient.gif magick rose_grey.jpg duotone_clut.gif \ -interpolate Bicubic -clut rose_duotone.jpg |
![[IM Output]](duotone_clut.gif)

![[IM Output]](duotone_gradient.gif)
![[IM Output]](rose_grey.jpg)

![[IM Output]](duotone_clut.gif)

![[IM Output]](rose_duotone.jpg)
颜色色调,DIY
“-tint
” 最大的问题之一是它是一个灰度(或矢量)运算符。也就是说,它完全独立地处理每个红色、绿色、蓝色通道。反过来,这意味着像“blue
”或“yellow
”这样的主色和副色不受“-tint
”的影响,即使所有灰度都受到影响。但是,借助各种通道数学变换,例如 FX 运算符 和更快的 Evaluate 和 Function 运算符,您可以生成自己的颜色叠加来修改图像。也就是说,以类似于 Colorize 运算符 的方式对图像进行 色调 处理。例如,在这里我将图像的灰度亮度级别转换为所需特定颜色的半透明叠加。
|
![]() |
black
”,因为颜色不视为矢量加法,而是 Alpha 合成。结果与您对普通色调获得的结果不太一样。 颜色色调叠加
特殊的 Alpha 合成 方法“Overlay
”和“Hardlight
”实际上是针对颜色(和图案)色调而设计的。这些合成方法还会替换中色调的灰色,只保留图像中的黑色和白色高光。例如,这里我快速生成一个彩色叠加图像,并将其合成到原始图像以对其进行色调处理。
|
![]() |
|
![]() |
Overlay
”是比上面使用的二次函数更线性的色调形式,并且与“-tint
”一样,它分别应用于图像的每个通道,因此主色和副色也保持不变。此外,这种 Alpha 合成方法没有提供调整控制,因此,如果您想控制色调级别,则需要在应用色调之前调整叠加图像的透明度。当然,与我迄今为止展示的其他色调方法不同,您不仅限于对简单颜色进行色调处理,还可以使用图像或平铺图案来应用色调。
|
![]() |
![]() ![]() |
Alpha 合成方法“HardLight ”将产生与“Overlay ”相同的结果,但源图像和目标图像已交换。这可以用来代替最后几个示例中的“ +swap ”。 |
全局颜色修改器
调节亮度、饱和度和色调
“-modulate
”运算符很特殊,因为它在特殊的 HSL(色相-饱和度-亮度)颜色空间 中修改图像。它将图像中的每个颜色像素转换为该颜色空间,对其进行修改,然后将其转换回原始颜色空间。它以百分比的形式接受三个值(虽然后面的值是可选的),因此 100 不会对图像进行任何更改。例如。
|
![]() |
magick rose: -modulate 0 mod_bright_0.gif magick rose: -modulate 50 mod_bright_50.gif magick rose: -modulate 80 mod_bright_80.gif magick rose: -modulate 100 mod_bright_100.gif magick rose: -modulate 150 mod_bright_150.gif magick rose: -modulate 200 mod_bright_200.gif |
![[IM Output]](mod_bright_0.gif)
![[IM Output]](mod_bright_50.gif)
![[IM Output]](mod_bright_80.gif)
![[IM Output]](mod_bright_100.gif)
![[IM Output]](mod_bright_150.gif)
![[IM Output]](mod_bright_200.gif)
0
”的亮度参数将生成纯黑色图像,但您无法使用此运算符单独生成纯白色图像。第二个值饱和度也是一个乘数,它会调整图像中存在的颜色总量。
magick rose: -modulate 100,0 mod_sat_0.gif magick rose: -modulate 100,20 mod_sat_20.gif magick rose: -modulate 100,70 mod_sat_70.gif magick rose: -modulate 100,100 mod_sat_100.gif magick rose: -modulate 100,150 mod_sat_150.gif magick rose: -modulate 100,200 mod_sat_200.gif |
![[IM Output]](mod_sat_0.gif)
![[IM Output]](mod_sat_20.gif)
![[IM Output]](mod_sat_70.gif)
![[IM Output]](mod_sat_100.gif)
![[IM Output]](mod_sat_150.gif)
![[IM Output]](mod_sat_200.gif)
0
”的饱和度将生成灰度图像,如上面 将颜色转换为灰度 中所示。但是,灰色会像 HSL 颜色空间定义的那样,均匀地混合所有三个颜色通道,因此不会生成真实的“亮度”灰度。本质上,较小的值会产生更多“柔和”的颜色,而大于“100
”的值会产生更多卡通化的彩色图像。请注意,由于亮度和饱和度是百分比乘数,因此您需要乘以一个非常大的数字才能将几乎所有图像颜色值更改为接近最大值。也就是说,您需要使用接近一百万的亮度系数才能使除纯黑、白色之外的所有颜色都变成黑色、白色。 色调调制
最后一个值,色调,实际上更有用。它以循环方式旋转图像的颜色。为了实现这一点,给定的色调值会产生“模加法”,而不是乘法。但是要注意,色调是使用百分比旋转的,而不是使用角度旋转的。这可能看起来很奇怪,但“-modulate
”一直都是这样。角度和调制参数之间的转换公式是。色调角 = ( 调制参数 - 100 ) * 180/100
调制参数 = ( 色调角 * 100/180 ) + 100
100
”(对于所有三个参数)不会产生任何变化。虽然“0
”或“200
”的值实际上会否定图像中的颜色(但不会否定亮度)。例如。
magick rose: -modulate 100,100,0 mod_hue_0.gif magick rose: -modulate 100,100,33.3 mod_hue_33.gif magick rose: -modulate 100,100,66.6 mod_hue_66.gif magick rose: -modulate 100,100,100 mod_hue_100.gif magick rose: -modulate 100,100,133.3 mod_hue_133.gif magick rose: -modulate 100,100,166.6 mod_hue_166.gif magick rose: -modulate 100,100,200 mod_hue_200.gif |
![]() 0 (红色 <-> 青色) |
![]() 33.3 (红色 -> 蓝色) |
![]() 66.6 |
![]() 100% 无操作 |
![]() 133.3 |
![]() 166.6 (红色 -> 绿色) |
![]() 200 (与 0 相同) |
33.3
”的值会使所有颜色大约 60 度的负向旋转,或逆时针旋转,有效地将红色映射到蓝色,蓝色映射到绿色,绿色映射到红色。使用“0
”或“200
”的值会产生 180 度的颜色完全否定,而不会否定图像的亮度。请注意,色调是循环的,因此使用“300
”的值将产生 360 度的颜色旋转,并且不会对图像产生任何变化。有关使用“色调调制”来修改图像中颜色的示例,请参见 色度键蒙版 和 地图中的图钉。也可以使用高级 颜色空间 技术来应用这些类型的操作以及更多操作,例如在 重新着色矩阵运算符(下面)中使用,但对于图像的基本“调制”,此运算符极大地简化了操作。对于主要颜色交换,无论是 重新着色矩阵运算符,还是通道交换(参见 分离/组合运算符),可能都是更准确的技术。虽然它没有那么通用。另请参见 Hald 颜色查找表,了解一种可以保存颜色变化(特别是色调变化)以供以后重复使用的方法。
调节 DIY
如果您真的想“自己动手”。您基本上将图像转换到适当的颜色空间,修改值,然后转换回来。请记住,在 HSL 颜色空间 中,绿色通道保存饱和度值,蓝色通道保存亮度值。例如,以下代码等效于“-modulate 80,120
”(稍微变暗,增加颜色饱和度),使用默认的 HSL 颜色空间。
magick rose: -colorspace HSL \ -channel B -evaluate multiply 0.80 \ -channel G -evaluate multiply 1.20 \ +channel -colorspace sRGB modulate_channel.png |
![[IM Output]](../images/rose.png)

![[IM Output]](modulate_channel.png)
在其他颜色空间中调节
“-modulate
”最大的问题是处理包含大量“接近白色”颜色的图像时。由于它在 HSL 颜色空间中完成工作,因此随着亮度降低,偏白色的颜色会变得更加“饱和”。您可以在上面玫瑰图像的白叶中看到这一点,它在 50% 变暗时显示出大量的颜色伪像。这在处理 JPEG 图像格式时尤其是一个问题,因为它由于其有损压缩算法,往往会生成偏白色颜色(实际上所有颜色通常都略微偏色)。例如。这里的问题是在 HSL 中,所有偏白色的颜色都集中在使用颜色空间的小“白点”区域(双锥体)内。当亮度降低时,偏白色的颜色会随着颜色锥体的扩展而扩展,导致偏白色颜色生成更多彩色的(饱和的)偏白色颜色集。也就是说,颜色的小变化会被夸大。解决此问题的方法是在 HSB 颜色空间而不是 HSL 颜色空间中“-modulate
”。![]() ![]() |
HSB 中的“B”表示亮度,但通常也称为 HSV,其中“V”表示值。它们是同一个颜色空间,但“V”是一个令人困惑的术语,因为值通常表示“存储的数字”。 还有一个 HSI 颜色空间(使用“I”表示亮度),但它并不常见,而且由于添加了 HCL(其中“L”表示亮度)循环颜色空间(见下文),因此不需要它。 |
modulate:colorspace
”来使用其中一个“色调”颜色空间。
|
![]() |
magick rose: -modulate 150 mod_bright_HSL.gif magick rose: -define modulate:colorspace=HSB \ -modulate 150 mod_bright_HSB.gif |
![]() HSL |
![]() HSB |
![]() ![]() |
在 IM v6.4.0-10 之前,“-modulate ”运算符实际上使用的是 HSB 颜色空间,而不是 HSL 颜色空间。更改此设置是因为用户报告了上述情况的错误。关键是,对于某些图像,如果您使用 HSL,您就完蛋了,而对于其他图像,如果您使用 HSB 颜色空间,您就完蛋了。这仅仅取决于您尝试执行的操作! |
在 LCHab 和其他颜色空间中调制
色调调制(在 HSL 或 HSB 色彩空间中)实际上被认为相当粗略。这些色彩空间没有考虑到更真实的颜色强度。因此,在“蓝色”和“黄色”色调之间旋转也会产生非常大的亮度变化。参见 维基百科:HSL 色彩空间的缺点。一种替代方法是执行亮度保持旋转,如 Grafica Obscura 的“矩阵运算”论文中所述。这很复杂,因为颜色修改是在操作过程中完成的,作为单个计算的矩阵操作,该操作根据所需的旋转量而不同。从 IM v6.8.4-7 开始,调制运算符 也可以处理特殊的色彩空间“LCHab
”和“LCHuv
”,它们是各自“Luv
”和“Lab
”色彩空间的圆柱形(色调-彩度)形式。参见 维基百科,圆柱形 LUV 或 LCHuv 色彩空间 和 HCL 色彩空间 以了解更多信息。![]() ![]() |
“LCHab ”和“LCHuv ”色彩空间的等效通道与“HCL ”和“HCB ”色彩空间的通道相反。也就是说,“灰度”强度等效位于图像的第一个(“红色”)通道中,而色调位于图像的第三个(“蓝色”)通道中。 |
LCHab
”色彩空间。将这些与上面“HSL
”色彩空间的先前集合进行比较。
|
![]() 0% & 200% |
![]() 25% (红色->蓝色) |
![]() 50% |
![]() 75% |
![]() 100% 无操作 |
![]() 125% |
![]() 150% |
![]() 175% |
LCHab
”与普通“HSL
”色彩空间(使用适当的旋转百分比)的简单色调旋转红色到蓝色的比较。请注意,蓝色绝不像黑色那么深,但它与原始图像的色调更匹配。有关 HCL 色彩空间色调的更多信息,请参阅 LCH 色轮 上的示例。![]() ![]() |
在 IM v6.8.4-7 之前,您将使用色彩空间“HCL ”(IM v6.7.9-1 引入)。该色彩空间与“LCHuv ”完全相同,但通道顺序相反(色调存储在图像的红色通道中,这只是该色彩空间的定义方式)。这意味着您还必须交换各种通道以使 调制运算符 正确工作。“ LCHab ”和“LCHuv ”色彩空间以与“HSL ”相同的方式对通道进行排序,以便允许调制正常工作,并直接对色彩空间进行操作,而无需重新排序通道。 |
![]() ![]() |
请注意,对于非常暗的颜色,“LCHuv ”可能会生成具有不连续性的颜色值。但是,对于真实图像来说,这种情况不应该发生,而只发生在直接在圆柱形空间中生成的图像中。 |
颜色矩阵运算符
“-color-matrix
”运算符将使用矩阵技术重新着色图像。也就是说,您需要提供一组值,这些值表示如何线性混合图像的各种颜色通道值以生成新的颜色值。典型的用法是向运算符提供 9 个值,这些值构成三个函数(行)或三个乘数(列)。因此,前三个数字是“红色”通道的颜色公式。下一个是“绿色”,依此类推,例如……
|
![]() |
red' |
= 1 * red + 0 * green + 0 * blue |
green' |
= 0 * red + 1 * green + 0 * blue |
blue' |
= 0 * red + 0 * green + 1 * blue |
|
![]() |
|
![]() |
|
![]() |
您可以使用更大的矩阵,最多包含 6 行和 6 列。它们对应于以下通道:“
Red
”、“Green
”、“Blue
”、“Black
”(如果设置)、“Alpha
”(如果设置)和一个常数。请注意通道:“Black
”和“Alpha
”;即使值本身可能不存在或未使用,如果矩阵大小为 6,则仍然必须提供它们。最后常数列只是公式的简单加法(如果为负则为减法)。如果给出第 6 行(如果给出),则会简单地忽略它,不使用。默认情况下,“矩阵”定义遵循与 用户定义的形态/卷积核 相同的结构,如果未指定大小几何体,则被视为“方形”核。核的偏移量目前未使用。给定的“值数组”随后被叠加在一个更大的“6x6 单位矩阵”(对角线为 1)上,然后应用于图像。这种内部处理意味着您实际上可以通过仅提供几行数字来简化矩阵值,而不是所有数字。这在您需要在颜色计算中包含“常数”,或者只想修改一个通道时特别有用。例如,反转(取反)图像。
|
![]() |
|
![]() |
![]() ![]() |
在 IM v6.6.1-0 之前,“-color-matrix ”被称为“-recolor ”。 |
颜色矩阵示例
棕褐色,或者至少是该操作的线性形式
|
![]() |
|
![]() |
|
![]() |
如 Grafica Obscura 网页所述。
有关使用颜色矩阵的更多信息,请参见……
- 颜色矩阵滤镜 Adobe Flash 教程
- 颜色变换和颜色矩阵
- ColorMatrix Unleased
- Grafica Obscura - 图像处理的矩阵运算
- SWF 颜色矩阵滤镜(用于亮度保持色调旋转)
太阳化着色
要“-solarize
”图像,基本上就是将最亮的色彩“烧成”黑色。色彩越亮,太阳化后的色彩就越深。这在化学胶片曝光过度时会发生在摄影中。
|
![]() |
0%
”的参数,您基本上就拥有了一个简陋的 取反运算符。例如,以下是用“-fx
”数学公式模拟的“-solarize
”。
|
![]() |
magick -size 10x300 gradient: -rotate 90 \ -sigmoidal-contrast 50x70% fuzzy_thres.png magick fuzzy_thres.png -solarize 50% fuzzy_spike.png magick fuzzy_spike.png -level 0,50% filament.png |
![[IM Output]](fuzzy_thres_pf.gif)

![[IM Output]](fuzzy_spike_pf.gif)

![[IM Output]](filament_pf.gif)
im_profile
”生成的,脚本 目录。请注意,任何白色都变成黑色,而中心尖峰周围的中色调灰色得以保留。尖峰的模糊度和位置由“-sigmoidal-contrast
”运算符决定。我称它为“灯丝”,因为结果通常看起来非常像发光的电灯丝或闪电放电。参见 随机磁通,以了解此效果的另一个示例。从位图形状中提取中色调灰色在生成 边缘轮廓 以及 两个偏差梯度的相乘 的技术中也得到了很好的应用。该操作的另一种新颖用法是确定图像基本上是纯黑白色素描或图画(例如来自书籍),而不是阴影灰度或彩色图像,参见 确定图像是否为:纯黑白色或灰度使用查找表重新着色图像
虽然您可以使用如上所示的各种直方图颜色调整来重新着色图像,但还有另一种重新着色图像的技术,只需从预先准备的颜色梯度或“颜色查找表”(颜色 LUT 或 CLUT)中“查找”修改后的值。颜色 LUT 有两种类型:简单的一维或“每通道”LUT 和 3D 颜色 LUT。通道 LUT 有三个独立的查找表:一个用于 R 通道,一个用于 G 通道,一个用于 B 通道。通道 LUT 中的每个条目都将输入通道值映射到输出通道值。输出图像的红色通道只受输入图像的原始红色值的影響。然而,3D 颜色 LUT 允许将整个颜色作为整个输入颜色的函数进行替换。也就是说,红色通道的输出值可以取决于输入的红色、绿色和蓝色值的任意一个或所有值。这有时被称为通道串扰。颜色(通道)查找表
图像处理工具的常见需求是能够从预先准备的颜色表中替换整个颜色范围。这使您能够将一组颜色(通常为灰度)的图像转换为完全不同的颜色集,只需从特殊图像中查找其替换颜色即可。当然,您需要一个“查找表”图像来读取替换颜色。对于接下来的几个示例,我选择使用颜色垂直梯度作为 LUT,以便 IM 的“gradient:
”生成器可以用来简化“颜色查找表”的生成。好了,理论到此为止。让我们尝试通过重新着色一个简单的 灰度等离子体 图像来试用一下,用深蓝色到淡白色的颜色梯度替换灰度。
|
![[IM Output]](gray_image.jpg)

![[IM Output]](gradient_ice-sea.png)

![[IM Output]](gray_recolored.jpg)
-clut
”运算符接受两个图像。第一个是要替换颜色值的图像,第二个是一个梯度图像,它要么是一行,要么是一列。![]() ![]() |
“-clut ”运算符是在 IM v6.3.5-8 中添加的。 |
-clut
”运算符,或者您想做一些不寻常的事情,例如二维颜色查找表,那么您可以使用 通用 DIY 运算符,FX 来自己实现。例如,以下是一个速度较慢但与上述命令等效的命令。
|
![]() |
-fx
" 运算符也非常慢,并且必须专门针对行或列 LUT 设计。但是它确实有效。LUT 不必很大。例如,这里我们使用一个非常小的 LUT,并且颜色数量非常有限。
magick -size 1x6 gradient:navy-snow gradient_levels.png magick gray_image.jpg gradient_levels.png -clut gray_levels.jpg |
![[IM Output]](gray_image.jpg)

![[IM Output]](gradient_levels_mag.png)

![[IM Output]](gray_levels.jpg)
双线性
' 设置,它只是将每个彩色像素与线性线段连接起来。不同的 "-interpolate
" 设置在使用非常小的颜色 LUT 时会生成不同程度的颜色平滑。例如,这里我展示了各种类型的 LUT 颜色插值平滑。
magick gray_image.jpg gradient_levels.png \ -interpolate Integer -clut gray_levels_integer.jpg magick gray_image.jpg gradient_levels.png \ -interpolate NearestNeighbor -clut gray_levels_nearest.jpg magick gray_image.jpg gradient_levels.png \ -interpolate Average -clut gray_levels_average.jpg magick gray_image.jpg gradient_levels.png \ -interpolate Blend -clut gray_levels_blend.jpg magick gray_image.jpg gradient_levels.png \ -interpolate BiLinear -clut gray_levels_bilinear.jpg magick gray_image.jpg gradient_levels.png \ -interpolate Catrom -clut gray_levels_catrom.jpg magick gray_image.jpg gradient_levels.png \ -interpolate Spline -clut gray_levels_spline.jpg |
![]() 整数 |
![]() 最近邻 |
![]() 平均 |
![]() 混合 |
![]() 双线性 |
![]() Catrom |
![]() 样条曲线 |
整数
' 和 '最近邻
' 设置是特殊的,因为它们根本不会平滑颜色。也就是说,不会添加任何新的“混合颜色”,只有存在的精确颜色值将用于对灰度图像进行着色。但是请注意,这两种方法的颜色查找方式不同。这是一个细微的差别,但可能非常重要。“平均
” 设置另一方面也生成了颜色带,但只使用颜色的混合,导致的颜色比颜色查找表图像的大小少一个。“混合
” 然而混合了“平均
” 和“最近邻
”,以添加更多像素。这种类型的颜色“条带”(或 块状伪影)实际上在地理地图和温度图中相当常见,因为它更好地表示了地图的精确形状。锐利的边界边缘被称为等高线。在最终图像上添加一个轻微的单像素 模糊 可以改善这些边缘的外观,使其看起来更平滑,而不会破坏颜色条带。“双线性
” 设置也会生成条带,但只有在颜色急剧变化时才以急剧的渐变变化的形式出现(在本例中没有)。而“Catrom
” 将使颜色变化平滑。最后,“样条曲线
” 会模糊颜色,并且可能不会生成给定 CLUT 中的任何颜色。为了避免插值问题,或更好地定义颜色渐变,最好的方法是使用更长的 LUT。理想情况下,这应该涵盖所有可能的强度值范围。对于 ImageMagick Q16(用 16 位质量编译),这需要 LUT 的高度为 65536 像素。但 像素插值 允许您使用更合理的 500 像素 LUT 渐变图像,适合大多数图像重新着色任务。请注意,以上示例中使用的垂直渐变 LUT 在我们眼中看起来是倒置的,因为黑色或 '0
' 索引位于图像的顶部。通常,我们人类更喜欢看到黑色水平位于底部的渐变(这要归功于我们的进化历史)。如果您想以“正确的方式”保存渐变图像,则可以在读取图像时对图像进行 "-flip
"。例如,让我们尝试一个更复杂的 LUT,在将它用于图像之前翻转垂直渐变。
magick -size 1x33 gradient:wheat-brown gradient:Brown-LawnGreen \ gradient:DodgerBlue-Navy -append gradient_planet.png magick gray_image.jpg \ \( gradient_planet.png -flip \) -clut gray_planet.jpg |
![[IM Output]](gray_image.jpg)

![[IM Output]](gradient_planet.png)

![[IM Output]](gray_planet.jpg)
函数到颜色 LUT 转换
这些预先准备好的“查找表图像”(或 LUT)也可以用来极大地提高非常复杂且因此很慢的 "-fx
" 运算速度,因此 IM 不必每像素解释 3 或 4 次功能字符串,而是可以更快地查找替换颜色。执行此操作的过程非常简单,要么将函数应用于未修改的线性渐变,要么将函数中的 'u
' 替换为值 '(i/w)
' 或 '(j/h)
',以根据其位置计算替换值。例如,在高级 '水下' 效果 示例中,我使用了一个复杂的 "-fx
" 函数来调整 阴影运算符 的灰度输出”。同样,由于这种灰度调整也叠加在“DodgerBlue”形状上,因此这两个运算符的结果没有理由不能合并到单个渐变查找表中。也就是说,我们从 "-fx
" 公式和颜色叠加生成一个 LUT。同样,对于这些示例,我决定生成一行像素,而不是像之前那样生成一列像素。
magick -size 1x512 gradient: -rotate 90 -alpha off \ -fx '3.5u^3 - 5.05u^2 + 2.05u + 0.3' \ -size 512x1 xc:DodgerBlue -compose Overlay -composite \ aqua_gradient.png |
![[IM Output]](aqua_gradient.png)
![]() ![]() |
上面的多项式 "-fx " 现在可以使用 多项式函数 更直接、更快地生成。例如
"-function Polynomial 3.5,-5.05,2.05,0.3" |
magick -font Candice -pointsize 72 -background None label:A \ -trim +repage aqua_mask.png magick aqua_mask.png -alpha Extract -blur 0x6 -shade 120x21 \ -alpha On -normalize aqua_shade.png magick aqua_shade.png aqua_gradient.png -clut aqua_font.png |
![[IM Output]](aqua_mask.png)

![[IM Output]](aqua_shade.png)

![[IM Output]](aqua_font.png)
警告:以上内容不完整(边缘尚未变暗)
CLUT 和透明度处理
"-clut
" 运算符受 "-channel
" 设置控制,但实际上,它只替换图像中的单个通道值。这意味着,通常源图像的每个通道都被用来从颜色查找表中“查找”仅该通道的替换值。这包括 alpha 通道,它通常很不方便,而且难以应用。通常 "-clut
" 运算符用于对灰度源图像进行着色(请参见前面的示例),或者用于使用灰度 CLUT(颜色查找表)对彩色图像进行直方图调整。换句话说,通常其中一张图像将是灰度图像。从 IM v6.4.9-8 开始,如果 "-channel
" 设置指定要替换/调整图像的 alpha 通道(存在一个 'A
'),并且“源”图像或“CLUT”图像都没有定义 alpha 通道,那么 IM 将假设该图像为灰度图像,并相应地采取行动。例如,这里我生成一个简单的模糊三角形,作为一个灰度图像。然后,我可以使用包含透明度的颜色查找表进行着色。这一次我没有翻转 CLUT 图像,因此黑色替换将在顶部,白色替换将在底部。
magick -size 100x100 xc: -draw 'polygon 50,10 10,80 90,80' \ -blur 0x10 blurred_shape.jpg magick -size 1x5 xc:none \ -draw 'fill red point 0,2' \ -draw 'fill yellow rectangle 0,0 0,1' gradient_border.png magick blurred_shape.jpg -alpha off gradient_border.png \ -channel RGBA -interpolate integer -clut clut_shape.png |
![[IM Output]](blurred_shape.jpg)

![[IM Output]](gradient_border.png)

![[IM Output]](clut_shape.png)
-alpha off
" 或 "-alpha off
" 关闭)并且您指定也想要查找 alpha 通道值(使用 "-channel RGBA
")时,以上操作才能按预期工作。以下是另一种特殊情况,其中我们有一个具有透明度(和 alpha 通道)的图像,需要使用灰度直方图调整渐变(没有启用 alpha 通道)进行调整。
magick -size 100x100 xc:none -draw 'polygon 50,10 10,80 90,80' \ tile_disks.jpg -compose In -composite shape_triangle.gif magick shape_triangle.gif -channel A -blur 0x10 +channel shape_blurred.png magick -size 1x50 gradient: xc:black -append -flip \ -sigmoidal-contrast 6x0% feather_histogram.jpg magick shape_blurred.png \( feather_histogram.jpg -alpha off \) \ -channel A -clut shape_feathered.png |
![[IM Output]](shape_triangle.gif)

![[IM Output]](shape_blurred.png)

![[IM Output]](feather_histogram.jpg)

![[IM Output]](shape_feathered.png)
-blur
" 操作使包围三角形的完全透明区域变得可见造成的。由于完全透明具有未定义的颜色,因此 IM 默认使用黑色。CLUT 图像本身的设计确保任何透明度小于 50% 的像素都将变为完全透明,从而有效地使图像中以前完全透明的部分再次透明。对于此示例,我过度使用了初始“模糊”,然后过度校正了 alpha 通道调整。结果是三角形的尖端被严重圆化。对于正常的图像羽化,通常会对 "-blur
" 和 "-sigmoidal-contrast
" alpha 调整使用更小的值。 Fred Weinhaus 在他的 "feather" 脚本中实现了一种模糊羽化技术,以使其更易于使用。 Hald 3D 颜色查找表
从 IM v6.5.3-4 开始,您现在还可以使用完整的 3D 颜色查找表,它可以用来直接替换多个图像的所有颜色。也就是说,它不只是像上面 CLUT 中那样将每个颜色通道的值作为独立实体进行查找,而是使用整个颜色来查找新颜色。但是,3D 颜色表通常需要使用特殊的格式来正确存储 3D 颜色值数组。然而,通过使用颜色值的特殊排列,可以将 3D 表存储到称为 Hald 颜色 LUT 的 2D 图像中。这只是一个普通的图像,因此可以使用任何好的图像文件格式来保存 Hald 3D 颜色 LUT。有关 HALD 图像的更多详细信息和示例,请参见官方网站 Hald 图像,Clut 技术。要生成 Hald 3D 颜色表,请使用 'HALD:{level}
' 图像生成器。例如,这里有一个很小的,我已经放大了,所以你可以看到各个像素...该表包含一个边长为 '{level}2
' 色彩或 9 色彩的色立方体。完整的色立方体包含 '9 × 9 × 9
' 种色彩,共计 729 种色彩,存储在一个大小为该数字平方根的图像中,即 27x27 像素。色彩的存储方式是,前 9 种色彩(左上角)形成从 '纯黑色' 到 '纯红色' 的渐变。每隔 9 种色彩,就会形成 '绿色' 的渐变,每隔 81 种色彩,就会形成 '蓝色' 的渐变。右下角的最后一种色彩为 '纯白色'。你可以将该图像看作是一个更简单的 1D 像素数组,它被引用为一个 3D 色立方体,这样更容易理解。现在这只是一张小的 HALD CLUT 图像。通常,你至少会使用一个 level 8 的 Hald(*默认*),它将包含一个每边 64 种色彩的色立方体,即 64^3 = 262144 种色彩,并生成一个大小为 512x512 像素的图像,并保存为大约 10Kbyte 的 PNG 图像。这并非所有 8 位色彩,但已经相当不错。对于一个包含所有 8 位色彩的 HALD 图像,你需要一个 level 16 版本,生成一个 4096x4096 的图像。这仅仅是为了证明,即使是普通的数码相机图像通常也不能包含所有可能的 8 位色彩。然而,可以采用更小的 Hald 图像,因为 IM 将从 Hald 中插值邻近的 8 种色彩,以计算出查找替换的最终色彩。它只是不会像更大版本的表示那样好。不建议使用大于 8 的 Hald 图像,因为它们需要非常大的图像,并且每个值的深度至少为 16 位才能存储。现在这些生成的 hald 图像是 '身份' 或 '无操作' CLUT 图像。也就是说,它们是形成 3D 色立方体的正常色彩值,因此不会对图像产生任何改变。例如,让我们使用 "-hald-clut
" 运算符应用 '无操作' Hald 图像...这张图像与原始图像完全相同,并且 Hald 图像中没有包含任何更改。然而,通过修改 Hald 图像,无论是手动修改还是使用颜色修改,你都可以用修改后的色彩替换原始色彩。例如,这里我创建一个混合的棕褐色色调方案...
magick hald_3.png \( +clone -sepia-tone 60% \) -evaluate-sequence mean hald_sepia.png magick rose.png hald_sepia.png -hald-clut rose_hald_sepia.png |
![[IM Output]](../images/rose.png)

![[IM Output]](hald_sepia.png)

![[IM Output]](rose_hald_sepia.png)
Gimp
" 或 "Photoshop
" 等图像编辑器,或者如果保存在 枚举的像素文本图像 中,可以使用纯文本编辑器!所有这些都特别适用于非常复杂的颜色修改 *请将你发现有趣或有用的任何 Hald CLUT 图像发邮件给我,我将在本文中以示例形式展示它们。你将在这里获得相应的署名!* Hald CLUT 限制
与使用 CLUT 运算符 进行更简单的 1 维渐变查找不同,你可以使用 Hald CLUT 来旋转色彩。例如,交换红色和蓝色。这是一种更加通用的 CLUT 方法。然而,它不适合用于更简单的事情,例如给灰度图像着色,或进行颜色值的直方图调整。它还可以通过在 Hald CLUT 图像中保存这样的替换色彩,将色彩替换为透明或半透明的值。然而,这种替换查找仅根据色彩进行。你无法使用它以特定的方式替换透明色彩。毕竟它不是一个 4D 色彩查找超立方体!使用 Hald CLUT 替换颜色
现在,由于整个颜色值被用于查找颜色替换,你也可以将其作为一种直接用其他颜色替换图像中所有颜色的方法。然而,由于 IM 目前对 Hald 进行线性插值查找,你需要在 3D 色立方体的所有 8 个相邻颜色单元格中设置替换颜色。

完整颜色映射替换
未来:用另一个颜色映射中的色彩替换一个颜色映射中的所有色彩。欢迎提出有关如何最好地实现此目的的建议,或让程序员实现一些图像颜色映射功能。一种方法可能是使用 符号抖动 中介绍的想法。目前已知最好的解决方案(但并不理想)由 Fred Weinhaus 在他的 "mapcolors
" 脚本中提供。该脚本本质上是逐个映射每个色彩,将一个图像中涉及的像素遮罩到一个新的初始空白图像中。另一个想法是将 3 维色彩替换映射到 HALD 颜色表 中。这不仅会映射指定的色彩,还会以逻辑的方式重新映射指定色彩之间的色彩。需要 HALD 生成器。

More color options yet to be looked at in detail... -contrast -brightness-contrast Color Cycling? -cycle shift colormap (for animations of fractals???) Chromaticity Color Points??? –white-point x,y –red-primary x,y –green-primary x,y –blue-primary x,y Thresholds (after negation) Specifically -white-threshold and -black-threshold