How to Convert Rgb Color to Hsv

How to Convert RGB Color to HSV?

Have you considered simply using System.Drawing namespace? For example:

System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue);
float hue = color.GetHue();
float saturation = color.GetSaturation();
float lightness = color.GetBrightness();

Note that it's not exactly what you've asked for (see differences between HSL and HSV and the Color class does not have a conversion back from HSL/HSV but the latter is reasonably easy to add.

Convert RGB value to HSV

I'm pretty sure what you want is RGBtoHSB

int r = ...
int g = ...
int b = ...
float[] hsv = new float[3];
Color.RGBtoHSB(r,g,b,hsv)
//hsv contains the desired values

Algorithm to convert RGB to HSV and HSV to RGB in range 0-255 for both

I've used these for a long time - no idea where they came from at this point... Note that the inputs and outputs, except for the angle in degrees, are in the range of 0 to 1.0.

NOTE: this code does no real sanity checking on inputs. Proceed with caution!

typedef struct {
double r; // a fraction between 0 and 1
double g; // a fraction between 0 and 1
double b; // a fraction between 0 and 1
} rgb;

typedef struct {
double h; // angle in degrees
double s; // a fraction between 0 and 1
double v; // a fraction between 0 and 1
} hsv;

static hsv rgb2hsv(rgb in);
static rgb hsv2rgb(hsv in);

hsv rgb2hsv(rgb in)
{
hsv out;
double min, max, delta;

min = in.r < in.g ? in.r : in.g;
min = min < in.b ? min : in.b;

max = in.r > in.g ? in.r : in.g;
max = max > in.b ? max : in.b;

out.v = max; // v
delta = max - min;
if (delta < 0.00001)
{
out.s = 0;
out.h = 0; // undefined, maybe nan?
return out;
}
if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash
out.s = (delta / max); // s
} else {
// if max is 0, then r = g = b = 0
// s = 0, h is undefined
out.s = 0.0;
out.h = NAN; // its now undefined
return out;
}
if( in.r >= max ) // > is bogus, just keeps compilor happy
out.h = ( in.g - in.b ) / delta; // between yellow & magenta
else
if( in.g >= max )
out.h = 2.0 + ( in.b - in.r ) / delta; // between cyan & yellow
else
out.h = 4.0 + ( in.r - in.g ) / delta; // between magenta & cyan

out.h *= 60.0; // degrees

if( out.h < 0.0 )
out.h += 360.0;

return out;
}


rgb hsv2rgb(hsv in)
{
double hh, p, q, t, ff;
long i;
rgb out;

if(in.s <= 0.0) { // < is bogus, just shuts up warnings
out.r = in.v;
out.g = in.v;
out.b = in.v;
return out;
}
hh = in.h;
if(hh >= 360.0) hh = 0.0;
hh /= 60.0;
i = (long)hh;
ff = hh - i;
p = in.v * (1.0 - in.s);
q = in.v * (1.0 - (in.s * ff));
t = in.v * (1.0 - (in.s * (1.0 - ff)));

switch(i) {
case 0:
out.r = in.v;
out.g = t;
out.b = p;
break;
case 1:
out.r = q;
out.g = in.v;
out.b = p;
break;
case 2:
out.r = p;
out.g = in.v;
out.b = t;
break;

case 3:
out.r = p;
out.g = q;
out.b = in.v;
break;
case 4:
out.r = t;
out.g = p;
out.b = in.v;
break;
case 5:
default:
out.r = in.v;
out.g = p;
out.b = q;
break;
}
return out;
}

android convert from rgb to hsv and viceversa

Finally I found the solution.
There seems to be a strange approximation in the android implementation of android.graphics.Color.RGBToHSV.
The approximated value is exactly the Hue that in this implementation goes from 0° to 360°.

I found the code of java.awt.Color.RGBtoHSB where the HUE goes from 0.0f to 1.0f and the conversion works well. So is not a float precision bug but an implementation bug, infact by multipling the Hue * 360f I get the correct HSV Hue value.

math behind hsv to rgb conversion of colors

The easy way it is to design it by yourself (and then check the differences), and it is easier to do the inverse way: from RGB to HSV. Your formula should be just the mathematically inverse operation (do it with floating point, or you will lose information). In following explaination I'll use values from 0 to 1 (so scale by dividing with 255, if you are using 8-bit RGB).

