Suivi: Trouver une «distance» précise entre les couleurs

Question originale

Je cherche une fonction qui tente de quantifier la “distance” (ou distinct) des deux couleurs. Cette question est vraiment en deux parties:

  1. Quel espace colorimésortingque représente le mieux la vision humaine?
  2. Quelle distance mésortingque dans cet espace représente le mieux la vision humaine (euclidienne?)

Convertissez en La * b * (alias simplement “Lab”, et vous verrez également la référence à “CIELAB”). Une bonne mesure rapide de la différence de couleur est

(L1-L2) ^ 2 + (a1-a2) ^ 2 + (b1-b2) ^ 2

Les scientifiques en couleur ont d’autres mesures plus sophistiquées, qui peuvent ne pas en valoir la peine, en fonction de la précision requirejse pour ce que vous faites.

Les valeurs a et b représentent des couleurs opposées de la même manière que les cônes fonctionnent et peuvent être négatives ou positives. Couleurs neutres – blanc, les gris sont a=0 , b=0 . Le L est la luminosité définie d’une manière particulière, de zéro (obscurité pure) à n’importe quoi.

Explication brute: >> Étant donné une couleur, nos yeux distinguent deux grandes plages de longueurs d’onde – le bleu et le long. et puis, grâce à une mutation génétique plus récente, les cônes de longueur d’onde plus longue se sont divisés en deux, distinguant pour nous rouge et vert.

Soit dit en passant, ce sera génial pour votre carrière de s’élever au-dessus de vos collègues de couleur des hommes des cavernes qui connaissent seulement “RVB” ou “CMJN” qui sont parfaits pour les appareils, mais sont nuls pour le travail de perception sérieux. J’ai travaillé pour des scientifiques en imagerie qui ne connaissaient rien à ce sujet!

Pour plus de lecture sur la théorie de la différence de couleur, essayez:

Plus de détails sur Lab à http://en.kioskea.net/video/cie-lab.php3 Je ne peux pas pour le moment trouver une page non laide qui contienne les formules de conversion, mais je suis sûr que quelqu’un va l’éditer répondre à en inclure un.

Comme le lien cmesortingc.htm ci-dessus a échoué pour moi, ainsi que de nombreuses autres implémentations pour la distance de couleur, j’ai trouvé (après un très long jurney ..) comment calculer la meilleure distance de couleur, et plus scientifiquement exacte: deltaE et de 2 Valeurs RVB (!) En utilisant OpenCV:

