如何更改图像的整体色调,类似于 Photoshop 的色调调整?

How can I change the overall hue of an image, akin to Photoshop's hue adjustment?

在 Photoshop 中,我可以调整图像的整体色调,使 black/white/grey 级别不受影响,而色调分别更改为 -100 左右(附有比例图片)。是否有可以实现此目的的 MATLAB 或 PsychToolbox 函数?

例如,一些像 newImage = hueadjust(Image, -100) 或像这样简单的函数。

我有很多图像,我确信有一种方法可以通过 Photoshop 对我的所有图像进行批处理,以便对所有图像应用相同的色调比例,但我想知道是否可以通过代码相对轻松地实现这一点,因为我缺乏的编码经验。

是的,这很简单。只需将图像转换为 HSV,获取色调通道并加减 360 度模数,然后将图像转换回来。请注意,操纵色调不会影响图像中看到的 black/gray/white 颜色,这实际上是您想要的。 HSV 颜色 space 中的饱和度和值分量为我们做到了这一点。每个像素的色调分量的加法 and/or 减法是 Photoshop(以及其他类似的图形编辑器,如 GIMP)在后台执行的操作。

使用函数rgb2hsv and its equivalent counterpart hsv2rgb。然而,每个转换通道的动态范围是 [0,1],但通常色调表示在 0 到 360 度之间。因此,将色相通道乘以 360,取模,然后除以 360。

如果您想像在 post 中那样创建一个名为 hueadjust 的函数,只需执行以下操作:

function newImage = hueadjust(img, hAdjust)
    hsv = rgb2hsv(img);
    hue = 360*hsv(:,:,1);
    hsv(:,:,1) = (mod(hue + hAdjust, 360)) / 360;
    newImage = hsv2rgb(hsv);
end

第一行代码将图像转换为 HSV。下一行代码将色调通道复制到一个名为 hue 的变量中,并将每个值乘以 360。然后我们通过获取原始图像的每个色调值(存储在hue) 通过 hAdjust 添加每个色调,这是所需的度数偏移,并确保如果我们超过 360 度则返回到 0(这就是 mod 正在做的),然后除法360 度的结果回到预期的 [0,1] 动态范围。此修改后的图像现在被转换回 RGB 并发送到输出。

请注意,由于调用了 hsv2rgb,输出图像将是 double 类型。每个通道的动态范围仍在 [0,1] 范围内,因此您可以轻松地将这些图像写入文件而不会出现问题。如果您出于某种原因想要返回到图像本身的原始类型,您可以使用图像处理工具箱中的 im2uint8 等函数将输入转换回其无符号 8 位整数形式。实践中看到的大部分图像都采用这个标准。

这是一个简单的示例,可以了解此功能的工作原理。另外为了完整起见,让我们看看色相圈是什么样子的:

来源:Lode's Computer Graphics Tutorial

我们可以看到红色的色相约为 0 度,而洋红色的色相约为 315 度或 -45 度。让我们也使用 MATLAB 中图像处理工具箱附带的 onions.png 图像。它看起来像这样:

我们也先读读这张图片。上图可以直接从网上读入使用图片所指的URL:

im = imread('http://i.stack.imgur.com/BULoQ.png');

IPT imread 功能的好处在于您可以直接从 Internet 读取图像。我想变换或移动色调,使红色调为洋红色,这意味着将每个色调中的所有色调移动 -45 度。所以 运行 函数像这样:

out = hueadjust(im, -45);

显示带有 imshow(out) 的图像,我们得到:

请注意,变换后的其余色调是有意义的。果岭是一种相当暗淡的绿色,可能徘徊在 60 度左右的色调。减去 45 会将其推到红色调,您可以在生成的图像中看到它。黄色也是如此,因为它们徘徊在 30 - 40 度左右的色调。另请注意,白色很可能会受到一点影响,因为在这些白色区域中看到的颜色不是纯白色(a.k.a。不是 100% 饱和度),这是可以预料的。