Value is just defined as the maximum value of RGB (just to keep thing simpler), if you need brightness, you should weight the 3 channels and sum them. With this definition (of value), we can have the brightest Blue, Red, and Green with same value, which it is handy for colour picker. OTOH we know that a complete blue screen (full with [0,0,255]) is darker then a completely green screen [0,255,0].

Hue indicates the pure colours (if fully saturated), the colour on a colour wheel. These are done by mixing just two components of R,G,B (the third component should be 0). Why this? Take a typical CIE xy figure (e.g. on https://en.wikipedia.org/wiki/SRGB). Pure hues are the spectral colours, so with just one wavelength (the outer colours) plus the line of purples (the lower line), so mixing deeper violet with deeper red. With RGB we can display just the content of triangle (+ the colours on the missing z (or Y) axis). So the most similar and purer colours are the colour on the edge of the triangle between the R, G, B points. And points on a triangle have just one or two components. [CIE xy figures is nice because mixing two colours should be in the line between the two colours].

One of the property of good colour wheel (for mixing, not perceptual) is:by mixing one colour with the opposite (on the wheel), one get grey. So opposite colours are opposite also on the wheel. So we have 6 colours: red [255,0,0], yellow [255,255,0], green [0,255,0], cyan [0,255,255], blue [0,0,255], and magenta [255,0,255]. These are the six cases, 60 degrees apart. So if you have [255, 20, 0] you are 20/255 from red to yellow (where 255/255 is 60 degrees). If you write down all cases, you see that you can eventually simplify calculations [which is usually done in common libraries]

Saturation: Full saturation is like hue (so one component is zero) and full unsaturated colours are greys (or black or white) so with all components with the same value. So the differences of maximum component with minimum component is a saturation.

Why not taking the minimum, as in some formula? This is also a good definition (and maybe more precise), and used on some places. But a darken colour is seems also unsaturated (so "mixing" black or white should have similar bahaviour, so the differences instead of minimum). Ihis manner (difference), saturation is independent of value, and it is more intuitive for a colour picker. The saturation is than divided by maximum component value. Also this is just to have a 0 to 1 number for every case.

Exceptions: then there are some expection (you will see if you implement the calculations, e.g. if all component values are equal, the hue is defined as zero (it do no matter: full unsaturated colours do not have hue). Saturation of black cannot be calculated (zero divided by zero), but it is unsaturated colour, so we set it as 0.

If you derive the inverse, you see your formula.

Note: these calculation are usually done for RGB (so they are not real hue or saturation, or lightness), and for colour picker, so standardized value from 0 to 1 (or 100, or 360 for hue). In reality minimum saturation (so maximum colorfulness) depends in hue. Saturation should depend on brightness, etc. So a more physical color picker should not be a circle (cylinder, double cone), but a figure with more complex form. Which is not efficient for storage (lost of information e.g. by putting in integer: not all combination are valid), and often less intuitive.

Convert RGB to HSV in android

Let's say you have a Bitmap object and x and y co-ordinates. You can get the color from the bitmap as a 32-bit value like this:

int color = bitmap.getPixel(x, y);

You can separate out the argb components like this:

int a = Color.alpha(color);
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);

Then you can convert to HSV like this:

float[] hsv = new float[3];
Color.RGBToHSV(r, g, b, hsv);

Now you can manipulate the HSV values however you want. When you are done you can convert back to rgb:

color = Color.HSVToRGB(hsv);

or like this is you want to use the alpha value:

color = Color.HSVToRGB(a, hsv);

Then you can write the color back to the bitmap (it has to be a mutable Bitmap):

bitmap.setPixel(x, y, color);

RGB to HSV in PHP


<?php
function RGB_TO_HSV ($R, $G, $B) // RGB Values:Number 0-255
{ // HSV Results:Number 0-1
$HSL = array();

$var_R = ($R / 255);
$var_G = ($G / 255);
$var_B = ($B / 255);

$var_Min = min($var_R, $var_G, $var_B);
$var_Max = max($var_R, $var_G, $var_B);
$del_Max = $var_Max - $var_Min;

$V = $var_Max;

if ($del_Max == 0)
{
$H = 0;
$S = 0;
}
else
{
$S = $del_Max / $var_Max;

$del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;

if ($var_R == $var_Max) $H = $del_B - $del_G;
else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B;
else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R;

if ($H<0) $H++;
if ($H>1) $H--;
}

$HSL['H'] = $H;
$HSL['S'] = $S;
$HSL['V'] = $V;

return $HSL;
}


Related Topics



Leave a reply



Submit