Confronta i colors RGB in c #

Sto cercando di trovare un modo per confrontare due colors per scoprire quanto sono simili. Non riesco a trovare risorse sull’argomento, quindi spero di ottenere alcuni suggerimenti qui.

In teoria, vorrei ottenere un punteggio che indichi quanto siano simili. Ad esempio, da 0 a 100, dove 100 sarebbe uguale e 0 sarebbe completamente diverso.

Grazie!

Modificare:

Conoscere un po ‘di più sui colors dalle risposte Capisco che la mia domanda era un po’ vaga. Proverò a spiegare per cosa ho bisogno di questo.

Ho pixeldata (posizione e colore) di una finestra di applicazione a 800×600 dimensioni in modo da poter scoprire se una determinata finestra è aperta o non controllando ogni x-intervallo.

Tuttavia, questo metodo fallisce non appena l’applicazione viene ridimensionata (i contenuti vengono ridimensionati, non spostati). Posso calcolare dove si muovono i pixel, ma a causa dell’arrotondamento e dell’antializzazione il colore può essere leggermente diverso.

La soluzione di Pieter è stata abbastanza buona per me in questo caso, anche se tutte le altre risposte sono state estremamente utili, quindi ho semplicemente upvoted tutti. Penso che la risposta di ColorEye sia la più accurata quando la si guarda da un punto di vista professionale, quindi l’ho contrassegnata come la risposta.

Quello che stai cercando si chiama Delta-E .

http://www.colorwiki.com/wiki/Delta_E:_The_Color_Difference

È la distanza tra due colors nello spazio colore LAB. Si dice che l’occhio umano non possa distinguere i colors al di sotto di 1 DeltaE (trovo che i miei occhi possano trovare differenze nei colors inferiori a 1 DeltaE, ogni persona è diversa).

Ci sono 4 formule per “differenza di colore”.

  • Delta E (CIE 1976)
  • Delta E (CIE 1994)
  • Delta E (CIE 2000)
  • Delta E (CMC)

Controlla il link di matematica su questo sito:

Quindi la risposta corretta è convertire il tuo RGB in LAB usando la formula data, quindi usa DeltaE 1976 per determinare la ‘differenza’ nei tuoi colors. Un risultato di 0 indica colors identici. Qualsiasi valore superiore a 0 potrebbe essere giudicato dalla regola “Un delta e di 1 o meno è indistinguibile dalla maggior parte delle persone”.

I colors hanno pesi diversi che colpiscono l’occhio umano. Quindi converti i colors in scala di grigi usando i loro pesi calcolati:

Colore grigio = .11 * B + .59 * G + .30 * R

E la tua differenza sarà (GrayColor1 – GrayColor2) * 100.0 / 256.0

Questo è in realtà un approccio comunemente usato e molto semplice utilizzato per calcolare le differenze di immagine nell’elaborazione dell’immagine.

-edifica che questa è la formula molto semplice e ancora utilizzabile, anche nelle applicazioni commerciali. Se vuoi approfondire dovresti controllare i metodi di differenza di colore chiamati: CIE1976, CIE1994, CIE2000 e CMC Qui puoi trovare alcune informazioni più dettagliate: http://en.wikipedia.org/wiki/Color_difference

La conversione del colore RGB nello spazio colore HSL spesso produce buoni risultati. Controlla wikipedia per la formula di conversione. Sta a te assegnare i pesi alle differenze in H, il colore, S, quanto ‘profondo’ è il colore e L, quanto è luminoso.

C’è una libreria .net open-source che ti permette di farlo facilmente: https://github.com/THEjoezack/ColorMine

Il metodo più comune per confrontare i colors è CIE76 :

 var a = new Rgb { R = 149, G = 13, B = 12 } var b = new Rgb { R = 255, G = 13, B = 12 } var deltaE = a.Compare(b,new Cie1976Comparison()); 

Qualcosa come questo:

  public static int CompareColors(Color a, Color b) { return 100 * (int)( 1.0 - ((double)( Math.Abs(aR - bR) + Math.Abs(aG - bG) + Math.Abs(aB - bB) ) / (256.0 * 3)) ); } 

La percezione del colore dipende da molti fattori e la somiglianza può essere misurata in molti modi. Solo confrontando come i componenti R, G e B in genere danno risultati che gli umani non sono d’accordo.

C’è del materiale generale sui confronti dei colors in wikipedia e su come lavorare con gli spazi colore naturali in C # in questa domanda .