Cela nécessitait 3 conversions d’espace colorimésortingque + une conversion de code de JavaScript ( http://svn.int64.org/viewvc/int64/colors/colors.js ) en C ++

Et enfin le code (semble fonctionner dès la sortie de la boîte, j’espère que personne ne trouvera un bug sérieux là-bas … mais ça semble aller bien après un certain nombre de tests)

 #include  #include  #include  #include  #include  using namespace cv; using namespace std; #define REF_X 95.047; // Observer= 2°, Illuminant= D65 #define REF_Y 100.000; #define REF_Z 108.883; void bgr2xyz( const Vec3b& BGR, Vec3d& XYZ ); void xyz2lab( const Vec3d& XYZ, Vec3d& Lab ); void lab2lch( const Vec3d& Lab, Vec3d& LCH ); double deltaE2000( const Vec3b& bgr1, const Vec3b& bgr2 ); double deltaE2000( const Vec3d& lch1, const Vec3d& lch2 ); void bgr2xyz( const Vec3b& BGR, Vec3d& XYZ ) { double r = (double)BGR[2] / 255.0; double g = (double)BGR[1] / 255.0; double b = (double)BGR[0] / 255.0; if( r > 0.04045 ) r = pow( ( r + 0.055 ) / 1.055, 2.4 ); else r = r / 12.92; if( g > 0.04045 ) g = pow( ( g + 0.055 ) / 1.055, 2.4 ); else g = g / 12.92; if( b > 0.04045 ) b = pow( ( b + 0.055 ) / 1.055, 2.4 ); else b = b / 12.92; r *= 100.0; g *= 100.0; b *= 100.0; XYZ[0] = r * 0.4124 + g * 0.3576 + b * 0.1805; XYZ[1] = r * 0.2126 + g * 0.7152 + b * 0.0722; XYZ[2] = r * 0.0193 + g * 0.1192 + b * 0.9505; } void xyz2lab( const Vec3d& XYZ, Vec3d& Lab ) { double x = XYZ[0] / REF_X; double y = XYZ[1] / REF_X; double z = XYZ[2] / REF_X; if( x > 0.008856 ) x = pow( x , .3333333333 ); else x = ( 7.787 * x ) + ( 16.0 / 116.0 ); if( y > 0.008856 ) y = pow( y , .3333333333 ); else y = ( 7.787 * y ) + ( 16.0 / 116.0 ); if( z > 0.008856 ) z = pow( z , .3333333333 ); else z = ( 7.787 * z ) + ( 16.0 / 116.0 ); Lab[0] = ( 116.0 * y ) - 16.0; Lab[1] = 500.0 * ( x - y ); Lab[2] = 200.0 * ( y - z ); } void lab2lch( const Vec3d& Lab, Vec3d& LCH ) { LCH[0] = Lab[0]; LCH[1] = sqrt( ( Lab[1] * Lab[1] ) + ( Lab[2] * Lab[2] ) ); LCH[2] = atan2( Lab[2], Lab[1] ); } double deltaE2000( const Vec3b& bgr1, const Vec3b& bgr2 ) { Vec3d xyz1, xyz2, lab1, lab2, lch1, lch2; bgr2xyz( bgr1, xyz1 ); bgr2xyz( bgr2, xyz2 ); xyz2lab( xyz1, lab1 ); xyz2lab( xyz2, lab2 ); lab2lch( lab1, lch1 ); lab2lch( lab2, lch2 ); return deltaE2000( lch1, lch2 ); } double deltaE2000( const Vec3d& lch1, const Vec3d& lch2 ) { double avg_L = ( lch1[0] + lch2[0] ) * 0.5; double delta_L = lch2[0] - lch1[0]; double avg_C = ( lch1[1] + lch2[1] ) * 0.5; double delta_C = lch1[1] - lch2[1]; double avg_H = ( lch1[2] + lch2[2] ) * 0.5; if( fabs( lch1[2] - lch2[2] ) > CV_PI ) avg_H += CV_PI; double delta_H = lch2[2] - lch1[2]; if( fabs( delta_H ) > CV_PI ) { if( lch2[2] <= lch1[2] ) delta_H += CV_PI * 2.0; else delta_H -= CV_PI * 2.0; } delta_H = sqrt( lch1[1] * lch2[1] ) * sin( delta_H ) * 2.0; double T = 1.0 - 0.17 * cos( avg_H - CV_PI / 6.0 ) + 0.24 * cos( avg_H * 2.0 ) + 0.32 * cos( avg_H * 3.0 + CV_PI / 30.0 ) - 0.20 * cos( avg_H * 4.0 - CV_PI * 7.0 / 20.0 ); double SL = avg_L - 50.0; SL *= SL; SL = SL * 0.015 / sqrt( SL + 20.0 ) + 1.0; double SC = avg_C * 0.045 + 1.0; double SH = avg_C * T * 0.015 + 1.0; double delta_Theta = avg_H / 25.0 - CV_PI * 11.0 / 180.0; delta_Theta = exp( delta_Theta * -delta_Theta ) * ( CV_PI / 6.0 ); double RT = pow( avg_C, 7.0 ); RT = sqrt( RT / ( RT + 6103515625.0 ) ) * sin( delta_Theta ) * -2.0; // 6103515625 = 25^7 delta_L /= SL; delta_C /= SC; delta_H /= SH; return sqrt( delta_L * delta_L + delta_C * delta_C + delta_H * delta_H + RT * delta_C * delta_H ); } 

J'espère que ça aide quelqu'un 🙂

HSL et HSV sont meilleurs pour la perception de la couleur humaine. Selon Wikipedia :

Il est parfois préférable, en travaillant avec des matériaux artistiques, des images numérisées ou d’autres supports, d’utiliser le modèle de couleurs HSV ou HSL sur des modèles alternatifs tels que RVB ou CMJN, en raison des différences entre les modèles. RVB et CMJN sont respectivement des modèles additifs et soustractifs, modélisant la manière dont les lumières ou pigments de couleurs primaires (respectivement) se combinent pour former de nouvelles couleurs lorsqu’elles sont mélangées.

Représentation graphique du HSV

L’ article de Wikipedia sur les différences de couleur énumère un certain nombre d’espaces de couleur et de mesures de distance conçus pour s’accorder avec la perception humaine des distances de couleur.

Peut ressembler à du spam mais non, ce lien est vraiment intéressant pour les espaces de couleur 🙂

http://www.compuphase.com/cmesortingc.htm

La distance la plus simple serait bien sûr de simplement considérer les couleurs comme des vecteurs 3d provenant de la même origine et prenant la distance entre leurs extrémités.

Si vous devez tenir compte de facteurs tels que le vert est plus important dans l’évaluation de l’intensité, vous pouvez peser les valeurs.

ImageMagic fournit les échelles suivantes:

  • rouge: 0.3
  • vert: 0.6
  • bleu: 0.1

Bien sûr, des valeurs comme celle-ci ne seraient significatives que par rapport à d’autres valeurs pour d’autres couleurs, et non comme quelque chose qui aurait un sens pour les humains. Tout ce que vous pourriez utiliser comme valeurs serait donc un ordre de similitude.

Eh bien, en tant que premier sharepoint contact, je dirais que les mésortingques communes HSV (Hue, Saturation et Value) ou HSL sont mieux représentatives de la façon dont les humains perçoivent la couleur que RVB ou CYMK. Voir HSL, HSV sur Wikipedia .

Je suppose naïvement que je tracerais les points dans l’espace HSL pour les deux couleurs et calculerais l’ampleur du vecteur de différence. Cependant, cela signifierait que le jaune vif et le vert vif seraient considérés comme aussi différents que le vert au vert foncé. Mais alors beaucoup considèrent le rouge et le rose deux couleurs différentes.

De plus, les vecteurs de différence dans la même direction dans cet espace de parameters ne sont pas égaux. Par exemple, l’œil humain capte mieux le vert que les autres couleurs. Un changement de teinte par rapport au vert de la même manière qu’un décalage par rapport au rouge peut sembler plus important. De même, un décalage de la saturation d’une petite quantité à zéro est la différence entre le gris et le rose, ailleurs le décalage serait la différence entre deux nuances de rouge.

Du sharepoint vue des programmeurs, vous devez tracer les vecteurs de différence, mais modifiés par une masortingce de proportionnalité qui ajusterait les longueurs en conséquence dans diverses régions de l’espace HSL – ce serait assez arbitraire et basé sur diverses idées de théorie des couleurs. être modifié assez arbitrairement en fonction de ce que vous vouliez appliquer à cela.

Mieux encore, vous pourriez voir si quelqu’un a déjà fait une telle chose en ligne …

En tant que daltonien, je pense qu’il est bon d’essayer d’append plus de séparation que de vision normale. La forme la plus commune de daltonisme est la déficience en rouge / vert. Cela ne signifie pas que vous ne pouvez pas voir le rouge ou le vert, cela signifie qu’il est plus difficile de voir et plus difficile de voir les différences. Il faut donc une plus grande séparation avant qu’une personne daltonienne puisse faire la différence.