Frage

Ursprüngliche Frage

Ich bin auf der Suche nach einer Funktion, die versucht zu quantifizieren, wie "fern" (oder deutlich) zwei Farben.Diese Frage besteht eigentlich aus zwei teilen:

  1. Welche Farbe Raum, die am besten für die menschliche vision?
  2. Welche Distanz-Metrik in diesem Raum am besten repräsentiert menschlichen vision (euklidischen?)
War es hilfreich?

Lösung

Konvertieren La*b* - (aka einfach nur "Labor", und Sie sehen auch der Verweis auf die "CIELAB").Eine gute, schnelle measaure Farbe Unterschied

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

Farbe Wissenschaftler haben andere mehr verfeinert Maßnahmen, die möglicherweise nicht die Mühe Wert, je nach der Genauigkeit für das, was du tust.

Die a und b Werte repräsentieren die gegensätzlichen Farben in einer Art und Weise ähnlich wie die Kegel arbeiten, und können positiv oder negativ sein.Neutrale Farben - weiß, Graustufen a=0,b=0.Die L ist die Helligkeit definiert, die in einer bestimmten Art und Weise, von null (Reine Dunkelheit) bis zu was auch immer.

Rohöl Erklärung :>> Gegeben ist eine Farbe, unsere Augen unterscheiden zwischen zwei weite Bereiche der Wellenlängen - blau vs längeren Wellenlängen.und dann, durch eine neuere genetische mutation, die längere Wellenlänge Kegel gegabelt in zwei, wobei für uns rote vs.grün.

Durch die Weg, es wird groß sein für Ihre Karriere nach oben steigen Ihre Farbe caveman Kollegen, die kennen nur "RGB" oder "CMYK", die sich hervorragend für Geräte, sondern saugen für schwere Wahrnehmung arbeiten.Ich habe mir für imaging-Wissenschaftler, die nicht wissen, eine Sache über dieses Zeug!

Für mehr Spaß beim Lesen auf Farbe Unterschied zu Theorie ist, versuchen Sie:

Mehr Details Lab http://en.kioskea.net/video/cie-lab.php3 Ich kann nicht zu diesem Zeitpunkt eine nicht-hässliche Seite, dass tatsächlich hatte der conversion-Formeln, aber ich bin sicher, jemand wird, Bearbeiten Sie diese Antwort, um.

Andere Tipps

als cmetric.htm link oben fehlgeschlagen ist für mich, wie auch viele andere Implementierungen für Farbe Entfernung, die ich gefunden (nach sehr langer jurney..) wie zu berechnen die beste Farbe Entfernung, und ..die meisten wissenschaftlich korrekt ein: Delta E und aus 2 RGB (!) Werte mit OpenCV:

Dieser benötigt 3 color space conversions + einige code-Konvertierung von javascript (http://svn.int64.org/viewvc/int64/colors/colors.js) C++

Und schließlich der code (scheint zu funktionieren direkt aus der box, hoffe, niemand findet einen schweren bug gibt es ...aber es scheint gut, nach einer Reihe von tests)

#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 es hilft jemandem :)

HSL-und HSV sind besser für den menschlichen Farbwahrnehmung.Nach Wikipedia:

Es ist manchmal vorzuziehen, in Zusammenarbeit mit Kunst-Materialien, digitalisierte Bilder oder andere Medien zu verwenden, die HSV-oder HSL-Farbmodell über alternative Modelle wie RGB oder CMYK, aufgrund der Unterschiede in den Möglichkeiten, die Modelle emulieren, wie Menschen Farbe wahrnehmen.RGB und CMYK sind additive und subtraktive Modelle, die jeweils die Modellierung der Weise, dass die primäre Farbe Lichter oder Pigmente (jeweils) kombinieren, um neue Farben angerührt.

Graphical depiction of HSV

Die Wikipedia-Artikel über Farbe Unterschiede listet eine Anzahl von Farbräumen und Distanz-Metriken entwickelt, um Stimmen mit der menschlichen Wahrnehmung von Farbe Entfernungen.

Aussehen wie spam, aber keine, dieser link ist wirklich interessant für Farbräume :)

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

Die einfachste Entfernung wäre natürlich zu einfach betrachten Sie die Farben als 3d-Vektoren, die aus der gleichen Herkunft, und wobei der Abstand zwischen den end-Punkten.

Wenn Sie brauchen, um zu überlegen, wie Faktoren, die grünen mehr im Vordergrund bei der Beurteilung der Intensität können Sie die Abwägung der Werte.

ImageMagic bietet die folgenden Tonleitern:

  • rot:0.3
  • grün:0.6
  • blau:0.1

Natürlich sind Werte wie diese wäre nur sinnvoll in Bezug zu anderen Werten für die anderen Farben, nicht als etwas, das wäre sinnvoll, um Menschen, damit alle Sie könnte verwenden die Werte, für die wäre similiarity Bestellung.

Nun, als erste Anlaufstelle würde ich sagen, dass die gemeinsame Metriken HSV (Farbton, Sättigung und Wert) oder HSL besser sind Vertreter wie Menschen Farbe wahrnehmen als beispielsweise RGB oder CYMK.Finden HSL, HSV bei Wikipedia.

Ich nehme an, naiv ich würde zeichnen Sie die Punkte in der HSL-Raum für die zwei Farben und die Berechnung der Größenordnung der Unterschied vector.Dies würde jedoch bedeuten, dass helles gelb und helles grün als wäre genauso unterschiedlich wie grün bis dunkelgrün.Dann aber von vielen als rot und rosa zwei verschiedenen Farben.

Darüber hinaus Unterschied Vektoren in die gleiche Richtung in diesem parameter wird der Raum nicht gleich sind.Zum Beispiel, das menschliche Auge nimmt grün viel besser als andere Farben.Eine Verschiebung Farbton von grün um den gleichen Betrag wie eine Verschiebung von rot kann scheinen größer.Auch eine Verschiebung in der Sättigung von eine kleine Menge auf null ist der Unterschied zwischen Grau und rosa, sonst die Verschiebung wäre, dass der Unterschied zwischen zwei Schattierungen von rot.

Aus Programmierer Sicht, würden Sie brauchen, um eine Darstellung der Differenz von Vektoren, aber modifiziert durch eine Verhältnismäßigkeit matrix, die würden passen Sie die Längen entsprechend in verschiedenen Regionen der HSL-Raum - wäre dies ziemlich willkürlich und würde werden basierend auf verschiedenen Farbenlehre Ideen, sondern optimiert werden ziemlich willkürlich je nachdem, was Sie wollten, um diese anwenden zu können.

Noch besser, Sie könnten sehen, ob jemand das schon gemacht hat, wie ein Ding online...

Als jemand, der farbenblind ist, ich glaube, es ist gut, zu versuchen, fügen Sie weitere Trennung dann normal vision.Die häufigste form der Farbenblindheit ist der rot/grün-Schwäche.Es bedeutet nicht, dass Sie können nicht sehen rot oder grün ist, bedeutet dies, dass es ist schwieriger zu finden und schwieriger, die Unterschiede zu erkennen.So dauert es eine größere Trennung bevor eine Farbe blinde person kann sagen, der Unterschied.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top