首先,代码有效,但是我想了解它的工作原理(每一行)。
这是我的插值代码:
void colortemp(float temp, FILE* tempfile)
{
//float temp_min = -138.0;
//float temp_max = -37.0;
//float color_min = 240.0;
//float color_max = 0;
if(temp < 135.0f)
{
temp = 135.0f;
}
/*
if(temp > 310.0f)
{
temp = 310.0f;
}*/
float a = ( 0.0f - 240.0f) / ( 310.0f - 135.0f);
float b = 240.0f - (a * 135.0f);
float h = (temp * a ) + b;
float S = 1.0f, V = 1.0f; //HSV
float P, Q, T, fract;
unsigned char pix[3];
(h == 360.0f)?(h = 0.0f):(h /= 60.0f); --> WHY DIVIDE BY 60, NO MODULO ?
fract = h - floor(h);
P = (V*(1. - S))*255;
Q = (V*(1. - S*fract))*255;
T = (V*(1. - S*(1. - fract)))*255;
V*=255;
S*=255;
if (0. <= h && h < 1.) //WHY WE USE BETWEEN TWO VALUES AND NOT EQUALS TO 1 FOR EXAMPLE
{
pix[0] = (int)V;
pix[1] = (int)T;
pix[2] = (int)P;
}
else if (1. <= h && h < 2.)
{
pix[0] = (int)Q;
pix[1] = (int)V;
pix[2] = (int)P;
}
else if (2. <= h && h < 3.)
{
pix[0] = (int)P;
pix[1] = (int)V;
pix[2] = (int)T;
}
else if (3. <= h && h < 4.)
{
pix[0] = (int)P;
pix[1] = (int)Q;
pix[2] = (int)V;
}
else if (4. <= h && h < 5.)
{
pix[0] = (int)T;
pix[1] = (int)P;
pix[2] = (int)V;
}
else if (5. <= h && h < 6.)
{
pix[0] = (int)V;
pix[1] = (int)P;
pix[2] = (int)Q;
}
else
{
pix[0] = 153;
pix[1] = 20;
pix[2] = 0;
}
fwrite(pix,1,3,tempfile);
}
我从posted on Stack Overflow的人那里获取了代码并对其进行了编辑。但是我不了解代码中的所有内容。此外,在Wikipedia中(用法语表示,t是色相的h),这是不同的,因为我们对6做模,我们看是否等于1,2,3等,如果等于1或2,例。
如果我们在Wikipedia中查看该算法,则没有任何解释,所以我不知道它是如何工作的...
我们有色调,变量h,我们将色调除以60 ...为什么除以60?
同样,在Wikipedia的算法中,我们有一个变量hi,在这里为什么做模6?
在我的代码中,发布该代码的人只是:
fract = h - floor(h)
而不是fract = h - (floor(h) mod 6)
如果继续,我们将看到3个变量(在Wikipedia中的算法中)l,m和n。这些是临时变量,但是如何找到将这些变量的结果提供给我们的公式?最后,在我的代码中,如果我们在两个值之间,则找到RGB,在算法中,发现它等于该值。为什么有区别?
该代码有效,但是如您所见,我对HSV转换为RGB背后的数学知识了解甚少。如果有人可以解释我。
最佳答案
HSV中的h是0-359度的 Angular 。 HSV到RGB变换是在6个单独的片段中定义的,基于该片段,h属于60度扇区:h在0-59之间定义是一种方式,h在60-119之间定义是另一种方式,h在120-179之间它定义了第三种方式,依此类推。
因此,该过程的第一步是找到我们所在的扇区。一种方法是将h除以60,这将为您提供0到6之间的值(不包括)。取该数字的下限将得到0-5的整数,该整数告诉您该扇区。
如果h不在0-359之间怎么办,那么如何确定扇区呢? Wikipedia文章考虑了这一点:这是您需要取模运算符的地方。 C++程序无法处理这种情况:它假定h已经在正确的范围内。
这是一个三线性插值,可以从以下规则得出:
为了获得更好的理解,请尝试在HSV中将红色取为h = 0 s = 1 v = 1,然后看看改变每个分量h s和v如何影响结果。
这是因为c++程序在步骤1中不再费心使用floor函数。与其说h是整数0-5,还不如说是0-6(不包括)
关于c++ - HSV转换为RGB的公式如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63307612/