使用scikit-image进行HSV颜色旋转

3 投票
1 回答
4828 浏览
提问于 2025-04-17 22:57

这个过程的目的是把一张纯红色的图片转换成色轮上的任何颜色。

  • 首先,把一张单色图片转换成RGB红色图片,比如说:
  • original monochrome image
  • 然后把这个红色图片转换成HSV格式。
  • 接着,修改色调部分,添加一个角度值,这个值应该对应色轮上的颜色。
  • 最后,把HSV格式的图片再转换回RGB颜色空间。

问题是,最终得到的图片只能是绿色或蓝色(比如说,当角度大约是30°时,得不到黄色):

Hue rotation

在一些ipython单元格中执行的代码依赖于scikit-image 0.10dev:

from skimage import io
from skimage import color
from scipy import ndimage as nd
import numpy as np
from matplotlib import pyplot as plt
import os
cy55 = io.imread('/home/jeanpat/MFISH/PSI/P07/01/Cy5/P070109C.tif')

zero = np.zeros(cy55.shape,dtype=np.uint8)
rgb0 = np.dstack([cy55, zero,zero])

hue_rotations = [18, 36,72,90,108]
images = {}
images[0] = rgb0
hsv0 = color.rgb2hsv(rgb0)
print hsv0[:,:,0].dtype
for hue in hue_rotations:
    hsv = np.copy(hsv0)
    hsv[:,:,0] = hsv[:,:,0]+ hue
    rgb = color.hsv2rgb(hsv)
    images[hue] = rgb
i = 1
plt.figure(num=None, figsize=(15, 5),  facecolor='w', edgecolor='k')
for hue in np.sort(images.keys()):
    plt.subplot(1,6,i,xticks=[],yticks=[])
    plt.title('hue='+str(hue))
    plt.imshow(images[hue])
    i = i +1
plt.show()

1 个回答

8

我在邮件列表上回答过这个问题,但我把解决方案复制到这里,这样更容易找到(而且格式看起来更好)。

基本上,色调的表示方式有一些不同,比如范围是0到1,而不是0到180,还有数据类型的差异,比如uint8和float,可能在将灰度图像转换为RGB时也会有一些问题。下面是一个简单的使用示例:

import numpy as np
import matplotlib.pyplot as plt
from skimage import color
from skimage import data


def colorize(image, hue):
    """Return image tinted by the given hue based on a grayscale image."""
    hsv = color.rgb2hsv(color.gray2rgb(image))
    hsv[:, :, 0] = hue
    hsv[:, :, 1] = 1  # Turn up the saturation; we want the color to pop!
    return color.hsv2rgb(hsv)


image = data.camera()[::2, ::2]

hue_rotations = np.linspace(0, 1, 6)  # 0--1 is equivalent to 0--180
colorful_images = [colorize(image, hue) for hue in hue_rotations]

fig, axes = plt.subplots(nrows=2, ncols=3)

for ax, array in zip(axes.flat, colorful_images):
    ax.imshow(array, vmin=0, vmax=1)
    ax.set_axis_off()

plt.show()

这样就会得到:

上色的灰度图像

撰写回答