Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Convert RGB Color to HSV?

Tags:

c#

colors

rgb

hsv

How can I convert a RGB Color to HSV using C#?
I've searched for a fast method without using any external library.

like image 252
Tom Smykowski Avatar asked Dec 11 '08 14:12

Tom Smykowski


People also ask

Why do we convert from RGB to HSV?

R, G, B in RGB are all co-related to the color luminance( what we loosely call intensity),i.e., We cannot separate color information from luminance. HSV or Hue Saturation Value is used to separate image luminance from color information. This makes it easier when we are working on or need luminance of the image/frame.

How do I convert an image from RGB to HSV in Python?

Thus, to convert to HSV, we should use the COLOR_BGR2HSV code. As output, the cvtColor will return the converted image, which we will store in a variable. After this, we will display both images. To show each image, we simply need to call the imshow function.


2 Answers

Note that Color.GetSaturation() and Color.GetBrightness() return HSL values, not HSV.
The following code demonstrates the difference.

Color original = Color.FromArgb(50, 120, 200); // original = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}  double hue; double saturation; double value; ColorToHSV(original, out hue, out saturation, out value); // hue        = 212.0 // saturation = 0.75 // value      = 0.78431372549019607  Color copy = ColorFromHSV(hue, saturation, value); // copy = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}  // Compare that to the HSL values that the .NET framework provides:  original.GetHue();        // 212.0 original.GetSaturation(); // 0.6 original.GetBrightness(); // 0.490196079 

The following C# code is what you want. It converts between RGB and HSV using the algorithms described on Wikipedia. The ranges are 0 - 360 for hue, and 0 - 1 for saturation or value.

public static void ColorToHSV(Color color, out double hue, out double saturation, out double value) {     int max = Math.Max(color.R, Math.Max(color.G, color.B));     int min = Math.Min(color.R, Math.Min(color.G, color.B));      hue = color.GetHue();     saturation = (max == 0) ? 0 : 1d - (1d * min / max);     value = max / 255d; }  public static Color ColorFromHSV(double hue, double saturation, double value) {     int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;     double f = hue / 60 - Math.Floor(hue / 60);      value = value * 255;     int v = Convert.ToInt32(value);     int p = Convert.ToInt32(value * (1 - saturation));     int q = Convert.ToInt32(value * (1 - f * saturation));     int t = Convert.ToInt32(value * (1 - (1 - f) * saturation));      if (hi == 0)         return Color.FromArgb(255, v, t, p);     else if (hi == 1)         return Color.FromArgb(255, q, v, p);     else if (hi == 2)         return Color.FromArgb(255, p, v, t);     else if (hi == 3)         return Color.FromArgb(255, p, q, v);     else if (hi == 4)         return Color.FromArgb(255, t, p, v);     else         return Color.FromArgb(255, v, p, q); } 
like image 130
Greg Avatar answered Sep 23 '22 12:09

Greg


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.

like image 37
georged Avatar answered Sep 25 '22 12:09

georged