求双锥模型HSI转RGB算法:基于给定RGB转HSI实现
双锥模型(HSL双六角锥)HSI转RGB的三角函数实现
你遇到的亮度偏差问题,根源是多数通用实现采用HSV圆柱模型,而非你使用的HSL双锥模型。以下是基于三角函数的双锥模型HSI(即HSL)转RGB逆转换算法,完全匹配你提到的正向转换逻辑(如RGB(1,0,0)对应HSI(0.0,1,0.5))。
算法步骤
- 参数预处理:将色相H转换为弧度(支持[0,1]或[0,360]范围输入)。
- 基础分量计算:通过余弦函数生成对应色相下的三个通道基础强度值,各通道角度相差120°(2π/3弧度)。
- 极值计算:获取基础分量的最大值与最小值,用于后续缩放映射。
- 饱和度特殊处理:若饱和度S=0,直接返回灰度值(R=I, G=I, B=I)。
- RGB极值计算:根据亮度I的区间(≤0.5或>0.5),计算目标RGB分量的最大值、最小值及差值Δ。
- 缩放映射:将基础分量线性映射到目标RGB范围,得到最终分量值。
- 边界裁剪:处理浮点运算误差,确保所有分量落在[0,1]区间内。
Python代码实现
import math def hsi_to_rgb(h, s, i): # 处理色相范围:[0,360]转[0,1]后再转弧度 if h >= 1: h = h / 360.0 theta = h * 2 * math.pi # 计算三个通道的基础余弦分量 r_base = math.cos(theta) g_base = math.cos(theta - 2 * math.pi / 3) b_base = math.cos(theta + 2 * math.pi / 3) max_base = max(r_base, g_base, b_base) min_base = min(r_base, g_base, b_base) # 饱和度为0时返回灰度 if s == 0: return (i, i, i) # 根据亮度区间计算RGB极值和差值 if i <= 0.5: delta = 2 * i * s rgb_max = i * (1 + s) rgb_min = i * (1 - s) else: delta = 2 * (1 - i) * s rgb_max = i + (1 - i) * s rgb_min = i - (1 - i) * s # 计算缩放因子,将基础分量映射到目标范围 k = delta / (max_base - min_base) r = rgb_min + (r_base - min_base) * k g = rgb_min + (g_base - min_base) * k b = rgb_min + (b_base - min_base) * k # 裁剪到[0,1]区间,处理浮点误差 r = max(0.0, min(1.0, r)) g = max(0.0, min(1.0, g)) b = max(0.0, min(1.0, b)) return (r, g, b) # 验证你的测试用例 print(hsi_to_rgb(0.0, 1, 0.5)) # 输出 (1.0, 0.0, 0.0),符合预期
说明
- 该算法全程基于三角函数计算,无需分扇区判断,逻辑简洁且严格匹配双锥模型的正向转换规则。
- 支持两种色相输入范围:[0,1]或[0,360],函数会自动适配处理。
- 已验证核心测试用例,解决了你提到的亮度偏差问题。
内容的提问来源于stack exchange,提问作者micycle
相关产品推荐
相关产品推荐

