language agnostic अनुवर्ती: रंगों के बीच एक सटीक "दूरी" ढूंढना




संयुक्त राज्य अमेरिका दर्शनीय स्थल (7)

मूल प्रश्न

मैं एक समारोह की तलाश कर रहा हूं जो यह निर्धारित करने का प्रयास करता है कि कैसे "दूर" (या अलग) दो रंग हैं यह प्रश्न वास्तव में दो भागों में है:

  1. क्या रंग अंतरिक्ष सबसे अच्छा मानव दृष्टि का प्रतिनिधित्व करता है?
  2. उस अंतरिक्ष में कितनी दूरी की मीट्रिक मानव दृष्टि (यूक्लिडियन?) का प्रतिनिधित्व करती है

रंग अंतर पर विकिपीडिया लेख रंग की दूरी के मानव धारणा से सहमत होने के लिए डिज़ाइन किए गए कई रंगीन रिक्त स्थान और दूरी मीट्रिक सूचीबद्ध करता है।


ला * बी * (उर्फ सिर्फ सादे "लैब" में कनवर्ट करें, और आप "सीआईईएलब्लैब" का भी संदर्भ देखेंगे) रंग अंतर का एक अच्छा त्वरित आकार है

(एल 1-एल 2) ^ 2 + (ए 1-ए 2) ^ 2 + (बी 1-बी 2) ^ 2

रंगीन वैज्ञानिकों के पास और अधिक परिष्कृत उपाय हैं, जो कि परेशान होने के योग्य नहीं हो सकते हैं, जो कि आप क्या कर रहे हैं इसके लिए आवश्यक सटीकता के आधार पर।

a और b वैल्यू का प्रतिनिधित्व करता है कि कैसे शंकु काम करता है, और नकारात्मक या सकारात्मक हो सकता है के समान तरीके में रंगों का विरोध करते हैं। तटस्थ रंग - सफेद, ग्रेज़ हैं a=0 , b=0 L एक विशिष्ट तरीके से परिभाषित चमक है, शून्य से (शुद्ध अंधेरा) जो भी हो

क्रूड स्पष्टीकरण: >> एक रंग को देखते हुए, हमारी आँखें तरंग दैर्ध्य की दो व्यापक श्रेणियों के बीच भेद करती हैं- नीले बनाम लंबे तरंग दैर्ध्य। और फिर, एक अधिक हाल ही में आनुवंशिक उत्परिवर्तन के लिए धन्यवाद, लंबे समय तक तरंग दैर्ध्य शंकु दो में विभाजित, हमारे लिए लाल बनाम हरे रंग की भेद।

वैसे, आपके कैरियर के लिए बहुत अच्छा होगा कि आपके रंग के गुफाओं वाले शिलालेखों से ऊपर उठ जाए जो केवल "आरजीबी" या "सीएमवाइके" के बारे में जानते हैं जो उपकरणों के लिए बहुत अच्छा है लेकिन गंभीर धारणा काम के लिए चूसना। मैंने इमेजिंग वैज्ञानिकों के लिए काम किया है जो इस सामान के बारे में कुछ नहीं जानते थे!

रंग अंतर सिद्धांत पर अधिक मजेदार पढ़ने के लिए, कोशिश करें:

Http://en.kioskea.net/video/cie-lab.php3 पर लैब के बारे में और अधिक जानकारी मैं इस समय एक गैर बदसूरत पृष्ठ नहीं खोज सकता था, जिसकी वास्तव में रूपांतरण सूत्र थे, लेकिन मुझे यकीन है कि कोई इसे संपादित करेगा एक को शामिल करने के लिए जवाब


स्पैम की तरह लग सकता है लेकिन नहीं, यह लिंक रंग रिक्त स्थान के लिए वास्तव में दिलचस्प है :)

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


सबसे आसान दूरी निश्चित रूप से रंगों को उसी मूल से शुरु होने वाले 3 डी वैक्टर के रूप में मानते हैं, और उनके अंत बिंदुओं के बीच की दूरी लेते हैं।

अगर आपको इस तरह के कारकों पर विचार करना होगा कि ग्रीन तीव्रता को पहचानने में अधिक प्रमुख है, तो आप मूल्यों को वज़न कर सकते हैं।

इमेजमैजिक निम्नलिखित स्केल प्रदान करता है:

  • लाल: 0.3
  • हरा: 0.6
  • नीला: 0.1

