从RGB获得Hue的最快公式

use*_*533 23 rgb colors

如果给出的红色,绿色和蓝色值范围为0-255,那么获得色调值的最快计算是什么?该公式将以30fps(每秒920万次)用于640x480图像的每个像素,因此每一点速度优化都有帮助.

我见过其他公式,但我不满意他们涉及多少步骤.我正在寻找一个实际的公式,而不是内置的库函数.

Umr*_*aev 29

  1. 将RGB值转换为0-1范围,这可以通过将值除以255得到8位颜色深度(r,g,b - 给定值):

    R = r / 255 = 0.09
    G = g / 255 = 0.38
    B = b / 255 = 0.46

  2. 找出R,G和B的最小值和最大值.

  3. 取决于RGB颜色通道的最大值.三种不同的公式是: If Red is max, then Hue = (G-B)/(max-min) If Green is max, then Hue = 2.0 + (B-R)/(max-min) If Blue is max, then Hue = 4.0 + (R-G)/(max-min)

您获得的Hue值需要乘以60才能将其转换为色环上的度数.如果Hue变为负值,则需要添加360,因为圆圈具有360度.

这是完整的文章.

  • @Sphynx请注意,“x - y”可以是正数或负数,因此“(x - y) / (max - min)”的范围是从-1到1,而不是从0到1。 (3认同)
  • 如果您只想将这些值相除,为什么需要将它们转换为 0 到 1 之间的值?直接除以差异就可以得到色相 (2认同)

Zar*_*kka 19

除了Umriyaev的回答:

如果仅需要色调,则不需要将0-255范围的颜色除以255.

ex的结果(green - blue) / (max - min)对于任何范围都是相同的(只要颜色在相同的范围内).

以下是获取Hue的java示例:

public int getHue(int red, int green, int blue) {

    float min = Math.min(Math.min(red, green), blue);
    float max = Math.max(Math.max(red, green), blue);

    if (min == max) {
        return 0;
    }

    float hue = 0f;
    if (max == red) {
        hue = (green - blue) / (max - min);

    } else if (max == green) {
        hue = 2f + (blue - red) / (max - min);

    } else {
        hue = 4f + (red - green) / (max - min);
    }

    hue = hue * 60;
    if (hue < 0) hue = hue + 360;

    return Math.round(hue);
}
Run Code Online (Sandbox Code Playgroud)

编辑:添加检查min和max是否相同,因为在这种情况下不需要计算的其余部分,并且避免除以0(参见注释)

编辑:修复java错误


小智 6

可能不是最快的,但这是一个 JavaScript 函数,您可以通过单击下面的“运行代码片段”按钮直接在浏览器中尝试

function rgbToHue(r, g, b) {
    // convert rgb values to the range of 0-1
    var h;
    r /= 255, g /= 255, b /= 255;

    // find min and max values out of r,g,b components
    var max = Math.max(r, g, b), min = Math.min(r, g, b);

    // all greyscale colors have hue of 0deg
    if(max-min == 0){
        return 0;
    }

    if(max == r){
        // if red is the predominent color
        h = (g-b)/(max-min);
    }
    else if(max == g){
        // if green is the predominent color
        h = 2 +(b-r)/(max-min);
    }
    else if(max == b){
        // if blue is the predominent color
        h = 4 + (r-g)/(max-min);
    }

    h = h*60; // find the sector of 60 degrees to which the color belongs
    // https://www.pathofexile.com/forum/view-thread/1246208/page/45 - hsl color wheel

    // make sure h is a positive angle on the color wheel between 0 and 360
    h %= 360;
    if(h < 0){
        h += 360;
    }

    return Math.round(h);
}

let gethue = document.getElementById('gethue');
let r = document.getElementById('r');
let g = document.getElementById('g');
let b = document.getElementById('b');

r.value = Math.floor(Math.random() * 256);
g.value = Math.floor(Math.random() * 256);
b.value = Math.floor(Math.random() * 256);

gethue.addEventListener('click', function(event) {
  let R = parseInt(r.value)
  let G = parseInt(g.value)
  let B = parseInt(b.value)
  let hue = rgbToHue(R, G, B)
  console.log(`Hue(${R}, ${G}, ${B}) = ${hue}`);
});
Run Code Online (Sandbox Code Playgroud)
<table>
  <tr><td>R = </td><td><input id="r"></td></tr>
  <tr><td>G = </td><td><input id="g"></td></tr>
  <tr><td>B = </td><td><input id="b"></td></tr>
  <tr><td colspan="2"><input id="gethue" type="button" value="Get Hue"></td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)