将 RGB 转换为 HSV 并将 HSV 转换为 RGB 后图像上出现奇怪的颜色点
Weird color dots on image after converting RGB to HSV and HSV to RGB
大家早上好。我正在尝试编写可以在 RGB 和 HSV 之间转换的 类。下面是我将 RGB 传输到 HSV 和将 HSV 传输到 RGB 的代码。我尝试将 RGB 转换为 HSV,然后将 HSV 转换为 RGB,然后打印图像。看起来可行,但我的图像上有色点。不知道有没有人能帮忙解释一下这个现象。
public class RGBtoHSV {
private float normR, normG, normB, Cmax, Cmin, delta;
private float hue, saturation, value;
private int R, G, B;
int numP;
public RGBtoHSV(int R, int G, int B){
this.R=R; this.G=G; this.B=B;
normR = R/255; normG = G/255; normB = B/255;
Cmax = Math.max(R, Math.max(G, B));
Cmin = Math.min(R, Math.min(G, B));
delta = Cmax - Cmin;
calcHue();
calcSaturation();
calcValue();
}
public void calcHue(){
if(delta == 0 ){
hue = 0;
}else if((Cmax == R)){
hue = 60 * ((G-B)/delta);
}else if(G == Cmax){
hue = 60 * (((B-R)/delta)+2);
}else{
hue = 60f * (((R-G)/delta)+4f);
}
}
public void calcSaturation(){
if(Cmax == 0)
saturation = 0;
else
saturation = delta/Cmax;
}
public void calcValue(){
value = Cmax/255;
}
//getters
public float[] getHSV(){
float[] HSV = new float[3];
HSV[0] = hue;
HSV[1] = saturation;
HSV[2] = value;
return HSV;
}
}
HSV转RGB的代码
public class HSVtoRGB {
int R, G, B;
float C, X, m;
float normR, normG, normB;
public HSVtoRGB(float H, float S, float V){
C = S *V;
X = C * (1 - Math.abs((H/60)%2 -1));
m = V - C;
if(H < 60){
normR=C; normG=X; normB=0;
}else if(H<120){
normR=X; normG=C; normB=0;
}else if(H <180){
normR=0; normG=C; normB=X;
}else if(H<240){
normR=0; normG=X; normB=C;
}else if(H<300){
normR=X;normG=0;normG=C;
}else{
normR=C;normG=0;normG=X;
}
R = Math.round((normR+m)*255);
G = Math.round((normG+m)*255);
B = Math.round((normB+m)*255);
}
public int[] getRGB(){
int [] RGB = new int[3];
RGB[0] = R;
RGB[1] = G;
RGB[2] = B;
return RGB;
}
Original Image
Image after Conversion
提前致谢!!
我没有看过你的代码,但我相信我知道是什么导致了问题:在你的代码中的某个地方,值被包装(例如,从 "fully white" 之外)到另一个刻度的末端(例如,"fully black" 附近的某处),通常是因为使用了太小的变量来保存临时值。
例如,如果你有一个signed byte变量并用它来存储16*9 (144,大于带符号字节的最大 +127 值),您的带符号字节值将是 -16 - 这将产生 "unexpected" 结果。
编辑
看了你的代码后,我怀疑你的部分问题是混合整数和浮点数运算:例如,有些地方你使用 60
,而其他地方你使用 60f
,我assume 表示您需要在计算中使用浮点数。 (我只是猜测,因为你没有指定你正在使用的 language。)你需要在 all[=30= 中使用浮点数] 的计算。
大家早上好。我正在尝试编写可以在 RGB 和 HSV 之间转换的 类。下面是我将 RGB 传输到 HSV 和将 HSV 传输到 RGB 的代码。我尝试将 RGB 转换为 HSV,然后将 HSV 转换为 RGB,然后打印图像。看起来可行,但我的图像上有色点。不知道有没有人能帮忙解释一下这个现象。
public class RGBtoHSV {
private float normR, normG, normB, Cmax, Cmin, delta;
private float hue, saturation, value;
private int R, G, B;
int numP;
public RGBtoHSV(int R, int G, int B){
this.R=R; this.G=G; this.B=B;
normR = R/255; normG = G/255; normB = B/255;
Cmax = Math.max(R, Math.max(G, B));
Cmin = Math.min(R, Math.min(G, B));
delta = Cmax - Cmin;
calcHue();
calcSaturation();
calcValue();
}
public void calcHue(){
if(delta == 0 ){
hue = 0;
}else if((Cmax == R)){
hue = 60 * ((G-B)/delta);
}else if(G == Cmax){
hue = 60 * (((B-R)/delta)+2);
}else{
hue = 60f * (((R-G)/delta)+4f);
}
}
public void calcSaturation(){
if(Cmax == 0)
saturation = 0;
else
saturation = delta/Cmax;
}
public void calcValue(){
value = Cmax/255;
}
//getters
public float[] getHSV(){
float[] HSV = new float[3];
HSV[0] = hue;
HSV[1] = saturation;
HSV[2] = value;
return HSV;
}
}
HSV转RGB的代码
public class HSVtoRGB {
int R, G, B;
float C, X, m;
float normR, normG, normB;
public HSVtoRGB(float H, float S, float V){
C = S *V;
X = C * (1 - Math.abs((H/60)%2 -1));
m = V - C;
if(H < 60){
normR=C; normG=X; normB=0;
}else if(H<120){
normR=X; normG=C; normB=0;
}else if(H <180){
normR=0; normG=C; normB=X;
}else if(H<240){
normR=0; normG=X; normB=C;
}else if(H<300){
normR=X;normG=0;normG=C;
}else{
normR=C;normG=0;normG=X;
}
R = Math.round((normR+m)*255);
G = Math.round((normG+m)*255);
B = Math.round((normB+m)*255);
}
public int[] getRGB(){
int [] RGB = new int[3];
RGB[0] = R;
RGB[1] = G;
RGB[2] = B;
return RGB;
}
Original Image
Image after Conversion
提前致谢!!
我没有看过你的代码,但我相信我知道是什么导致了问题:在你的代码中的某个地方,值被包装(例如,从 "fully white" 之外)到另一个刻度的末端(例如,"fully black" 附近的某处),通常是因为使用了太小的变量来保存临时值。
例如,如果你有一个signed byte变量并用它来存储16*9 (144,大于带符号字节的最大 +127 值),您的带符号字节值将是 -16 - 这将产生 "unexpected" 结果。
编辑
看了你的代码后,我怀疑你的部分问题是混合整数和浮点数运算:例如,有些地方你使用 60
,而其他地方你使用 60f
,我assume 表示您需要在计算中使用浮点数。 (我只是猜测,因为你没有指定你正在使用的 language。)你需要在 all[=30= 中使用浮点数] 的计算。