python - 将 RGB 数组转换为 HSL

标签 python numpy rgb hsl

首先声明一下,我对Python不太熟练,你们让我很钦佩。

我的问题: 我需要从模板(128px x 128px)生成 10k+ 具有各种色调和亮度的图像。

我加载图像并将它们转换为数组

image = Image.open(dir + "/" + file).convert('RGBA')
arr=np.array(np.asarray(image).astype('float'))

据我所知,以这种方式处理 numpy 数组比循环每个像素并使用 colorsys 快得多。

现在,我偶然发现了几个将 RGB 转换为 HSV 的函数。 这帮助我生成了具有不同色调的图像,但我还需要调整亮度,以便有些可以是黑色,有些可以是白色。

def rgb_to_hsv(rgb):
    # Translated from source of colorsys.rgb_to_hsv
    hsv=np.empty_like(rgb)
    hsv[...,3:]=rgb[...,3:]
    r,g,b=rgb[...,0],rgb[...,1],rgb[...,2]
    maxc = np.max(rgb[...,:2],axis=-1)
    minc = np.min(rgb[...,:2],axis=-1)    
    hsv[...,2] = maxc   
    hsv[...,1] = (maxc-minc) / maxc
    rc = (maxc-r) / (maxc-minc)
    gc = (maxc-g) / (maxc-minc)
    bc = (maxc-b) / (maxc-minc)
    hsv[...,0] = np.select([r==maxc,g==maxc],[bc-gc,2.0+rc-bc],default=4.0+gc-rc)
    hsv[...,0] = (hsv[...,0]/6.0) % 1.0
    idx=(minc == maxc)
    hsv[...,0][idx]=0.0
    hsv[...,1][idx]=0.0
    return hsv

def hsv_to_rgb(hsv):
    # Translated from source of colorsys.hsv_to_rgb
    rgb=np.empty_like(hsv)
    rgb[...,3:]=hsv[...,3:]    
    h,s,v=hsv[...,0],hsv[...,1],hsv[...,2]   
    i = (h*6.0).astype('uint8')
    f = (h*6.0) - i
    p = v*(1.0 - s)
    q = v*(1.0 - s*f)
    t = v*(1.0 - s*(1.0-f))
    i = i%6
    conditions=[s==0.0,i==1,i==2,i==3,i==4,i==5]
    rgb[...,0]=np.select(conditions,[v,q,p,p,t,v],default=v)
    rgb[...,1]=np.select(conditions,[v,v,v,q,p,p],default=t)
    rgb[...,2]=np.select(conditions,[v,p,t,v,v,q],default=p) 
    return rgb

修改这些函数以与 HSL 相互转换有多容易? 有什么技巧可以将 HSV 转换为 HSL 吗?

非常感谢您能给我的任何信息,谢谢!

最佳答案

是的,numpy,即矢量化代码,可以加速颜色转换。

此外,对于 10k+ 位图的大规模生产,如果它与您首选的亮度模型不完全匹配,您可能需要重新使用现成的专业转换或对其进行子类化。

计算机视觉库 OpenCV 目前可作为 Python 的 cv2 模块使用,无需任何额外编码即可处理颜色系统转换:

现成的转换单行代码

out = cv2.cvtColor(   anInputFRAME, cv2.COLOR_YUV2BGR ) # a bitmap conversion

cv2 中可用的一些颜色系统的列表(您可能会注意到 RGB 被称为 BRG 由于 OpenCV 约定图像的 Blue-Red-Green 颜色顺序不同-飞机),

(对称性适用于 COLOR_YCR_CB2BGR <-|-> COLOR_BGR2YCR_CB 并非所有显示的对)

>>> import cv2
>>> for key in dir( cv2 ):                              # show all ready conversions
...     if key[:7] == 'COLOR_Y':
...         print key

