convert RGB values to equivalent HSV values using

2020-06-17 14:13发布

I want to convert RGB values to HSV using python. I got some code samples, which gave the result with the S and V values greater than 100. (example : http://code.activestate.com/recipes/576554-covert-color-space-from-hsv-to-rgb-and-rgb-to-hsv/ ) . anybody got a better code which convert RGB to HSV and vice versa

thanks

6条回答
我只想做你的唯一
2楼-- · 2020-06-17 14:47

If using PIL, with a recent copy of Pillow, one should probably use

def rgb2hsv(image):
    return image.convert('HSV')
查看更多
Lonely孤独者°
3楼-- · 2020-06-17 14:51

Based on array indexing and slicing in numpy, this is my approach for the forward:

import numpy as np

def rgb2hsv(rgb):
    """ convert RGB to HSV color space

    :param rgb: np.ndarray
    :return: np.ndarray
    """

    rgb = rgb.astype('float')
    maxv = np.amax(rgb, axis=2)
    maxc = np.argmax(rgb, axis=2)
    minv = np.amin(rgb, axis=2)
    minc = np.argmin(rgb, axis=2)

    hsv = np.zeros(rgb.shape, dtype='float')
    hsv[maxc == minc, 0] = np.zeros(hsv[maxc == minc, 0].shape)
    hsv[maxc == 0, 0] = (((rgb[..., 1] - rgb[..., 2]) * 60.0 / (maxv - minv + np.spacing(1))) % 360.0)[maxc == 0]
    hsv[maxc == 1, 0] = (((rgb[..., 2] - rgb[..., 0]) * 60.0 / (maxv - minv + np.spacing(1))) + 120.0)[maxc == 1]
    hsv[maxc == 2, 0] = (((rgb[..., 0] - rgb[..., 1]) * 60.0 / (maxv - minv + np.spacing(1))) + 240.0)[maxc == 2]
    hsv[maxv == 0, 1] = np.zeros(hsv[maxv == 0, 1].shape)
    hsv[maxv != 0, 1] = (1 - minv / (maxv + np.spacing(1)))[maxv != 0]
    hsv[..., 2] = maxv

    return hsv

and backward color space conversion:

def hsv2rgb(hsv):
    """ convert HSV to RGB color space

    :param hsv: np.ndarray
    :return: np.ndarray
    """

    hi = np.floor(hsv[..., 0] / 60.0) % 6
    hi = hi.astype('uint8')
    v = hsv[..., 2].astype('float')
    f = (hsv[..., 0] / 60.0) - np.floor(hsv[..., 0] / 60.0)
    p = v * (1.0 - hsv[..., 1])
    q = v * (1.0 - (f * hsv[..., 1]))
    t = v * (1.0 - ((1.0 - f) * hsv[..., 1]))

    rgb = np.zeros(hsv.shape)
    rgb[hi == 0, :] = np.dstack((v, t, p))[hi == 0, :]
    rgb[hi == 1, :] = np.dstack((q, v, p))[hi == 1, :]
    rgb[hi == 2, :] = np.dstack((p, v, t))[hi == 2, :]
    rgb[hi == 3, :] = np.dstack((p, q, v))[hi == 3, :]
    rgb[hi == 4, :] = np.dstack((t, p, v))[hi == 4, :]
    rgb[hi == 5, :] = np.dstack((v, p, q))[hi == 5, :]

    return rgb

I was motivated to write these lines as I wasn't convinced by a pixel-wise conversion due to the computational overload and also did not want to rely on another library such as OpenCV.

Feel free to suggest a modification to make this solution more elegant and generic.

查看更多
家丑人穷心不美
4楼-- · 2020-06-17 15:03

I suggest to work with OpenCV

import cv2

# Read the image - Notice that OpenCV reads the images as BRG instead of RGB
img = cv2.imread('myimage.jpg')

# Convert the BRG image to RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# Convert the RGB image to HSV
img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
查看更多
看我几分像从前
5楼-- · 2020-06-17 15:06

I've looked at the various libraries from opencv, colorsys and PIL.

colorsys is not very accurate but gets within 15 degrees. Most of the time within 3 degress. FOr the others there seems to be minor dependencies over a few degrees, but who is more correct? I don't know. But here is my numpyfied rgb to hsv code. I think it's pretty good but I am sure it could be better optimized somehow. The most obvious would be to combine the H, s, and v. Yes that is there also. Mine's more accurate then colorsys for sure, but you definitely see some small rounding errors. But hey it does the whole array in several steps at least. Sorry no invert code. Maybe another day I will write it. Ok so last thing is I don't assume scale. You have to add your own post scaling for the separate hue, sat, and val. the optional s argument is input scaling to 1, the dhue, dsat and dval are out scaling. And yes this is for 2dim arrays. it shouldn't be hard to fix it to work on while, or just reshape your stuff to 2dim and then back again.

def rgb_hue(rgb, s=1):
  nrgb = rgb.astype(np.float64) / float(s)
  nmax = np.max(nrgb,1)
  ndelta = nmax - np.min(nrgb,1)
  return (np.where(ndelta == 0, 0
      , np.where(nmax == nrgb[:,0], nrgb[:,1]-nrgb[:,2]
      , np.where(nmax == nrgb[:,1], (nrgb[:,2]-nrgb[:,0])+2
      , (nrgb[:,0]-nrgb[:,1])+4))) / 6.) % 1.

def rgb_saturation(rgb, s=1):
  nrgb = rgb.astype(np.float64) / float(s)
  nmax = np.max(nrgb,1)
  ndelta = nmax - np.min(nrgb,1)
  return np.where(nmax == 0, 0, ndelta / nmax)

def rgb_value(rgb, s=1):
  nrgb = rgb.astype(np.float64) / float(s)
  nmax = np.max(nrgb,1)
  return nmax

def rgb_hsv(rgb, s=1, dhue=1, dsat=1, dval=1):
  nrgb = rgb.astype(np.float64) / float(s)
  nmax = np.max(nrgb,1)
  ndelta = nmax - np.min(nrgb,1)
  hue = (np.where(ndelta == 0, 0
      , np.where(nmax == nrgb[:,0], nrgb[:,1]-nrgb[:,2]
      , np.where(nmax == nrgb[:,1], (nrgb[:,2]-nrgb[:,0])+2
      , (nrgb[:,0]-nrgb[:,1])+4))) / 6.) % 1.
  sat = np.where(nmax == 0, 0, ndelta / nmax)
  val = nmax
  return np.column_stack((hue*dhue, sat*dsat, val*dval))
查看更多
放荡不羁爱自由
6楼-- · 2020-06-17 15:10

Did you try using the colorsys library?

The colorsys module defines bidirectional conversions of color values between colors expressed in the RGB (Red Green Blue) color space used in computer monitors and three other coordinate systems: YIQ, HLS (Hue Lightness Saturation) and HSV (Hue Saturation Value)

Example (taken from the above link):

>>> import colorsys
>>> colorsys.rgb_to_hsv(.3, .4, .2)
(0.25, 0.5, 0.4)
>>> colorsys.hsv_to_rgb(0.25, 0.5, 0.4)
(0.3, 0.4, 0.2)
查看更多
成全新的幸福
7楼-- · 2020-06-17 15:12

What values of R, G, and B did you put in, and what values of H, S, and V that look erroneous did you get out?

The code you link to, like colorsys, expects float values between 0.0 and 1.0. If you call it with integer values in the 0-to-255 range, you'll get bogus results. It should work fine if you give it the input values it expects.

(It is a distinct failure of that code sample that it does not actually document what sorts of inputs it expects.)

查看更多
登录 后发表回答