繁体   English   中英

RGB到HSV Python,不断改变Hue

[英]RGB to HSV Python, change Hue continuously

我要做的是:不断更改图像的Hue值,从0到360,为每个Hue保存一个图像。

我是怎么尝试的:我开始使用在此链接上找到的代码,然后修改它以更改Hue并保存图像。

问题是:上面链接中的代码显然没有将图像保存为真正的HSV,因为当它合并图像时,它使用图像模式RGB 但我找不到让它成为HSV的方法。

def hueChange(img, hue):
    if isinstance(img, Image.Image):
        img.load()
        r, g, b = img.split()
        h_data = []
        s_data = []
        v_data = []

        for rd, gr, bl in zip(r.getdata(), g.getdata(), b.getdata()):
            h, s, v = colorsys.rgb_to_hsv(rd / 255., bl / 255., gr / 255.) 
            h_data.append(int(hue))
            s_data.append(int(s * 255.))
            v_data.append(int(v * 255.))

        r.putdata(h_data)
        g.putdata(s_data)
        b.putdata(v_data)
        return toRGB(Image.merge('RGB',(r,g,b)))
    else:
        return None

# Don't care about the range indices, they are just for testing 
for hue in range(1, 255, 30):
    in_name = '/Users/cgois/Dropbox/Python/fred/fred' + str(hue) + '.jpg'
    img = Image.open(in_name)
    img = hueChange(img, hue)

    out_name = '/Users/cgois/Dropbox/Python/fred/hue/fred_hue' + str(hue) + '.png'
    img.save(out_name)

我尝试的最后一个解决方案如上所述进行转换,然后使用与hueChange(...)类似的代码将其转换回RGB。 然而,效果只是输出图像在它们之上具有*(单个)*颜色叠加。

有任何想法吗? 感谢您的时间 (:

使用colorsys.hsv_to_rgb将(H,S,V)元组转换回RGB:

import os
import colorsys
import Image

def hueChange(img, hue):
    # It's better to raise an exception than silently return None if img is not
    # an Image.
    img.load()
    r, g, b = img.split()
    r_data = []
    g_data = []
    b_data = []

    for rd, gr, bl in zip(r.getdata(), g.getdata(), b.getdata()):
        h, s, v = colorsys.rgb_to_hsv(rd / 255., bl / 255., gr / 255.) 
        rgb = colorsys.hsv_to_rgb(hue/360., s, v)
        rd, gr, bl = [int(x*255.) for x in rgb]
        r_data.append(rd)
        g_data.append(gr)
        b_data.append(bl)

    r.putdata(r_data)
    g.putdata(g_data)
    b.putdata(b_data)
    return Image.merge('RGB',(r,g,b))

filename = 'image.png'
basename, ext = os.path.splitext(filename)
img = Image.open(filename).convert('RGB')
for hue in range(1, 360, 30):
    img2 = hueChange(img, hue)
    out_name = '{}_hue{:03d}.jpg'.format(basename, hue)
    img2.save(out_name)

对于大图像,逐个像素地改变值可能非常慢。 为了获得更好的性能,请使用NumPy。 (NumPy函数取自此处 ):

import os
import Image
import numpy as np

def rgb_to_hsv(rgb):
    # Translated from source of colorsys.rgb_to_hsv
    # r,g,b should be a numpy arrays with values between 0 and 255
    # rgb_to_hsv returns an array of floats between 0.0 and 1.0.
    rgb = rgb.astype('float')
    hsv = np.zeros_like(rgb)
    # in case an RGBA array was passed, just copy the A channel
    hsv[..., 3:] = rgb[..., 3:]
    r, g, b = rgb[..., 0], rgb[..., 1], rgb[..., 2]
    maxc = np.max(rgb[..., :3], axis=-1)
    minc = np.min(rgb[..., :3], axis=-1)
    hsv[..., 2] = maxc
    mask = maxc != minc
    hsv[mask, 1] = (maxc - minc)[mask] / maxc[mask]
    rc = np.zeros_like(r)
    gc = np.zeros_like(g)
    bc = np.zeros_like(b)
    rc[mask] = (maxc - r)[mask] / (maxc - minc)[mask]
    gc[mask] = (maxc - g)[mask] / (maxc - minc)[mask]
    bc[mask] = (maxc - b)[mask] / (maxc - minc)[mask]
    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
    return hsv

def hsv_to_rgb(hsv):
    # Translated from source of colorsys.hsv_to_rgb
    # h,s should be a numpy arrays with values between 0.0 and 1.0
    # v should be a numpy array with values between 0.0 and 255.0
    # hsv_to_rgb returns an array of uints between 0 and 255.
    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.astype('uint8')

def hueChange(img, hue):
    arr = np.array(img)
    hsv = rgb_to_hsv(arr)
    hsv[..., 0] = hue
    rgb = hsv_to_rgb(hsv)
    return Image.fromarray(rgb, 'RGB')

filename = 'image.png'
basename, ext = os.path.splitext(filename)
img = Image.open(filename).convert('RGB')
for hue in np.linspace(0, 360, 8):
    img2 = hueChange(img, hue/360.)
    out_name = '{}_hue{:03d}.jpg'.format(basename, int(hue))
    img2.save(out_name)

根据此页面 ,当未选中Photoshop“着色”框时,每个像素的色调移动相同的量。 选中“着色”框时,每个像素的色调设置为相同的量。

因此,要将色调移动固定量,请使用:

def hueShift(img, amount):
    arr = np.array(img)
    hsv = rgb_to_hsv(arr)
    hsv[..., 0] = (hsv[..., 0]+amount) % 1.0
    rgb = hsv_to_rgb(hsv)
    return Image.fromarray(rgb, 'RGB')

filename = 'without_colorize.jpg'
basename, ext = os.path.splitext(filename)
img = Image.open(filename).convert('RGB')
for amount in (50, 133):
    img2 = hueShift(img, amount/360.)
    out_name = '{}_hue{:+03d}.jpg'.format(basename, int(amount))
    img2.save(out_name)

without_colorize.jpg:

在此输入图像描述

色调+ 50:

在此输入图像描述

色调+ 133:

在此输入图像描述

注意:当移动色调时,头发和脸部的某些区域变成了不同的颜色,具有明显的,不自然的边界。 看起来我的代码并没有忠实地再现Photoshop正在做的事情......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM