简体   繁体   English

hsv_to_rgb不是matplotlib上rgb_to_hsv的反转

[英]hsv_to_rgb isn't the inverse of rgb_to_hsv on matplotlib

I tried to convert an image to hsv and back to rgb, but somehow I lost color information. 我试图将图像转换为hsv并返回到rgb,但不知怎的,我丢失了颜色信息。

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

And I also replicated the problem on shell too, just writing this line after importing also gives the same result. 而且我也在shell上复制了这个问题,只是在导入后写这行也会得到相同的结果。

plt.imshow(
  matplotlib.colors.hsv_to_rgb(
    matplotlib.colors.rgb_to_hsv(mpimg.imread('go2.jpg'))
  )
)

Can you tell me what am I doing wrong? 你能告诉我我做错了什么吗?

edit: this is only a partial solution, 编辑:这只是部分解决方案,

see discussion at https://github.com/matplotlib/matplotlib/pull/2569 请参阅https://github.com/matplotlib/matplotlib/pull/2569上的讨论

This is an integer division issue. 这是一个整数除法问题。 numpy is serious about it's types and seems to not respect from __future__ import division . numpy认真对待它的类型,似乎不尊重from __future__ import division The simple work around is to convert your rgb values to floats before calling rgb_to_hsv or patch the function as such: 简单的解决方法是在调用rgb_to_hsv之前将rgb值转换为浮点数或者将函数修改为:

def rgb_to_hsv(arr):
    """
    convert rgb values in a numpy array to hsv values
    input and output arrays should have shape (M,N,3)
    """
    arr = arr.astype('float')  # <- add this line
    out = np.zeros(arr.shape, dtype=np.float)
    arr_max = arr.max(-1)
    ipos = arr_max > 0
    delta = arr.ptp(-1)
    s = np.zeros_like(delta)
    s[ipos] = delta[ipos] / arr_max[ipos]
    ipos = delta > 0
    # red is max
    idx = (arr[:, :, 0] == arr_max) & ipos
    out[idx, 0] = (arr[idx, 1] - arr[idx, 2]) / delta[idx]
    # green is max
    idx = (arr[:, :, 1] == arr_max) & ipos
    out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0]) / delta[idx]
    # blue is max
    idx = (arr[:, :, 2] == arr_max) & ipos
    out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1]) / delta[idx]
    out[:, :, 0] = (out[:, :, 0] / 6.0) % 1.0
    out[:, :, 1] = s
    out[:, :, 2] = arr_max
    return out

This problem is reproducible for me (matplotlib 1.3.0). 这个问题对我来说是可重现的(matplotlib 1.3.0)。 It looks like a bug to me. 对我来说这看起来像个错误。 The issue seems to be that in the rgb_to_hsv step, the saturation is being dropped to zero. 问题似乎是在rgb_to_hsv步骤中,饱和度降至零。 At least for most colours: 至少对于大多数颜色:

import numpy as np
darkgreen = np.array([[[0, 100, 0]]], dtype='uint8')
matplotlib.colors.rgb_to_hsv(darkgreen)                  # [0.33, 1., 100.], okay so far
darkgreen2 = np.array([[[10, 100, 10]]], dtype='uint8')  # very similar colour
matplotlib.colors.rgb_to_hsv(darkgreen2)                 # [0.33, 0., 100.], S=0 means this is a shade of gray

I think the correct place to report bugs is on the github issue tracker . 我认为报告错误的正确位置是在github 问题跟踪器上

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

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