如果给出的红色,绿色和蓝色值范围为0-255,那么获得色调值的最快计算是什么?该公式将以30fps(每秒920万次)的速度用于640x480图像的每个像素,因此速度优化的每一点都有帮助。
我见过其他公式,但我不满意他们涉及多少步骤。我正在寻找一个实际的公式,而不是内置的库函数。
答案 0 :(得分:26)
将RGB值转换为0-1范围,这可以通过将值除以255得到8位颜色深度(r,g,b - 给定值):
{ {2}}
查找R,G和B的最小值和最大值。
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度。
这是full article。
答案 1 :(得分:17)
除了Umriyaev的回答:
如果只需要色调,则不需要将0-255范围的颜色除以255.
e.x的结果。 (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);
}
编辑:添加检查min和max是否相同,因为在这种情况下不需要其余的计算,并且避免除以0(参见注释)
编辑:修复java错误
答案 2 :(得分:2)
// 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);
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
if(h > 0){
// h is a positive angle in the color wheel
return Math.floor(h);
}
else{
// h is a negative angle.
return Math.floor(360 -h);
}
答案 3 :(得分:0)
您必须指定所需的语言。 C#,Java和C是非常不同的语言,可以在不同的平台上运行
与当前常见分辨率相比,640x480并不是很大。您必须尝试所有可能的解决方案和基准。具有多个步骤的算法并不一定比较短的算法慢,因为指令周期不固定,并且还有许多其他因素会影响性能,例如缓存一致性。对于上面提到的算法Umriyaev,你可以用1.0/255
乘以乘以255的除法,这样可以提高性能并带来一点可接受的错误。
在C中你可以对其进行矢量化以进一步改进它。您也可以使用硬件加速。
在C#和Java中,你没有多少选择。您可以在C#中运行不安全的代码,或者如果您使用Mono,则可以使用已经支持SSE的矢量类型。在Java中,您可以通过JNI
运行本机代码答案 4 :(得分:0)
网页Math behind colorspace conversions, RGB-HSL对此进行了介绍,但其中包含我认为是错误的内容。它说明了色相计算要除以max-min,但是如果将其除以该分数,则该值会增加并且很容易超过-1到5的整个预期范围。我发现,将max-min乘以预期即可工作。
代替此:
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)
我建议这样做:
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)