COLOR_YCR_CB2BGR
COLOR_YCR_CB2RGB
COLOR_YUV2BGR
COLOR_YUV2BGRA_I420
COLOR_YUV2BGRA_IYUV
COLOR_YUV2BGRA_NV12
COLOR_YUV2BGRA_NV21
COLOR_YUV2BGRA_UYNV
COLOR_YUV2BGRA_UYVY
COLOR_YUV2BGRA_Y422
COLOR_YUV2BGRA_YUNV
COLOR_YUV2BGRA_YUY2
COLOR_YUV2BGRA_YUYV
COLOR_YUV2BGRA_YV12
COLOR_YUV2BGRA_YVYU
COLOR_YUV2BGR_I420
COLOR_YUV2BGR_IYUV
COLOR_YUV2BGR_NV12
COLOR_YUV2BGR_NV21
COLOR_YUV2BGR_UYNV
COLOR_YUV2BGR_UYVY
COLOR_YUV2BGR_Y422
COLOR_YUV2BGR_YUNV
COLOR_YUV2BGR_YUY2
COLOR_YUV2BGR_YUYV
COLOR_YUV2BGR_YV12
COLOR_YUV2BGR_YVYU
COLOR_YUV2GRAY_420
COLOR_YUV2GRAY_I420
COLOR_YUV2GRAY_IYUV
COLOR_YUV2GRAY_NV12
COLOR_YUV2GRAY_NV21
COLOR_YUV2GRAY_UYNV
COLOR_YUV2GRAY_UYVY
COLOR_YUV2GRAY_Y422
COLOR_YUV2GRAY_YUNV
COLOR_YUV2GRAY_YUY2
COLOR_YUV2GRAY_YUYV
COLOR_YUV2GRAY_YV12
COLOR_YUV2GRAY_YVYU
COLOR_YUV2RGB
COLOR_YUV2RGBA_I420
COLOR_YUV2RGBA_IYUV
COLOR_YUV2RGBA_NV12
COLOR_YUV2RGBA_NV21
COLOR_YUV2RGBA_UYNV
COLOR_YUV2RGBA_UYVY
COLOR_YUV2RGBA_Y422
COLOR_YUV2RGBA_YUNV
COLOR_YUV2RGBA_YUY2
COLOR_YUV2RGBA_YUYV
COLOR_YUV2RGBA_YV12
COLOR_YUV2RGBA_YVYU
COLOR_YUV2RGB_I420
COLOR_YUV2RGB_IYUV
COLOR_YUV2RGB_NV12
COLOR_YUV2RGB_NV21
COLOR_YUV2RGB_UYNV
COLOR_YUV2RGB_UYVY
COLOR_YUV2RGB_Y422
COLOR_YUV2RGB_YUNV
COLOR_YUV2RGB_YUY2
COLOR_YUV2RGB_YUYV
COLOR_YUV2RGB_YV12
COLOR_YUV2RGB_YVYU
COLOR_YUV420P2BGR
COLOR_YUV420P2BGRA
COLOR_YUV420P2GRAY
COLOR_YUV420P2RGB
COLOR_YUV420P2RGBA
COLOR_YUV420SP2BGR
COLOR_YUV420SP2BGRA
COLOR_YUV420SP2GRAY
COLOR_YUV420SP2RGB
COLOR_YUV420SP2RGBA

我为亮度转换做了一些原型(prototype)设计(基于 >>> http://en.wikipedia.org/wiki/HSL_and_HSV )

但尚未测试发布。

def        get_YUV_V_Cr_Rec601_BRG_frame( brgFRAME ):                   # For the Rec. 601 primaries used in gamma-corrected sRGB, fast, VECTORISED MUL/ADD CODE
    out =  numpy.zeros( brgFRAME.shape[0:2] )
    out += 0.615 / 255 * brgFRAME[:,:,1]    # // Red                    # normalise to <0.0 - 1.0> before vectorised MUL/ADD, saves [usec] ... on 480x640 [px] faster goes about 2.2 [msec] instead of 5.4 [msec]
    out -= 0.515 / 255 * brgFRAME[:,:,2]    # // Green
    out -= 0.100 / 255 * brgFRAME[:,:,0]    # // Blue                   # normalise to <0.0 - 1.0> before vectorised MUL/ADD
    return out

关于python - 将 RGB 数组转换为 HSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26292114/

相关文章:

python - QtableView单元格在窗体关闭时失去焦点时如何保存正在编辑的数据

python - numpy.genfromtxt- ValueError- Line #(得到 n 列而不是 m)

java - 随机 HSV 颜色

opengl - 使用 GLSL 将 RGB 转换为 YUV

java - 可以在 Java 中绘制 YCbCr 吗?

Python 检查 fork() 进程是否完成

python - 用其前后值之间的线性插值替换 numpy 数组中的零

python - 具有 3 个变量的 numpy 直方图

python - 多维度的 NumPy PolyFit 和 PolyVal?

大型数组的 numpy.mean 精度