Followup: Die Suche nach einem genauen „Abstand“ zwischen den Farben

stimmen
44

Original Question

Ich bin für eine Funktion, die zu quantifizieren versucht, wie „weit entfernt“ (oder verschiedene) zwei Farben sind. Diese Frage ist wirklich in zwei Teilen:

  1. Welcher Farbraum repräsentiert am besten die menschliche Auge?
  2. Welche Distanzmetrik in diesem Raum repräsentiert am besten die menschliche Auge (euklidische?)
Veröffentlicht am 04/08/2008 um 16:08
quelle vom benutzer
In anderen Sprachen...                            


8 antworten

stimmen
43

Konvertieren in La * b * (auch bekannt als einfach nur „Lab“, und Sie werden auch sehen Verweis auf „CIELAB“). Eine gute schnelle measaure der Farbunterschied

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

Farbe Wissenschaftler haben andere verfeinerte Maßnahmen, die es nicht wert sein kann, die Mühe, je nach Genauigkeit benötigt für das, was Sie tun.

Die aund bWerte repräsentieren gegenüberliegende Farben in einer Art und Weise ähnlich, wie Kegel arbeiten und kann negativ oder positiv sein. Neutrale Farben - weiß, grau sind a=0, b=0. Das List die Helligkeit in einer bestimmten Art und Weise definiert ist , von Null (reiner Dunkelheit) bis zu was auch immer.

Crude Erklärung: >> Bei einer Farbe, die Augen unterscheiden zwischen zwei breiten Wellenlängenbereichen - Blau vs längeren Wellenlängen. und dann, dank einer neueren genetischen Mutation, der längere Wellenlänge Kegel in zwei gegabelt, für uns die Unterscheidung gegenüber grün rot.

By the way, es wird groß sein für Ihre Karriere über Ihrer Farbe Caveman collegues steigen, die nur wissen von „RGB“ oder „CMYK“, die für Geräte sind groß, aber für ernsthafte Wahrnehmung Arbeit saugen. Ich habe für die Bildgebung Wissenschaftler gearbeitet, die nichts über diese Dinge wussten!

Für mehr Spaß auf Farbdifferenztheorie zu lesen, versuchen Sie:

Weitere Einzelheiten zu Lab bei http://en.kioskea.net/video/cie-lab.php3 kann ich zu diesem Zeitpunkt nicht eine nicht-hässliche Seite finden, der die Umrechnungsformeln tatsächlich hatte , aber ich bin sicher , dass jemand diese bearbeiten wird Antwort eines aufzunehmen.

Beantwortet am 16/09/2008 um 17:08
quelle vom benutzer

stimmen
8

als cmetric.htm Link für mich oben scheiterte, wie auch viele andere Implementierungen für Farbabstand fand ich (nach einem sehr langen jurney ..) , wie der besten Farbabstand zu berechnen, und .. wissenschaftlich genau ein: deltaE und 2 (!) RGB - Werte mit OpenCV:

Dies erforderte 3 Farbraumumwandlungen + einige Code Konvertierung von JavaScript ( http://svn.int64.org/viewvc/int64/colors/colors.js ) bis C ++

Und schließlich der Code (scheint direkt aus der Box zu arbeiten, hofft, dass niemand da einen schwerwiegenden Fehler findet ... aber es scheint, nach einer Reihe von Tests in Ordnung)

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/photo/photo.hpp>
#include <math.h>

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 );
}

Hoffe, dass es jemand hilft :)

Beantwortet am 17/10/2013 um 02:39
quelle vom benutzer

stimmen
4

HSL und HSV ist besser für die menschliche Farbwahrnehmung. Laut Wikipedia :

Es ist manchmal bevorzugt, bei der Arbeit mit Kunstmaterialien, digitalisierte Bilder oder andere Medien, die HSV oder HSL-Farbmodell über alternative Modelle zu verwenden, wie RGB oder CMYK, wegen der Unterschiede in der Art und Weise die Modelle emulieren, wie Menschen Farbe wahrnehmen. RGB und CMYK sind additive und subtraktiven Modelle bzw. die Art und Weise modelliert, dass die primären Farblichter oder Pigmente (jeweils) kombinieren, um neue Farben zu bilden, wenn sie gemischt werden.

