-
June 11th, 2014, 09:33 AM
#16
Re: Convert HSB color to RGB and RGB to HSB
Originally Posted by crazy boy
This message on the other hand says that I did not defined pointer * but I try to access member like a pointer:
type 'RGB' does not have an overloaded member 'operator ->'
And what code produces this error?
In the recent posts you did not show this error message, so you probably changed something?
Victor Nijegorodov
-
June 11th, 2014, 09:35 AM
#17
Re: Convert HSB color to RGB and RGB to HSB
The code below now compiles
Code:
#include <algorithm>
using namespace std;
struct RGB { int r; int g; int b; };
struct HSV { float h; float s; float v; };
struct STAT { int min; int max; };
void getMinMax(RGB rgb, STAT& stat){
// r g b
// 3 2 1
stat.min = min(std::min(rgb.r, rgb.g), rgb.b);
stat.max = max(std::max(rgb.r, rgb.g), rgb.b);
return;
}
// Returns the hue, saturation, and brightness of the color
void rgb2hsv(RGB rgb, HSV& hsv)
{
STAT stat;
int R,G,B;
float H,S,V, dR,dG,dB; // H,S,V and delta components
// struct hsv { float h; float s; float v; };
R = ( rgb.r / 255 ); //RGB from 0 to 255
G = ( rgb.g / 255 );
B = ( rgb.b / 255 );
getMinMax(rgb, stat); // get min and max values of RGB
int dMax = stat.max - stat.min; //Delta RGB value
V = (float)stat.max;
if ( dMax == 0 ) //This is a gray, no chroma...
{
hsv.h = 0; //HSV results from 0 to 1
hsv.s = 0;
}
else //Chromatic data...
{
hsv.s = (float)dMax / stat.max ;
dR = (float) ( ( ( stat.max - R ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dG = (float) ( ( ( stat.max - G ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dB = (float) ( ( ( stat.max - B ) / 6 ) + ( dMax / 2 ) ) / dMax ;
if ( R == stat.max ) H = dB - dG ;
else if ( G == stat.max ) H = ( 1 / 3 ) + dR - dB ;
else if ( B == stat.max ) H = ( 2 / 3 ) + dG - dR ;
if ( H < 0 ) H += 1 ;
if ( H > 1 ) H -= 1 ;
}
}
int main()
{
struct RGB rgb = { 132, 34, 255 };
struct HSV hsb;
rgb2hsv(rgb, hsb);
printf("RGB(%u,%u,%u) -> HSB(%f,%f,%f)\n", rgb.r, rgb.g, rgb.b,
hsb.h, hsb.s, hsb.v);
// prints: RGB(132,34,255) -> HSB(266.606354,0.866667,1.000000)
return 0;
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
June 11th, 2014, 09:51 AM
#18
Re: Convert HSB color to RGB and RGB to HSB
Can you tell me how to fix this bug?
Update.
Code:
// mask1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <conio.h>
struct RGB { int r; int g; int b; } rgb;
struct HSV { float h; float s; float v; } hsv;
struct STAT { float min; float max; } stat;
void getMinMax(float R, float G, float B){
// r g b
// 3 2 1
if (R < G )
{
if (R < B )
{
stat.min = R;
if ( G > B )
stat.max = G;
else
stat.max = B;
}
else
{
stat.min = B;
if ( G > B )
stat.max = G;
else
stat.max = B;
}
}
else
if ( G < B )
{
stat.min = G;
stat.max = B;
}
else
{
stat.min = B;
stat.max = G;
}
}
// Returns the hue, saturation, and brightness of the color
void rgb2hsv(struct RGB rgb, struct HSV *hsv)
{
float R,G,B,V, dR,dG,dB,H; // H,S,V and delta components
H = 0;
R = (float) ( rgb.r / 255 ); //RGB from 0 to 255
G = (float) ( rgb.g / 255 );
B = (float) ( rgb.b / 255 );
getMinMax(R,G,B); // get min and max values of RGB
int dMax = stat.max - stat.min; //Delta RGB value
V = (float) stat.max;
if ( dMax == 0 ) //This is a gray, no chroma...
{
hsv->h = 0; //HSV results from 0 to 1
hsv->s = 0;
}
else //Chromatic data...
{
hsv->s = (float) dMax / stat.max ;
dR = (float) ( ( ( stat.max - R ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dG = (float) ( ( ( stat.max - G ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dB = (float) ( ( ( stat.max - B ) / 6 ) + ( dMax / 2 ) ) / dMax ;
if ( R == stat.max ) H = dB - dG ;
else if ( G == stat.max ) H = ( 1 / 3 ) + dR - dB ;
else if ( B == stat.max ) H = ( 2 / 3 ) + dG - dR ;
if ( H < 0 ) H += 1 ;
if ( H > 1 ) H -= 1 ;
}
}
int main()
{
struct RGB rgb = { 132, 34, 255 };
struct HSV hsb;
rgb2hsv(rgb, &hsb);
printf("RGB(%u,%u,%u) -> HSB(%f,%f,%f)\n", rgb.r, rgb.g, rgb.b,
hsb.h, hsb.s, hsb.v);
// prints: RGB(132,34,255) -> HSB(266.606354,0.866667,1.000000)
_getch();
return 0;
}
RGB(132,34,255) -> HSB(-107374176.000000,1.000000,-107374176.000000)
I used this algorithm:
http://www.easyrgb.com/index.php?X=MATH&H=20#text20
But, according this calculator:
http://www.rapidtables.com/convert/color/rgb-to-hsv.htm
Results should be H:267 ° , S:86.7 °, V:100.0 %
Last edited by crazy boy; June 11th, 2014 at 10:03 AM.
-
June 11th, 2014, 10:27 AM
#19
Re: Convert HSB color to RGB and RGB to HSB
Why the R, G, B locals are empty?
-
June 11th, 2014, 10:33 AM
#20
Re: Convert HSB color to RGB and RGB to HSB
because you are doing integer divison that returns an int that you are then casting to a float. Try
Code:
R = (float)rgb.r / 255.0;
G = (float)rgb.g / 255.0;
B = (float)rgb.b / 255.0;
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
June 11th, 2014, 11:01 AM
#21
Re: Convert HSB color to RGB and RGB to HSB
Here is my code, the hue does not look correct.
hsv->h 0.073906541 float
If I multiply hsv->h by 360 I get
26.606354713439941 double
But I think it should be 267° . It looks like I should multiply by 10 but why. Now I tested another color and it really looks like I should multiply by 10. But for struct RGB rgb ={ 32, 134, 55 }; I got:
RGB(32,134,55) -> HSB(0.037582,0.761194,0.525490)
which would be:
Code:
hsv->h*360*10 135.29427051544189 double
On the link they have H:134 S:76.1 V:52.5
Yet JS http://www.javascripter.net/faq/rgb2hsv.htm
makes different result: 133.5 . That's quite difference
Code:
// mask1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <conio.h>
struct RGB { int r; int g; int b; } rgb;
struct HSV { float h; float s; float v; } hsv;
struct STAT { float min; float max; } Stat;
void getMinMax(float R, float G, float B){
// r g b
// 3 2 1
if (R < G )
{
if (R < B )
{
Stat.min = R;
if ( G > B )
Stat.max = G;
else
Stat.max = B;
}
else
{
Stat.min = B;
if ( G > B )
Stat.max = G;
else
Stat.max = B;
}
}
else
if ( G < B )
{
Stat.min = G;
Stat.max = B;
}
else
{
Stat.min = B;
Stat.max = G;
}
}
// Returns the hue, saturation, and brightness of the color
void rgb2hsv(struct RGB rgb, struct HSV *hsv)
{
float R,G,B,dR,dG,dB; // RGB and delta components
hsv->h = 0;
R = (float) rgb.r / 255 ; //RGB from 0 to 255
G = (float) rgb.g / 255 ;
B = (float) rgb.b / 255 ;
getMinMax(R,G,B); // get min and max values of RGB
float dMax = Stat.max - Stat.min; //Delta RGB value
hsv->v = Stat.max;
if ( dMax == 0 ) //This is a gray, no chroma...
{
hsv->h = 0; //HSV results from 0 to 1
hsv->s = 0;
}
else //Chromatic data...
{
hsv->s = dMax / Stat.max ;
dR = ( ( ( Stat.max - R ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dG = ( ( ( Stat.max - G ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dB = ( ( ( Stat.max - B ) / 6 ) + ( dMax / 2 ) ) / dMax ;
if ( R == Stat.max ) hsv->h = dB - dG ;
else if ( G == Stat.max ) hsv->h = ( 1 / 3 ) + dR - dB ;
else if ( B == Stat.max ) hsv->h = ( 2 / 3 ) + dG - dR ;
if ( hsv->h < 0 ) hsv->h += 1 ;
if ( hsv->h > 1 ) hsv->h -= 1 ;
}
}
int main()
{
struct RGB rgb ={ 132, 34, 255 };
struct HSV hsb;
rgb2hsv(rgb, &hsb);
printf("RGB(%u,%u,%u) -> HSB(%f,%f,%f)\n", rgb.r, rgb.g, rgb.b,
hsb.h, hsb.s, hsb.v);
// prints: RGB(132,34,255) -> HSB(266.606354,0.866667,1.000000)
_getch();
return 0;
}
Any idea what could be wrong?
Last edited by crazy boy; June 11th, 2014 at 11:12 AM.
-
June 11th, 2014, 11:09 AM
#22
Re: Convert HSB color to RGB and RGB to HSB
Originally Posted by crazy boy;2156761[code
if ( R == Stat.max ) hsv->h = dB - dG ;
else if ( G == Stat.max ) hsv->h = ( 1 / 3 ) + dR - dB ;
else if ( B == Stat.max ) hsv->h = ( 2 / 3 ) + dG - dR ;
[/code]
I have no idea what these lines of code suppose to do but both ( 1 / 3 ) and ( 2 / 3 ) parts may be thrown away since they both are equal to zero.
Victor Nijegorodov
-
June 11th, 2014, 11:23 AM
#23
Re: Convert HSB color to RGB and RGB to HSB
It is explained here:
http://www.easyrgb.com/index.php?X=MATH&H=20#text20
and here the formula see bellow:
http://www.rapidtables.com/convert/color/rgb-to-hsv.htm
It has something with the lengh of circle 1/3 of 360°, 2/3 or 360° and 3/3 360° - ranges of segments of circle
-
June 11th, 2014, 11:28 AM
#24
Re: Convert HSB color to RGB and RGB to HSB
Thanks guys, now I think it really works :-) First time working with floats.
Code:
// mask1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <conio.h>
struct RGB { int r; int g; int b; } rgb;
struct HSV { float h; float s; float v; } hsv;
struct STAT { float min; float max; } Stat;
void getMinMax(float R, float G, float B){
// r g b
// 3 2 1
if (R < G )
{
if (R < B )
{
Stat.min = R;
if ( G > B )
Stat.max = G;
else
Stat.max = B;
}
else
{
Stat.min = B;
if ( G > B )
Stat.max = G;
else
Stat.max = B;
}
}
else
if ( G < B )
{
Stat.min = G;
Stat.max = B;
}
else
{
Stat.min = B;
Stat.max = G;
}
}
// Returns the hue, saturation, and brightness of the color
void rgb2hsv(struct RGB rgb, struct HSV *hsv)
{
float R,G,B,dR,dG,dB; // RGB and delta components
hsv->h = 0;
R = (float) rgb.r / 255 ; //RGB from 0 to 255
G = (float) rgb.g / 255 ;
B = (float) rgb.b / 255 ;
getMinMax(R,G,B); // get min and max values of RGB
float dMax = Stat.max - Stat.min; //Delta RGB value
hsv->v = Stat.max;
if ( dMax == 0 ) //This is a gray, no chroma...
{
hsv->h = 0; //HSV results from 0 to 1
hsv->s = 0;
}
else //Chromatic data...
{
hsv->s = dMax / Stat.max ;
dR = ( ( ( Stat.max - R ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dG = ( ( ( Stat.max - G ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dB = ( ( ( Stat.max - B ) / 6 ) + ( dMax / 2 ) ) / dMax ;
if ( R == Stat.max ) hsv->h = dB - dG ;
else if ( G == Stat.max ) hsv->h = ( 1.0 / 3.0 ) + dR - dB ;
else if ( B == Stat.max ) hsv->h = ( 2.0 / 3.0 ) + dG - dR ;
if ( hsv->h < 0 ) hsv->h += 1 ;
if ( hsv->h > 1 ) hsv->h -= 1 ;
}
}
int main()
{
struct RGB rgb ={ 32, 134, 55 };
struct HSV hsb;
rgb2hsv(rgb, &hsb);
printf("RGB(%u,%u,%u) -> HSB(%f,%f,%f)\n", rgb.r, rgb.g, rgb.b,
hsb.h, hsb.s, hsb.v);
// prints: RGB(132,34,255) -> HSB(266.606354,0.866667,1.000000)
_getch();
return 0;
}
-
June 11th, 2014, 01:22 PM
#25
Re: Convert HSB color to RGB and RGB to HSB
Finished
Code:
// mask1.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <conio.h>
struct RGB { int r; int g; int b; } rgb;
struct HSV { float h; float s; float v; } hsv;
struct STAT { float min; float max; } Stat;
double round(double n)
{
return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5);
}
void getMinMax(float R, float G, float B){
if (R < G )
{
if (R < B )
{
Stat.min = R;
if ( G > B )
Stat.max = G;
else
Stat.max = B;
}
else
{
Stat.min = B;
if ( G > B )
Stat.max = G;
else
Stat.max = B;
}
}
else
if ( G < B )
{
Stat.min = G;
Stat.max = B;
}
else
{
Stat.min = B;
Stat.max = G;
}
}
// Returns the hue, saturation, and brightness of the color
void rgb2hsv(struct RGB rgb, struct HSV *hsv)
{
float R,G,B,dR,dG,dB; // RGB and delta components
hsv->h = 0;
R = (float) rgb.r / 255; G = (float) rgb.g / 255; B = (float) rgb.b / 255;
getMinMax(R,G,B); // get min and max values of RGB
float dMax = Stat.max - Stat.min; //Delta RGB value
hsv->v = Stat.max;
if ( dMax == 0 ) //This is a gray, no chroma...
{
hsv->h = 0; //HSV results from 0 to 1
hsv->s = 0;
}
else //Chromatic data...
{
hsv->s = dMax / Stat.max ;
dR = ( ( ( Stat.max - R ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dG = ( ( ( Stat.max - G ) / 6 ) + ( dMax / 2 ) ) / dMax ;
dB = ( ( ( Stat.max - B ) / 6 ) + ( dMax / 2 ) ) / dMax ;
if ( R == Stat.max ) hsv->h = dB - dG ;
else if ( G == Stat.max ) hsv->h = ( 1.0 / 3.0 ) + dR - dB ;
else if ( B == Stat.max ) hsv->h = ( 2.0 / 3.0 ) + dG - dR ;
if ( hsv->h < 0 ) hsv->h += 1 ;
if ( hsv->h > 1 ) hsv->h -= 1 ;
}
}
void hsv2rgb(struct HSV hsv, struct RGB *rgb)
{
float R,G,B,varH,varR,varG,varB,varI,var1,var2,var3;
if ( hsv.s == 0 ) //HSV from 0 to 1
{ R = hsv.v * 255; G = hsv.v * 255; B = hsv.v * 255; }
else
{
varH = hsv.h * 6;
if ( varH == 6 ) varH = 0; //H must be < 1
varI = (int) int( varH ); //Or ... varI = floor( varH )
var1 = hsv.v * ( 1 - hsv.s );
var2 = hsv.v * ( 1 - hsv.s * ( varH - varI ) );
var3 = hsv.v * ( 1 - hsv.s * ( 1 - ( varH - varI ) ) );
if ( varI == 0 ) { varR = hsv.v; varG = var3; varB = var1; }
else if ( varI == 1 ) { varR = var2; varG = hsv.v; varB = var1; }
else if ( varI == 2 ) { varR = var1; varG = hsv.v; varB = var3; }
else if ( varI == 3 ) { varR = var1; varG = var2; varB = hsv.v; }
else if ( varI == 4 ) { varR = var3; varG = var1; varB = hsv.v; }
else { varR = hsv.v; varG = var1; varB = var2; }
rgb->r = (int) round(varR * 255); //RGB results from 0 to 255
rgb->g = (int) round(varG * 255);
rgb->b = (int) round(varB * 255);
}
}
int main()
{
struct RGB rgb ={ 32, 134, 55 };
struct HSV hsb;
rgb2hsv(rgb, &hsb);
printf("RGB(%u,%u,%u) -> HSB(%f,%f,%f)\n", rgb.r, rgb.g, rgb.b,
hsb.h, hsb.s, hsb.v);
// TEST it back
rgb.r = 0; rgb.g = 0, rgb.b = 0;
hsv2rgb(hsb, &rgb);
printf("HSV(%f,%f,%f) -> RGB(%u,%u,%u)\n", hsb.h, hsb.s, hsb.v,
rgb.r, rgb.g, rgb.b);
// prints: RGB(132,34,255) -> HSB(266.606354,0.866667,1.000000)
_getch();
return 0;
}
Last edited by crazy boy; June 11th, 2014 at 02:04 PM.
-
June 11th, 2014, 01:31 PM
#26
Re: Convert HSB color to RGB and RGB to HSB
It's not good doing equality tests on floats/doubles. The actual internal value may not be exact even though you think it should be. So your test for varH == 6 may or not give the answer expected.
In tracing through the code with the debugger, where does the results start to deviate from that expected?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
June 11th, 2014, 02:04 PM
#27
Re: Convert HSB color to RGB and RGB to HSB
I've just updated the code to finish the round()s. I found there is not error in the function. It gives correct number. But it was wrong displayed. I corrected the problem.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|