Ho trovato un approccio interessante chiamato Color metric e adattato a C #

 public static double ColourDistance(Color e1, Color e2) { long rmean = ((long)e1.R + (long)e2.R) / 2; long r = (long)e1.R - (long)e2.R; long g = (long)e1.G - (long)e2.G; long b = (long)e1.B - (long)e2.B; return Math.Sqrt((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8)); } 

Ho tradotto il codice per DeltaE2000 sulla pagina di Bruce Lindbloom in C.

Qui:

  // // deltae2000.c // // Translated by Dr Cube on 10/1/16. // Translated to C from this javascript code written by Bruce LindBloom: // http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html // http://www.brucelindbloom.com/javascript/ColorDiff.js #include  #include  #define Lab2k struct Lab2kStruct Lab2k { float L; float a; float b; }; // function expects Lab where: 0 >= L <=100.0 , -100 >=a <= 100.0 and -100 >= b <= 100.0 float DeltaE2000(Lab2k Lab1,Lab2k Lab2) { float kL = 1.0; float kC = 1.0; float kH = 1.0; float lBarPrime = 0.5 * (Lab1.L + Lab2.L); float c1 = sqrtf(Lab1.a * Lab1.a + Lab1.b * Lab1.b); float c2 = sqrtf(Lab2.a * Lab2.a + Lab2.b * Lab2.b); float cBar = 0.5 * (c1 + c2); float cBar7 = cBar * cBar * cBar * cBar * cBar * cBar * cBar; float g = 0.5 * (1.0 - sqrtf(cBar7 / (cBar7 + 6103515625.0))); /* 6103515625 = 25^7 */ float a1Prime = Lab1.a * (1.0 + g); float a2Prime = Lab2.a * (1.0 + g); float c1Prime = sqrtf(a1Prime * a1Prime + Lab1.b * Lab1.b); float c2Prime = sqrtf(a2Prime * a2Prime + Lab2.b * Lab2.b); float cBarPrime = 0.5 * (c1Prime + c2Prime); float h1Prime = (atan2f(Lab1.b, a1Prime) * 180.0) / M_PI; float dhPrime; // not initialized on purpose if (h1Prime < 0.0) h1Prime += 360.0; float h2Prime = (atan2f(Lab2.b, a2Prime) * 180.0) / M_PI; if (h2Prime < 0.0) h2Prime += 360.0; float hBarPrime = (fabsf(h1Prime - h2Prime) > 180.0) ? (0.5 * (h1Prime + h2Prime + 360.0)) : (0.5 * (h1Prime + h2Prime)); float t = 1.0 - 0.17 * cosf(M_PI * ( hBarPrime - 30.0) / 180.0) + 0.24 * cosf(M_PI * (2.0 * hBarPrime ) / 180.0) + 0.32 * cosf(M_PI * (3.0 * hBarPrime + 6.0) / 180.0) - 0.20 * cosf(M_PI * (4.0 * hBarPrime - 63.0) / 180.0); if (fabsf(h2Prime - h1Prime) <= 180.0) dhPrime = h2Prime - h1Prime; else dhPrime = (h2Prime <= h1Prime) ? (h2Prime - h1Prime + 360.0) : (h2Prime - h1Prime - 360.0); float dLPrime = Lab2.L - Lab1.L; float dCPrime = c2Prime - c1Prime; float dHPrime = 2.0 * sqrtf(c1Prime * c2Prime) * sinf(M_PI * (0.5 * dhPrime) / 180.0); float sL = 1.0 + ((0.015 * (lBarPrime - 50.0) * (lBarPrime - 50.0)) / sqrtf(20.0 + (lBarPrime - 50.0) * (lBarPrime - 50.0))); float sC = 1.0 + 0.045 * cBarPrime; float sH = 1.0 + 0.015 * cBarPrime * t; float dTheta = 30.0 * expf(-((hBarPrime - 275.0) / 25.0) * ((hBarPrime - 275.0) / 25.0)); float cBarPrime7 = cBarPrime * cBarPrime * cBarPrime * cBarPrime * cBarPrime * cBarPrime * cBarPrime; float rC = sqrtf(cBarPrime7 / (cBarPrime7 + 6103515625.0)); float rT = -2.0 * rC * sinf(M_PI * (2.0 * dTheta) / 180.0); return(sqrtf( (dLPrime / (kL * sL)) * (dLPrime / (kL * sL)) + (dCPrime / (kC * sC)) * (dCPrime / (kC * sC)) + (dHPrime / (kH * sH)) * (dHPrime / (kH * sH)) + (dCPrime / (kC * sC)) * (dHPrime / (kH * sH)) * rT ) ); }