C++ HSI的问题->;RGB转换
我在尝试将HSI转换为RGB时遇到了一些奇怪的问题,我正在尝试将其作为家庭作业的一部分。首先,这里是我的原始图像: (很抱歉链接,我没有代表发布图片) 我正在从具有H、S、I值(0-255)的图像进行转换。以下是该图像在RGB颜色空间中的显示(色调=红色,sat=绿色,强度=蓝色): 对我来说,它看起来是正确的。。。白色的花(高强度)是蓝色的,颜色(红色)似乎随着不同颜色的花而变化 现在我在一些框中对强度通道(显示为蓝色)进行了一些均衡,结果如下: HSI均衡图像:C++ HSI的问题->;RGB转换,c++,image-processing,rgb,C++,Image Processing,Rgb,我在尝试将HSI转换为RGB时遇到了一些奇怪的问题,我正在尝试将其作为家庭作业的一部分。首先,这里是我的原始图像: (很抱歉链接,我没有代表发布图片) 我正在从具有H、S、I值(0-255)的图像进行转换。以下是该图像在RGB颜色空间中的显示(色调=红色,sat=绿色,强度=蓝色): 对我来说,它看起来是正确的。。。白色的花(高强度)是蓝色的,颜色(红色)似乎随着不同颜色的花而变化 现在我在一些框中对强度通道(显示为蓝色)进行了一些均衡,结果如下: HSI均衡图像: http://i.imgu
http://i.imgur.com/hgk9K.png
((您必须复制这些,因为我没有超过2个超链接的代表))
没什么大不了的。它看起来并不完全正确,但很难说,兴趣区框之外的所有东西都是一样的
现在问题来了。将其转换回RGB后,我得到以下结果:
转换图像:
http://i.imgur.com/6wEyw.png
不知道这里有什么问题,绿色看起来不错,但一些红色/蓝色像素似乎已达到最大值。三个盒子如预期的那样在那里,它们的内容看起来很混乱,但这不是这里更大的问题,因为这可能是因为我的均衡功能。那些盒子外的一切现在应该与原始图像几乎相同,但不知何故,它已经被混淆了
我已经检查了我的代码很多次,添加了额外的括号和数据类型转换,只是为了确定,但仍然找不到问题所在。我相信我的公式是正确的,但我必须在计算像素值的方式中遗漏一些问题
下面是我用来将HSI转换为RGB的代码。错误可能不在该方法的范围内,但此处使用的所有函数都已在其他地方进行了测试,并且似乎工作正常
void colorSpace::HSItoRGB(image &src, image &tgt){
cout<<"HSI->RGB\n";
tgt.resize(src.getNumberOfRows(),src.getNumberOfColumns());
float pi = 3.14159265358979f;
for (int i=0; i<src.getNumberOfRows(); i++){ //for each pixel
for (int j=0; j<src.getNumberOfColumns(); j++){
//re-normalize h,s,i
float h = ((float)src.getPixel(i,j,H))*pi*2.0f/255.0f;//255/2 instead of 180
float s = ((float)src.getPixel(i,j,S))/255.0f;//255 instead of 100
float in= ((float)src.getPixel(i,j,I))/255.0f;
//compute x y z
float x = in*(1.0f-s);
float y = in*( 1.0f + (s*cos(h) / cos(pi/3.0f-h)) );
float z = 3.0f*in-(x+y);
float r,g,b; //set rgb
if(h<(2.0f*pi/3.0f)){
b = x;
r = y;
g = z;
}else if(h<(4.0f*pi/3.0f)){//&&2pi/3<=h
r = x;
g = y;
b = z;
}else{ //less than 2pi && 4pi/3<=h
g = x;
b = y;
r = z;
}
//convert normalized rgb to 0-255 range
int rr = (int)round(r*255.0f);
int gg = (int)round(g*255.0f);
int bb = (int)round(b*255.0f);
tgt.setPixel(i,j,RED,rr);
tgt.setPixel(i,j,GREEN,gg);
tgt.setPixel(i,j,BLUE,bb);
}
}
}
void colorSpace::HSItoRGB(image&src,image&tgt){
cout在计算与之相关的cos值之前,需要针对这三种情况调整h值。即:
if(h<(2.0f*pi/3.0f)){
y = in*( 1.0f + (s*cos(h) / cos(pi/3.0f-h)) );
b = x;
r = y;
g = z;
}else if(h<(4.0f*pi/3.0f)){//&&2pi/3<=h
h -= 2*pi/3;
y = in*( 1.0f + (s*cos(h) / cos(pi/3.0f-h)) );
r = x;
g = y;
b = z;
}else{ //less than 2pi && 4pi/3<=h
h -= 4*pi/3;
y = in*( 1.0f + (s*cos(h) / cos(pi/3.0f-h)) );
g = x;
b = y;
r = z;
}
if(h这里的基本思想是色调值从0到360的偏移,这将产生rgb值。我们还有饱和度,它是从0.00到1.00或介于两者之间的任何值,还有强度,它也是0.00到1.00
///我使用这个
//函数结果将是数组rgb[3]的值,并且将是rgb值0-255
///浮点H的值为0-360,因为hsi颜色空间中有360度的颜色
///浮点数S为0.00-1.00,介于两者之间
///浮动I为0.00-1.00,介于两者之间
///我们函数的输入是hsi_到rgb(色调、饱和度、强度(亮度))
int rgb[3];///通道数rgb=3
无效hsi_至_rgb(浮动H、浮动S、浮动I){
int r,g,b;
如果(H>360){
H=H-360;
}
H=fmod(H,360);//将H循环至0-360度
H=3.14159*H/(浮点)180;//转换为弧度。
S=S>0?(S<1?S:1):0;//将S和I钳制到间隔[0,1]
I=I>0?(I<1?I:1):0;
如果(H<2.09439){
r=255*I/3*(1+S*cos(H)/cos(1.047196667-H));
g=255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H));
b=255*I/3*(1-S);
}否则如果(H<4.188787){
H=H-2.09439;
g=255*I/3*(1+S*cos(H)/cos(1.047196667-H));
b=255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H));
r=255*I/3*(1-S);
}否则{
H=H-4.188787;
b=255*I/3*(1+S*cos(H)/cos(1.047196667-H));
r=255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H));
g=255*I/3*(1-S);
}
//将输出设置为数组
rgb[0]=r;
rgb[1]=g;
rgb[2]=b;
}
非常感谢!我没有给出任何必要的说明,所以我对此表示怀疑,但它很有魅力!你帮了我大忙。还感谢你提出的检查最终值的建议,但我已经在SetPixel()方法中考虑到了这一点;值四舍五入到256(或可能弹出的超出范围的值)设置为最大值。还值得注意的是,需要重新排列一些其他语句以获得正确的值。
if (rr < 0) rr = 0;
if (rr > 255) rr = 255;
///I use this
// the function result will be the values of the array rgb[3] and will be the rgb values 0-255
///float H is values 0-360 because there are 360 degrees of color in hsi colorspace
///float S is 0.00 - 1.00 and aything in between
///float I is 0.00 - 1.00 and aything in between
///The input to our function is going to be hsi_to_rgb (Hue, Saturation, Intensity(brightness))
int rgb[3]; ///number of channels rgb = 3
void hsi_to_rgb(float H, float S, float I) {
int r, g, b;
if (H > 360) {
H = H - 360;
}
H = fmod(H, 360); // cycle H around to 0-360 degrees
H = 3.14159 * H / (float)180; // Convert to radians.
S = S > 0 ? (S < 1 ? S : 1) : 0; // clamp S and I to interval [0,1]
I = I > 0 ? (I < 1 ? I : 1) : 0;
if (H < 2.09439) {
r = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
g = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
b = 255 * I / 3 * (1 - S);
} else if (H < 4.188787) {
H = H - 2.09439;
g = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
b = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
r = 255 * I / 3 * (1 - S);
} else {
H = H - 4.188787;
b = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
r = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
g = 255 * I / 3 * (1 - S);
}
//set the output to the array
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
}