使用python将RGB值转换为等效的HSV值

时间:2010-04-10 05:24:04

标签: python image-processing

我想使用python将RGB值转换为HSV。我得到了一些代码示例,其结果是S和V值大于100.(例如:http://code.activestate.com/recipes/576554-covert-color-space-from-hsv-to-rgb-and-rgb-to-hsv/)。任何人都有一个更好的代码,将RGB转换为HSV,反之亦然

感谢

8 个答案:

答案 0 :(得分:13)

您是否尝试使用colorsys库?

  

colorsys模块定义   双向颜色转换   颜色之间的颜色值   使用RGB(红绿蓝)颜色空间   在电脑显示器和其他三个   坐标系:YIQ,HLS(Hue   亮度饱和度)和HSV(色调   饱和度值)

示例(取自上面的链接):

>>> 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)

答案 1 :(得分:1)

你输入了R,G和B的哪些值,以及你看出错误的H,S和V的值是什么?

您链接的代码(如colorsys)要求浮点值介于0.0和1.0之间。如果你用0到255范围内的整数值来调用它,你会得到虚假的结果。如果你给它预期的输入值,它应该可以正常工作。

(该代码示例明显失败,它实际上没有记录它所期望的那种输入。)

答案 2 :(得分:0)

如果使用PIL,最近的Pillow副本,应该使用

def rgb2hsv(image):
    return image.convert('HSV')

答案 3 :(得分:0)

我建议使用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)

答案 4 :(得分:0)

基于numpy中的数组索引和切片,这是我的前进方法:

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

和向后色彩空间转换:

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

我之所以写这些行,是因为由于计算量过大,我不相信逐像素转换,而且我也不希望依赖其他库,例如OpenCV。

请随意提出修改意见,以使该解决方案更优雅,更通用。

答案 5 :(得分:0)

如果您需要转换保存为 numpy 的图像,您应该使用:

  1. opencv 见 answer by George Pipis
  2. skimage
from skimage.color import rgb2hsv
hsv_img = rgb2hsv(rgb_img)

答案 6 :(得分:0)

1.) 这是一个完整的脚本。它将 RGB(40, 32, 28) 转换为 HSV(20, 30, 26)

2.) 用法。

运行这个脚本,特别是函数 convert_rgb_to_hsv()

您可以编辑变量 red、green、blue。

import colorsys

#usage.
#run this script, in particular the function convert_rgb_to_hsv()
#edit red, green, blue



def convert_rgb_to_hsv():
    #rgb normal: range (0-255, 0-255, 0.255)
    red=40
    green=32
    blue=28

    
    
    #get rgb percentage: range (0-1, 0-1, 0-1 )
    red_percentage= red / float(255)
    green_percentage= green/ float(255)
    blue_percentage=blue / float(255)

    
    #get hsv percentage: range (0-1, 0-1, 0-1)
    color_hsv_percentage=colorsys.rgb_to_hsv(red_percentage, green_percentage, blue_percentage) 
    print('color_hsv_percentage: ', color_hsv_percentage)

    
    
    #get normal hsv: range (0-360, 0-255, 0-255)
    color_h=round(360*color_hsv_percentage[0])
    color_s=round(255*color_hsv_percentage[1])
    color_v=round(255*color_hsv_percentage[2])
    color_hsv=(color_h, color_s, color_h)

    print('color_hsv: ', color_hsv)



#INVOCATE MAIN FUNCTION
convert_rgb_to_hsv()

答案 7 :(得分:-2)

我研究了来自opencv,colorsys和PIL的各种库。

colorsys不太准确,但在15度以内。大部分时间在3度以内。 也许其他人似乎在几个程度上有较小的依赖性,但是谁更正确?我不知道。但是这是我的numpyfied rgb到hsv代码。我认为它相当不错,但是我相信可以通过某种方式更好地对其进行优化。最明显的是将H,s和v组合在一起。我的无疑比colorsys更准确,但是您肯定会看到一些小的舍入错误。但是,嘿,至少要分几个步骤完成整个阵列。对不起,没有反转码。也许有一天我会写它。好吧,最后一件事是我不假设规模。您必须为单独的色相,饱和度和色度添加自己的缩放比例。可选的s参数是输入比例缩放为1,dhue,dsat和dval超出比例缩放。是的,这是用于2dim阵列。修复它可以在一段时间内工作不难,或者只是将您的内容重塑为2dim然后再返回。

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))