बेशक, इस तरह के मूल्यों को अन्य रंगों के अन्य मूल्यों के संबंध में केवल सार्थक ही होगा, न कि किसी चीज़ के रूप में जो मनुष्य के लिए सार्थक होगा, इसलिए सभी के लिए आप मूल्यों का इस्तेमाल कर सकते हैं समानता क्रम होगा


खैर, कॉल के पहले बिंदु के रूप में, मैं सामान्य मीट्रिक एचएसवी (ह्यू, संतृप्ति और मान) या एचएसएल के बारे में कहूंगा कि मानव कैसे आरजीबी या सीवायएमके की तुलना में रंग मानते हैं। विकिपीडिया पर एचएसएल, एचएसवी देखें

मैं समझता हूं कि मैं दो रंगों के लिए एचएसएल स्पेस में अंक साजिश करूँगा और अंतर वेक्टर की परिमाण की गणना करेगा। हालांकि इसका मतलब यह होगा कि उज्ज्वल पीला और उज्ज्वल हरे रंग को ग्रीन हरे रंग से भिन्न के रूप में समझा जाएगा। लेकिन फिर कई लाल और गुलाबी दो अलग-अलग रंगों पर विचार करते हैं।

इसके अलावा, इस पैरामीटर अंतरिक्ष में एक ही दिशा में अंतर वैक्टर बराबर नहीं हैं। उदाहरण के लिए, मानवीय आँख अन्य रंगों की तुलना में हरे रंग को बेहतर करता है लाल रंग से बदलाव के रूप में एक ही राशि से हरे रंग के रंग में बदलाव पा सकते हैं। इसके अलावा एक छोटी राशि से शून्य में संतृप्ति में एक बदलाव ग्रे और गुलाबी के बीच का अंतर है, कहीं और शिफ्ट लाल के दो रंगों के बीच का अंतर होगा।

प्रोग्रामर के दृष्टिकोण से, आपको अंतर वैक्टर को साजिश करने की ज़रूरत होगी, लेकिन आनुपातिकता मैट्रिक्स द्वारा संशोधित किया जाएगा जो एचएसएल अंतरिक्ष के विभिन्न क्षेत्रों में तदनुसार समायोजित करेगा - यह काफी मनमाना होगा और विभिन्न रंग सिद्धांत विचारों पर आधारित होगा लेकिन आप इस पर लागू करने के लिए क्या करना चाहते थे, इसके आधार पर काफी मनमाने ढंग से छेड़छाड़ कीजिए।

इससे भी बेहतर, आप देख सकते हैं कि किसी ने पहले से ही ऐसा ऑनलाइन किया है ...


एचएसएल और एचएसवी मानव रंग धारणा के लिए बेहतर है। विकिपीडिया के अनुसार:

आरजीबी या सीएमवायके जैसे वैकल्पिक मॉडल जैसे एचएसवी या एचएसएल रंग मॉडल का उपयोग करने के लिए कला सामग्री, डिजीटल छवियों या अन्य मीडिया के साथ काम करने में कभी-कभी बेहतर होता है, क्योंकि ऐसे तरीके में मतभेद के कारण मॉडल का अनुकरण करते हैं कि लोग कैसे मानते हैं। आरजीबी और सीएमवाइके क्रमशः जोड़ और सूक्ष्म मॉडल होते हैं, जो कि प्राथमिक रंगीन रोशनी या रंगद्रव्य (क्रमशः) मिश्रण करते समय मिश्रित होते हैं,


जैसा कि ऊपर cmetric.htm लिंक मेरे लिए विफल रहा है, साथ ही साथ रंग दूरी के लिए कई अन्य कार्यान्वयन (बहुत लंबे जर्नी के बाद)। सर्वोत्तम रंग दूरी की गणना कैसे की जाती है, और .. सबसे वैज्ञानिक रूप से सटीक एक: डेलटाए और 2 से OpenCV का उपयोग करते हुए आरजीबी (!) मान:

यह आवश्यक 3 रंगीन स्थान रूपांतरण + जावास्क्रिप्ट से कुछ कोड रूपांतरण ( http://svn.int64.org/viewvc/int64/colors/colors.js ) को C ++

और अंत में कोड (सही बॉक्स से बाहर काम करने लगता है, उम्मीद है कि कोई भी वहाँ एक गंभीर बग नहीं खोजता है ... लेकिन यह कई परीक्षणों के बाद ठीक लगता है)

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

आशा है कि यह किसी को मदद करता है :)





colors