Grafische Darstellung des HSV

Beantwortet am 04/08/2008 um 16:16
quelle vom benutzer

stimmen
3

Der Wikipedia - Artikel über Farbunterschiede führt eine Reihe von Farbräumen und Abstandsmetriken entwickelt , um mit dem menschlichen Wahrnehmung von Farbabständen zu vereinbaren.

Beantwortet am 24/08/2008 um 16:38
quelle vom benutzer

stimmen
2

Als jemand, der ist farbenblind Ich glaube, es ist gut zu versuchen, mehr Trennung dann normale Sicht hinzuzufügen. Die häufigste Form der Farbenblindheit ist rot / grün-Mangel. Es bedeutet nicht, dass Sie nicht rot oder grün sehen können, bedeutet dies, dass es schwieriger ist, zu sehen und mehr schwierig, die Unterschiede zu sehen. So ist es eine größere Trennung vor einem farbenblind Person nimmt kann den Unterschied erkennen.

Beantwortet am 16/09/2008 um 17:45
quelle vom benutzer

stimmen
2

Nun, als erste Anlaufstelle, würde ich die gemeinsamen Metriken sagt HSV (Farbton, Sättigung und Wert) oder HSL ist besser repräsentativ dafür , wie Menschen wahrnehmen Farbe als sagen RGB oder CMYK. Siehe HSL, HSV auf Wikipedia .

Ich nehme an naiv würde ich die Punkte in dem HSL Raum für die beiden Farben zeichnen und die Größe des Differenzvektors berechnen. Dies würde jedoch bedeuten, dass leuchtend gelb und leuchtend grün genauso unterschiedlich wie grün bis dunkelgrün betrachtet werden würde. Aber dann viele als rot und rosa zwei verschiedene Farben.

Außerdem Differenzvektoren in der gleichen Richtung in diesem Parameterraum sind nicht gleich. Zum Beispiel nimmt das menschliche Auge grün viel besser als andere Farben. Eine Verschiebung im Farbton von Grün um den gleichen Betrag als eine Verschiebung von Rot kann größer sein scheint. Auch eine Verschiebung der Sättigung von einer kleinen Menge auf Null ist der Unterschied zwischen grau und rosa, die sonst die Verschiebung würde die Differenz zwischen zwei Farben rot sein.

Von einem Programmierer Sicht müssten Sie die Differenzvektoren zeichnen, sondern durch eine Proportionalität Matrix modifiziert, dass die Längen entsprechend in verschiedenen Regionen des HSL Raum einstellen würde - das wäre ziemlich willkürlich und würde auf verschiedene Farbtheorie Ideen beruhen, sondern werden ziemlich willkürlich gezwickt je nachdem, was Sie dies anwenden wollte.

Noch besser ist, konnte man sehen, ob jemand bereits online so etwas getan ...

Beantwortet am 04/08/2008 um 16:37
quelle vom benutzer

stimmen
2

Die einfachste Strecke wäre natürlich nur die Farben , wie 3D - Vektoren , die aus dem gleichen Ursprung Ursprung zu betrachten, und den Abstand zwischen ihren Endpunkten nehmen.

Wenn Sie solche Faktoren berücksichtigen müssen, dass grüne prominenteren bei der Beurteilung Intensität ist, können Sie die Werte wiegen.

ImageMagick bietet die folgenden Skalen:

  • rot: 0.3
  • grün: 0,6
  • blau: 0,1

Natürlich wäre wie diese Werte nur in Bezug auf andere Werte für andere Farben sinnvoll sein, nicht als etwas, das den Menschen von Bedeutung sein würde, also alles, was Sie die Werte verwenden könnte für similiarity Ordnung sein würde.

Beantwortet am 04/08/2008 um 16:14
quelle vom benutzer

stimmen
2

aussehen wie Spam kann aber nein, dieser Link ist wirklich interessant für Farbräume :)

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

Beantwortet am 04/08/2008 um 16:14
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more