RGB to HSV conversion using PIL

蹲街弑〆低调 提交于 2019-12-30 03:17:06

问题


I'm trying to automate the enhancement of some images that are to be transfered to a digital frame. I have code in place that resizes, adds a date/time to the least-significant (least details) corner of the image and pastes together pairs of portrait images to avoid displaying a single portrait in the frame's 41:20 low resolution screen.

I've implemented a brightness-stretching filter for those pictures where the lighting wasn't so good, using the colorsys.rgb_to_hsv function to calculate H, S, V bands, operating on the V one and then converting back to RGB before saving a JPEG in the digital frame. Obviously, the conversion takes a lot of time, even using itertools tricks; I managed to improve things using psyco.

However, I noticed an example for the PIL Image.convert where RGB can be converted to XYZ color space using a 4×4 matrix as a second argument to the convert method, and I got to wonder:

How can I convert RGB to HSV (and then HSV back to RGB) using a custom matrix in the convert method call? (Minor rounding errors are not important in this case, so I don't mind that each band will be expressed as a series of 0…255 integers)

Thank you in advance.


回答1:


Although I've seen references[1] that claim HSV color-space is linear transformation from RGB, which would seem to imply that it could be done with a matrix, I have been unable to find or determine for myself just what such a matrix would look like. In a way this doesn't really surprise me based on all the [similar] non-matrix procedural implementations I've also seen -- the way they go about it doesn't look linear.

Anyway, while looking into this, I ran across a [somewhat dated] article in former SGI researcher Paul Haeberli's online computer graphics notebook titled Matrix Operations for Image Processing which describes how to do a number of different color transformations using 4x4 matrices which might help you. All of the examples given operate directly on RGB color images and, like geometric matrix transformations, any sequence of them can be combined into a single matrix using concatenation.

Hope this helps.


[1]: Colour Space Conversions <http://www.poynton.com/PDFs/coloureq.pdf>:

2.7.3 HSL (Hue Saturation and Lightness)

This represents a wealth of similar colour spaces, alternative names include HSI (intensity), HSV (value), HCI (chroma / colourfulness), HVC, TSD (hue saturation and darkness) etc. Most of these colour spaces are linear transforms from RGB and are therefore device dependent and non–linear. Their advantage lies in the extremely intuitive manner of specifying colour. It is very easy to select a desired hue and to then modify it slightly by adjustment of its saturation and intensity.




回答2:


The formula to transform an RGB value to an HSV value can be found here: http://www.rapidtables.com/convert/color/rgb-to-hsv.htm. I once needed it the other way around, and made the following function for it.

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]


来源:https://stackoverflow.com/questions/4554627/rgb-to-hsv-conversion-using-pil

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!