【问题标题】:RGB to HSV conversion using PIL使用 PIL 将 RGB 转换为 HSV
【发布时间】:2011-06-01 01:50:06
【问题描述】:

我正在尝试自动增强某些要传输到数码相框的图像。我有代码可以调整大小,将日期/时间添加到图像最不重要(最少细节)的角落,并将成对的肖像图像粘贴在一起,以避免在框架的 41:20 低分辨率屏幕上显示单个肖像。

我已经为那些光线不太好的图片实现了一个亮度拉伸滤镜,使用colorsys.rgb_to_hsv 函数来计算 H、S、V 波段,在 V 波段上运行,然后转换回 RGB在数码相框中保存 JPEG 之前。显然,转换需要很多时间,即使使用itertools技巧;我设法使用psyco 改进了一些东西。

但是,我注意到 PIL Image.convert 的一个示例,其中 RGB 可以使用 4×4 矩阵作为 convert 方法的第二个参数转换为 XYZ color space,我想知道:

如何在 convert 方法调用中使用自定义矩阵将 RGB 转换为 HSV(然后将 HSV 转换回 RGB)? (在这种情况下,较小的舍入误差并不重要,所以我不介意每个波段将表示为一系列 0…255 整数)

提前谢谢你。

【问题讨论】:

  • 注:有可能我所做的也可以通过ImageOps.autocontrast函数来完成;但是,我希望能够根据需要扩展过滤器(例如,可能会增加一点饱和度),这就是为什么我想要一个快速的 RGB↔HSV 方法)。

标签: python python-imaging-library color-space


【解决方案1】:

虽然我看到参考文献 [1] 声称 HSV 颜色空间是来自 RGB 的线性变换,这似乎暗示它可以用矩阵完成,但我自己无法找到或确定什么这样的矩阵看起来像。在某种程度上,基于我也见过的所有 [类似的] 非矩阵过程实现,这并不让我感到惊讶——它们的执行方式看起来不是线性的。 p>

无论如何,在研究这个问题时,我在前 SGI 研究员 Paul Haeberli 的在线计算机图形笔记本上看到一篇 [有点过时的] 文章,标题为 Matrix Operations for Image Processing,它描述了如何使用 4x4 矩阵进行许多不同的颜色转换这可能会帮助你。给出的所有示例都直接对 RGB 彩色图像进行操作,并且与几何矩阵变换一样,它们的任何序列都可以使用串联组合成单个矩阵。

希望这会有所帮助。


[1]:色彩空间转换 http://www.poynton.com/PDFs/coloureq.pdf>:

2.7.3 HSL(色相饱和度和亮度)

这代表了很多类似的 颜色空间,替代名称 包括 HSI(强度)、HSV(值)、 HCI(色度/色彩)、HVC、 TSD(色相饱和度和暗度)等。 大多数这些色彩空间是 RGB 的线性变换 并且是 因此设备依赖和 非线性的。他们的优势在于 极其直观的方式 指定颜色。这很容易 选择所需的色调,然后 通过调整稍微修改它 它的饱和度和强度。

【讨论】:

  • 谢谢,我正在调查。和你一样,到目前为止我看到的代码并没有让我对我的问题的积极回答持乐观态度……
  • 接近的东西(但没有雪茄):Converting between RGB and…,作者 Paul Bourke。不幸的是,YIQ/YUV 的来回转换会扭曲很多颜色信息。这可能是由于矩阵中数字的小数位数很少。在任何情况下,它们都不能按原样使用。
  • 转换确实是线性的,但它们是分段的,所以我认为用单个矩阵进行转换是不可能的(而且我不确定使用“分段-矩阵”)。
【解决方案2】:

可在此处找到将 RGB 值转换为 HSV 值的公式:http://www.rapidtables.com/convert/color/rgb-to-hsv.htm。我曾经反过来需要它,并为它制作了以下功能。

def hsb2rgb(hsb):
    '''
    Transforms a hsb array to the corresponding rgb tuple
    In: hsb = array of three ints (h between 0 and 360, s and v between 0 and 100)
    Out: rgb = array of three ints (between 0 and 255)
    '''
    H = float(hsb[0] / 360.0)
    S = float(hsb[1] / 100.0)
    B = float(hsb[2] / 100.0)

    if (S == 0):
        R = int(round(B * 255))
        G = int(round(B * 255))
        B = int(round(B * 255))
    else:
        var_h = H * 6
        if (var_h == 6):
            var_h = 0  # H must be < 1
        var_i = int(var_h)
        var_1 = B * (1 - S)
        var_2 = B * (1 - S * (var_h - var_i))
        var_3 = B * (1 - S * (1 - (var_h - var_i)))

        if      (var_i == 0):
            var_r = B     ; var_g = var_3 ; var_b = var_1
        elif (var_i == 1):
            var_r = var_2 ; var_g = B     ; var_b = var_1
        elif (var_i == 2):
            var_r = var_1 ; var_g = B     ; var_b = var_3
        elif (var_i == 3):
            var_r = var_1 ; var_g = var_2 ; var_b = B
        elif (var_i == 4):
            var_r = var_3 ; var_g = var_1 ; var_b = B
        else:
            var_r = B     ; var_g = var_1 ; var_b = var_2

        R = int(round(var_r * 255))
        G = int(round(var_g * 255))
        B = int(round(var_b * 255))

    return [R, G, B]

【讨论】:

  • 我已经使用了colorsys 模块。该问题询问了可以与convert 函数一起使用的矩阵。
猜你喜欢
  • 2014-04-09
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
相关资源
最近更新 更多