【问题标题】:Why is my HSI color wheel weird looking?为什么我的 HSI 色轮看起来很奇怪?
【发布时间】:2026-01-19 12:05:01
【问题描述】:

我正在尝试在 HSI 色彩空间中绘制一个色轮。我得到的色轮有非常宽的青色、黄色和洋红色,看起来很不对劲。我见过的所有其他色轮都有带最宽的红色、绿色和蓝色。

这就是恒指色轮的外观吗?还是我的数学错了?我已经尝试了所有我能找到的 HSI 到 RGB 的 sn-p,并在书中查找了这个等式。这个方程有很多变化,但是当我画我的圆圈时,它们都会导致相同的结果。我唯一不同的是在最后夹紧通道。我的 Intensity 到处都是 1.0,Hue 是像素的角度(旋转一点),Saturation 是到中心距离的大小。

这是我将 HSI 转换为 RGB(Objective-C)的杂乱代码:

float r;
float g;
float b;

S = S > 1.0f ? 1.0f : S;
I = I > 1.0f ? 1.0f : I;
H = H > 1.0f ? H - 1.0 : H;
H = H * M_PI * 2.0;
H = fmod(H, M_PI * 2.0);

if(S==0.0f){
    r = I;
    g = I;
    b = I;
} else{
    if((H>=0.0) && (H<2.0*M_PI/3.0)){

        b = (1.0f-S)/3.0f;
        r = (1.0f + S*cosf(H) / cosf(M_PI/3.0-H))/3.0f;          
        g = 1.0f-r-b;

    } else if((H>=2.0*M_PI/3.0) && (H<4.0*M_PI/3.0)){
        H = H - 2.0f*M_PI/3.0f;
        r = (1.0f-S)/3.0f;
        g = (1.0f+S*cosf(H)/cosf(M_PI/3.0 - H))/3.0f;

        b = 1.0f-r-g;
    } else if ((H>=4.0*M_PI/3.0) && (H<2.0*M_PI)){
        H= H-4.0f*M_PI/3.0f;
        g = (1.0f-S)/3.0f;
        b = (1.0f+S*cosf(H)/cosf(M_PI/3.0-H))/3.0f;

        r = 1.0f-b-g;
    } 
}
if(r<0.0f)
    r=0.0f;
if(g<0.0f)
    g=0.0f;
if(b<0.0f)
    b=0.0f;
float R = 3.0f*I*r;
float G = 3.0f*I*g;
float B = 3.0f*I*b;

if(R>1.0f)
    R=1.0f;
if(G>1.0f)
    G=1.0f;
if(B>1.0f)
    B=1.0f;

【问题讨论】:

  • 你试过降低强度吗?我猜在强度最大的情况下,原色最大并被剪裁为 1。因此混合色主导了*。
  • @user3386109 关于当 I=1 时原色被洗掉的说法是正确的。 RGB 颜色 (1,0,0),这是您可以得到的最红的颜色,只能映射到 I=1/3。您可以改用 HSV 或 HSL 吗?这些色彩空间可能会带来更直观的用户界面。
  • 顺便说一下,通过快速查看您的代码,我没有发现任何问题。我认为最重要的问题不是 I = 1.0 的所有 H 和 S 值都映射到有效的 (R, G, B) 三元组。我认为这就是函数末尾剪辑代码的原因。

标签: c color-space color-wheel


【解决方案1】:

阅读 cmets 后,很明显,限制 RGB 值会导致 CMY 偏差。降低强度消除了偏差,但仍然存在奇怪的条带问题,并且色轮看起来仍然不像其他人的色轮。考虑到数学,这个结果是有道理的,但出于某种原因,没有人在任何关于 HSI 的书籍或在线信息中的任何地方提到这些问题。人们展示的 HSI 色轮看起来像 HSV/B 色轮,但我仍然不知道他们在转换为 RGB 时是如何得到这个结果的。

解决方案:我改用 HSV 色彩空间,结果证明它比 HSI 更符合我的要求。

【讨论】: