2008-12-13 5 views
8

Toutes mes méthodes échouent de moi de diverses façons. Un éclairage différent peut tout gâcher aussi.en essayant de convertir RGB à partir d'un. NET Couleur à une chaîne comme "rouge" ou "bleu"

Quelqu'un essaie-t-il tous de renvoyer un nom avec une valeur rgb? "rouge" "vert" "bleu" suffirait à satisfaire mes besoins pour aujourd'hui.

J'ai un traitement d'octets non sécurisé des images de ma webcam.

webcam http://i35.tinypic.com/2yvorau.png

colors

+0

Donc le problème pourrait être réitéré comme donné un dictionnaire de couleurs et de noms, pour une couleur donnée trouver le nom de la couleur la plus proche? – ICR

Répondre

0

Eh bien, Rouge/Vert/Bleu sont assez faciles à identifier par l'inspection; quelle gamme de valeurs avez-vous besoin de soutenir? Le problème est que, sauf si vous commencez avec une couleur nommée, il est très difficile d'obtenir retour à un; IsNamedColor retournera false même si vous créez une couleur évidente via FromArgb.

Si vous avez seulement besoin des couleurs standard réellement attendues, vous pouvez énumérer les couleurs connues par réflexion?

 Color test = Color.FromArgb(255,0,0); 
     Color known = (
        from prop in typeof(Color) 
         .GetProperties(BindingFlags.Public | BindingFlags.Static) 
        where prop.PropertyType == typeof(Color) 
        let color = (Color)prop.GetValue(null, null) 
        where color.A == test.A && color.R == test.R 
        && color.G == test.G && color.B == test.B 
        select color) 
        .FirstOrDefault(); 

     Console.WriteLine(known.Name); 

Vous pouvez également utiliser cette approche comme source de couleurs connues pour un algorithme plus sophistiqué.

+0

full spectrum J'ai un traitement d'image par octet depuis ma webcam. http://i35.tinypic.com/2yvorau.png –

+3

Une source légèrement plus simple de couleurs standard est l'énumération KnownColors. De cette façon, vous n'avez pas besoin d'utiliser GetProperties, etc. (Utilisez Color.FromKnownColor. –

4

Si vous avez une liste de couleurs connues avec des noms, vous pouvez voir quels de ces couleurs connues une couleur cible donnée est « plus proche » à l'aide d'une fonction « proximité » le long des lignes de (F # code):

let Diff (c1:Color) (c2:Color) = 
    let dr = (c1.R - c2.R) |> int 
    let dg = (c1.G - c2.G) |> int 
    let db = (c1.B - c2.B) |> int 
    dr*dr + dg*dg + db*db 

Quelle que soit l'une des couleurs connues ayant la plus petite différence par rapport à la couleur cible que vous souhaitez nommer, utilisez ce nom.

+0

oh c'est plutôt cool – xxxxxxx

+0

alto un joli morceau de code. cette solution vous donne juste le maximum. de la différence RGB. pas vraiment ce que je demande. Je veux donner une couleur et trouver de près. mais en écrivant cela j'ai répondu dans ma tête. Je posterai le code plus tard –

2

Personnellement, je trouve plus naturel de penser aux couleurs en termes de hue/saturation/brightness que les valeurs RVB, et je pense que cela fonctionnerait bien pour vous dans ce cas. Essayez ceci:

Affectez des noms de couleurs à certaines plages du spectre, comme bon vous semble. Par exemple, peut-être que le rouge est 0-39, orange est 40-79, etc. (ce sont des nombres arbitraires - je n'ai aucune idée si elles correspondent à n'importe quelle échelle ou non). Puis calculer la teinte à partir de votre valeur RVB (vous pouvez trouver une formule here, bien qu'il puisse y avoir d'autres). Une fois que vous connaissez la teinte, vous savez à quelle gamme du spectre il appartient, et vous pouvez lui donner un nom.

+0

C'est la seule bonne réponse ici! Pour trouver une couleur, l'espace colorimétrique HSV et HSL est la seule bonne alternative. Votre code pourrait prendre comme 5 lignes dans OpenCV! –

3

Vous pouvez essayer ce code

static char[] hexDigits = { 
     '0', '1', '2', '3', '4', '5', '6', '7', 
     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 



public static string ColorToHexString(Color color) 
     { 
      byte[] bytes = new byte[4]; 
      bytes[0] = color.A; 
      bytes[1] = color.R; 
      bytes[2] = color.G; 
      bytes[3] = color.B; 
      char[] chars = new char[bytes.Length * 2]; 
      for (int i = 0; i < bytes.Length; i++) 
      { 
       int b = bytes[i]; 
       chars[i * 2] = hexDigits[b >> 4]; 
       chars[i * 2 + 1] = hexDigits[b & 0xF]; 
      } 
      return new string(chars); 
     } 
0

Voici un schéma simple de nom en utilisant deux qualificatifs et un nom de couleur:

string ColorName(Color c) 
{ 
    List<float> hues = new List<float>() 
    { 0, 15, 35, 44, 54, 63, 80, 160, 180, 200, 244, 280, 350, 360}; 
    List<string> hueNames = new List<string>() 
     { "red", "orange-red", "orange", "yellow-orange", "yellow", 
      "yellow-green", "green" , "blue-green" , "cyan", "blue", 
      "violet", "purple", "red" }; 

    float h = c.GetHue(); 
    float s = c.GetSaturation(); 
    float b = (c.R * 0.299f + c.G * 0.587f + c.B *0.114f)/256f; 

    string name = s < 0.35f ? "pale " : s > 0.8f ? "vivid " : ""; 
    name += b < 0.35f ? "dark " : b > 0.8f ? "light " : ""; 
    for (int i = 0; i < hues.Count - 1; i++) 
     if (h >= hues[i] && h <= hues[i+1]) 
     { 
      name += hueNames[i]; 
      break; 
     } 
    return name; 
} 

Vous pouvez facilement adapter si vous voulez le blues être plus différencié etc ..

Questions connexes