आरजीबी रंग की चमक का निर्धारण करने के लिए सूत्र


387

आरजीबी मूल्यों को देखते हुए एक रंग की चमक का निर्धारण करने के लिए मैं किसी प्रकार के सूत्र या एल्गोरिथ्म की तलाश कर रहा हूं। मुझे पता है कि यह आरजीबी मूल्यों को एक साथ जोड़ने और उच्च रकम होने के रूप में सरल नहीं हो सकता है, लेकिन मुझे नुकसान है कि मैं कहाँ से शुरू करूं।


8
परसेंट ब्राइटनेस है जो मुझे लगता है कि मैं ढूंढ रहा हूं, धन्यवाद।
रोबमेरिका

2
एक अच्छा लेख है ( .NET - भाग 1 में रंग हेरफेर ) उन दोनों के बीच सिद्धांत और कोड (C #) सहित रंग रिक्त स्थान और वार्तालाप के बारे में। उत्तर के लिए लेख में मॉडल विषय के बीच रूपांतरण देखें।
underscore

4
मैं बहुत सालों से सदस्य हूं, और मैंने ऐसा पहले कभी नहीं किया। क्या मेरा सुझाव है कि आप उत्तरों की समीक्षा करें और फिर से विचार करें कि कौन सा स्वीकार करना है?
जिवे डैडसन

जवाबों:


455

क्या आपका मतलब चमक है? परसेंट ब्राइटनेस? Luminance?

  • चमक (कुछ रंग स्थानों के लिए मानक): (0.2126*R + 0.7152*G + 0.0722*B) [१]
  • ल्यूमिनेन्स (कथित विकल्प 1): (0.299*R + 0.587*G + 0.114*B) [२]
  • ल्यूमिनेन्स (कथित विकल्प 2, गणना करने के लिए धीमा): sqrt( 0.241*R^2 + 0.691*G^2 + 0.068*B^2 )sqrt( 0.299*R^2 + 0.587*G^2 + 0.114*B^2 )( @MatthewHerbst के लिए धन्यवाद ) [3]

26
ध्यान दें कि ये दोनों शारीरिक पहलुओं पर जोर देते हैं: मानव नेत्र हरे रंग की रोशनी के लिए सबसे अधिक संवेदनशील है, लाल से कम और नीले से कम।
बॉब क्रॉस

16
ध्यान दें कि ये सभी शायद रेखीय 0-1 आरजीबी के लिए हैं, और आपके पास शायद गामा-सही 0-255 आरजीबी है। वे ऐसे रूपांतरित नहीं होते जैसे आप सोचते हैं कि वे हैं।
एलेक्स अजीब

4
गलत। रैखिक परिवर्तन को लागू करने से पहले, किसी को पहले रंग स्थान के लिए गामा फ़ंक्शन के व्युत्क्रम को लागू करना चाहिए। फिर रैखिक फ़ंक्शन को लागू करने के बाद, गामा फ़ंक्शन लागू किया जाता है।
जीव डडसन

6
अंतिम सूत्र में, क्या यह (0.299 * R) ^ 2 है या यह 0.299 * (R ^ 2) है?
कैसर सोज़े

3
@KaizerSozay जैसा कि यहां लिखा गया है, इसका मतलब होगा 0.299*(R^2)(क्योंकि घातांक गुणा से पहले हो जाता है)
दांतेवग

298

मुझे लगता है कि आप जो खोज रहे हैं वह RGB -> Luma रूपांतरण सूत्र है।

फोटोमेट्रिक / डिजिटल ITU BT.709 :

Y = 0.2126 R + 0.7152 G + 0.0722 B

डिजिटल ITU BT.601 (आर और बी घटकों के लिए अधिक वजन देता है):

Y = 0.299 R + 0.587 G + 0.114 B

यदि आप पूर्णता के लिए सटीकता का व्यापार करने के इच्छुक हैं, तो इसके लिए दो सन्निकटन सूत्र हैं:

Y = 0.33 R + 0.5 G + 0.16 B

Y = 0.375 R + 0.5 G + 0.125 B

इनकी गणना जल्दी से की जा सकती है

Y = (R+R+B+G+G+G)/6

Y = (R+R+R+B+G+G+G+G)>>3

47
मुझे यह पसंद है कि आप सटीक मान रखते हैं, लेकिन इसमें एक त्वरित "करीब पर्याप्त" प्रकार का शॉर्टकट भी शामिल है। +1।
बस्का

3
@ जोनाथन ड्यूमाइन - दो त्वरित गणना सूत्र, दोनों में नीले शामिल हैं - पहला एक (2 * लाल + Blue+ 3 * हरा) / 6, 2 दूसरा है (3 * लाल + Blue+ 4 * हरा) >> 3। प्रदान किया गया, दोनों त्वरित सन्निकटन में, ब्लू का वजन सबसे कम है, लेकिन यह अभी भी वहां है।
फ्रेंकी पेनोव

84
@JonathanDumaine यह इसलिए है क्योंकि मानव की आंख नीली के लिए सबसे कम है
;;

4
क्विक वर्जन अच्छा काम करता है। हजारों उपयोगकर्ताओं के साथ वास्तविक दुनिया के ऐप पर परीक्षण किया गया और लागू किया गया, सब कुछ ठीक लग रहा है।
मील के पत्थर

10
यदि आप इसे करते हैं तो त्वरित संस्करण और भी तेज है: Y = (R<<1+R+G<<2+B)>>3(एआरएम पर केवल 3-4 सीपीयू चक्र) लेकिन मुझे लगता है कि एक अच्छा संकलक आपके लिए यह अनुकूलन करेगा।
rjmunro

105

मैंने स्वीकृत उत्तर में तीन एल्गोरिदम की तुलना की है। मैंने चक्र में रंग उत्पन्न किए जहां केवल हर 400 वें रंग का उपयोग किया गया था। प्रत्येक रंग को 2x2 पिक्सेल द्वारा दर्शाया जाता है, रंगों को सबसे गहरे से हल्के (बाएं से दाएं, ऊपर से नीचे) में क्रमबद्ध किया जाता है।

पहली तस्वीर - प्रकाश (रिश्तेदार)

0.2126 * R + 0.7152 * G + 0.0722 * B

दूसरी तस्वीर - http://www.w3.org/TR/AERT#color-contrast

0.299 * R + 0.587 * G + 0.114 * B

तीसरी तस्वीर - एचएसपी कलर मॉडल

sqrt(0.299 * R^2 + 0.587 * G^2 + 0.114 * B^2)

चौथी तस्वीर - डब्ल्यूसीएजी 2.0 एससी 1.4.3 सापेक्ष चमक और विपरीत अनुपात फार्मूला (देखें सिन्क्रो का जवाब यहां देखें) )

एक पंक्ति में रंगों की संख्या के आधार पर पैटर्न को कभी-कभी पहली और दूसरी तस्वीर पर देखा जा सकता है। मैंने कभी भी 3 या 4 के एल्गोरिथ्म से चित्र पर कोई पैटर्न नहीं देखा।

अगर मुझे चुनना था तो मैं एल्गोरिथम नंबर 3 के साथ जाऊंगा क्योंकि इसे लागू करने में बहुत आसान है और इसके 4 जी की तुलना में लगभग 33% तेज है।

Perceived चमक एल्गोरिथ्म तुलना


3
मेरे लिए यह सबसे अच्छा उत्तर है क्योंकि oyu एक चित्र पैटर्न का उपयोग करता है जो आपको यह बताता है कि क्या अलग-अलग hues को समान luminance के साथ प्रस्तुत किया गया है। मेरे और मेरे वर्तमान मॉनिटर के लिए तीसरी तस्वीर "सबसे अच्छी लग रही" है क्योंकि यह भी तेज है तो 4 है कि एक प्लस
कॉफ़ीड्यूलेटर

8
आपकी तुलना छवि गलत है क्योंकि आपने सभी फ़ंक्शन को सही इनपुट प्रदान नहीं किया है। पहले फ़ंक्शन को रैखिक आरजीबी इनपुट की आवश्यकता होती है ; मैं केवल nonlinear (यानी गामा-सही) RGB प्रदान करके बैंडिंग प्रभाव को पुन: उत्पन्न कर सकता हूं । इस समस्या को ठीक करते हुए, आपको कोई बैंडिंग कलाकृतियां नहीं मिलती हैं और 1 फ़ंक्शन स्पष्ट विजेता है।
अधिकतम

1
@ ^2और sqrtतीसरे सूत्र में शामिल किया गया है और इसके बजाय गैर-रैखिक आरजीबी से रैखिक आरजीबी का अनुमान लगाने का एक तेज़ तरीका है ^2.2और ^(1/2.2)यह अधिक सही होगा। लीनियर के बजाय नॉनलाइनियर इनपुट का उपयोग करना दुर्भाग्य से बेहद आम है।
मार्क रैनसम

53

नीचे sRGB छवियों को परिवर्तित करने के लिए एकमात्र सुधार एल्गोरिदम है, जैसा कि ब्राउज़र आदि में उपयोग किया जाता है, ग्रेस्केल तक।

आंतरिक उत्पाद की गणना करने से पहले रंग स्थान के लिए गामा फ़ंक्शन के व्युत्क्रम को लागू करना आवश्यक है। फिर आप कम मान पर गामा फ़ंक्शन लागू करते हैं। गामा फ़ंक्शन को शामिल करने में विफलता के परिणामस्वरूप 20% तक की त्रुटियां हो सकती हैं।

सामान्य कंप्यूटर सामान के लिए, रंग स्थान sRGB है। SRGB के लिए सही संख्या लगभग है। 0.21, 0.72, 0.07। SRGB के लिए गामा एक मिश्रित कार्य है जो 1 / (2.2) द्वारा घातांक का अनुमान लगाता है। यहाँ C ++ में पूरी बात है।

// sRGB luminance(Y) values
const double rY = 0.212655;
const double gY = 0.715158;
const double bY = 0.072187;

// Inverse of sRGB "gamma" function. (approx 2.2)
double inv_gam_sRGB(int ic) {
    double c = ic/255.0;
    if ( c <= 0.04045 )
        return c/12.92;
    else 
        return pow(((c+0.055)/(1.055)),2.4);
}

// sRGB "gamma" function (approx 2.2)
int gam_sRGB(double v) {
    if(v<=0.0031308)
        v *= 12.92;
    else 
        v = 1.055*pow(v,1.0/2.4)-0.055;
    return int(v*255+0.5); // This is correct in C++. Other languages may not
                           // require +0.5
}

// GRAY VALUE ("brightness")
int gray(int r, int g, int b) {
    return gam_sRGB(
            rY*inv_gam_sRGB(r) +
            gY*inv_gam_sRGB(g) +
            bY*inv_gam_sRGB(b)
    );
}

5
यह उसी तरह है जैसे sRGB को परिभाषित किया गया है। मुझे लगता है कि इसका कारण यह है कि यह शून्य के पास कुछ संख्यात्मक समस्याओं से बचा जाता है। यदि आप केवल 2.2 और 1 / 2.2 की संख्या के लिए संख्या बढ़ाते हैं तो इससे बहुत अंतर नहीं पड़ेगा।
जीव डडसन

8
जेएमडी - एक दृश्य धारणा प्रयोगशाला में काम के हिस्से के रूप में, मैंने सीआरटी मॉनिटर पर प्रत्यक्ष ल्यूमिनेंस माप किया है और यह पुष्टि कर सकता है कि मूल्यों की सीमा के नीचे ल्यूमिनेंस का एक रैखिक क्षेत्र है।
जेरी फेडरस्पिल

2
मुझे पता है कि यह बहुत पुराना है, लेकिन अभी भी इसे खोजा जाना बाकी है। मुझे नहीं लगता कि यह सही हो सकता है। ग्रे (255,255,255) नहीं होना चाहिए = ग्रे (255,0,0) + ग्रे (0,255,0) + ग्रे (0,0,255)? यह नहीं है
DCBillen

2
@DCBillen: नहीं, चूंकि मान गैर-रैखिक गामा-सही sRGB स्थान में हैं, आप उन्हें जोड़ नहीं सकते। यदि आप उन्हें जोड़ना चाहते हैं, तो आपको gam_sRGB को कॉल करने से पहले ऐसा करना चाहिए।
rdb

1
@DCBillen Rdb सही है। उन्हें जोड़ने का तरीका फंक्शन int grey (int r, int g, int b) में दिखाया गया है, जो gam_sRGB को "अनकॉल" करता है। यह मुझे पीड़ा देता है कि चार साल बाद, सही उत्तर को इतना कम रेट किया गया है। :-) वास्तव में नहीं .. मैं इसे खत्म कर दूँगा।
जिव डडसन

45

"स्वीकृत" उत्तर गलत और अपूर्ण है

एकमात्र उत्तर जो सटीक हैं, वे हैं @ jive-dadson और @EddingtonsMonkey उत्तर और समर्थन @ nils-pipenbrinck में । अन्य उत्तर (स्वीकृत सहित) स्रोतों को जोड़ने या उद्धृत करने के लिए हैं जो या तो गलत हैं, अप्रासंगिक हैं, अप्रचलित हैं, या टूटे हुए हैं।

संक्षेप में:

  • sRGB को LINEARIZED होना चाहिएगुणांक लागू करने से पहले ।
  • ल्यूमिनेन्स (L या Y) प्रकाश के रूप में रैखिक है।
  • पेरिसेन्ड लाइटनेस (L *) नॉनलाइनियर है जैसा कि इंसानी धारणा है।
  • एचएसवी और एचएसएल धारणा के संदर्भ में दूर से भी सटीक नहीं हैं।
  • SRGB के लिए IEC मानक, 0.04045 की सीमा को निर्दिष्ट करता है, यह 0.03928 नहीं है (जो अप्रचलित शुरुआती मसौदे से था)।
  • उपयोगी हो (यानी धारणा के सापेक्ष) , यूक्लिडियन दूरियों को एक समान रूप से समान कार्टेशियन वेक्टर स्थान की आवश्यकता होती है जैसे कि CIELAB। sRGB एक नहीं है।

निम्नलिखित सही और पूर्ण उत्तर है:

क्योंकि यह धागा खोज इंजन में अत्यधिक दिखाई देता है, इसलिए मैं इस उत्तर को इस विषय पर विभिन्न भ्रांतियों को स्पष्ट करने के लिए जोड़ रहा हूँ।

चमक एक अवधारणात्मक विशेषता है, इसका सीधा माप नहीं है।

Perceived lightness को कुछ विज़न मॉडल जैसे CIELAB द्वारा मापा जाता है, यहाँ L * (Lstar) अवधारणात्मक लपट का एक उपाय है , और मानव दृष्टि को गैर-रेखीय प्रतिक्रिया वक्र से अनुमानित करने के लिए गैर-रैखिक है।

ल्यूमिनेन्स प्रकाश का एक रैखिक माप है, सामान्य दृष्टि के लिए स्पष्ट रूप से भारित होता है, लेकिन प्रकाश की गैर-रैखिक धारणा के लिए समायोजित नहीं किया जाता है।

Luma ( Y, Prime ) एक गामा एन्कोडेड, भारित संकेत है जिसका उपयोग कुछ वीडियो एन्कोडिंग में किया जाता है। यह रैखिक चमक के साथ भ्रमित नहीं होना है।

गामा या स्थानांतरण वक्र (TRC) एक वक्र है जो अक्सर अवधारणात्मक वक्र के समान होता है, और आमतौर पर कथित शोर को कम करने और / या डेटा उपयोग (और संबंधित कारणों) में सुधार के लिए भंडारण या प्रसारण के लिए छवि डेटा पर लागू होता है।

कथित हल्कापन निर्धारित करने के लिए , पहले परिवर्तित गामा रैखिक luminance (करने के लिए R'G'B' छवि मूल्यों इनकोडिंग Lया Y) और फिर गैर रेखीय कथित हल्कापन करने के लिए ( L*)


लुमिनेंस को खोजने के लिए:

... क्योंकि जाहिर है कि यह कहीं खो गया था ...

पहला कदम:

सभी sRGB 8 बिट पूर्णांक मानों को दशमलव 0.0-1.0 में बदलें

  vR = sR / 255;
  vG = sG / 255;
  vB = sB / 255;

दूसरा चरण:

एक गामा इनकोडिंग RGB को रैखिक मान में बदलें। उदाहरण के लिए sRGB (कंप्यूटर मानक) को लगभग V ^ 2.2 की शक्ति वक्र की आवश्यकता होती है, हालांकि "सटीक" परिवर्तन है:

रैखिक को sRGB

जहां V Where गामा-एनकोडेड R, G या B चैनल sRGB है।
स्यूडोकोड:

function sRGBtoLin(colorChannel) {
        // Send this function a decimal sRGB gamma encoded color value
        // between 0.0 and 1.0, and it returns a linearized value.

    if ( colorChannel <= 0.04045 ) {
            return colorChannel / 12.92;
        } else {
            return pow((( colorChannel + 0.055)/1.055),2.4));
        }
    }

तीसरा कदम:

Luminance (Y) को खोजने के लिए sRGB के लिए मानक गुणांक लागू करें:

गुणांक Y = R * 0.2126 + G * 0.7152 + B * 0.0722 लागू करें

उपरोक्त कार्यों का उपयोग करते हुए स्यूडोकोड:

Y = (0.2126 * sRGBtoLin(vR) + 0.7152 * sRGBtoLin(vG) + 0.0722 * sRGBtoLin(vB))

प्राप्त प्रकाश व्यवस्था के लिए:

चरण चार:

ऊपर से luminance Y लें, और L * में बदलें

L * Y समीकरण से
स्यूडोकोड:

function YtoLstar(Y) {
        // Send this function a luminance value between 0.0 and 1.0,
        // and it returns L* which is "perceptual lightness"

    if ( Y <= (216/24389) {       // The CIE standard states 0.008856 but 216/24389 is the intent for 0.008856451679036
            return Y * (24389/27);  // The CIE standard states 903.3, but 24389/27 is the intent, making 903.296296296296296
        } else {
            return pow(Y,(1/3)) * 116 - 16;
        }
    }

L * 0 (काला) से 100 (सफ़ेद) का मान है जहाँ 50 अवधारणात्मक "मध्य ग्रे" है। L * = 50 Y = 18.4 के बराबर है, या दूसरे शब्दों में एक 18% ग्रे कार्ड, एक फोटोग्राफिक एक्सपोज़र (Ansel Adams Zone V) के मध्य का प्रतिनिधित्व करता है।

संदर्भ:

IEC 61966-2-1:1999 Standard
Wikipedia sRGB
Wikipedia CIELAB
Wikipedia CIEXYZ
चार्ल्स पोयटन के गामा FAQ


@ रॉटम धन्यवाद - मैंने कुछ अजीब और अधूरे बयान देखे और महसूस किया कि यह इसे नीचे गिराने में मददगार होगा, विशेष रूप से यह धागा अभी भी खोज इंजन पर अत्यधिक रैंक करता है।
मयंडेक्स

मैंने BT.601 Luma और CIE 1976 L * अवधारणात्मक ग्रे की तुलना करते हुए एक प्रदर्शन बनाया , कुछ MATLAB कमांड का उपयोग करते हुए:Luma=rgb2gray(RGB);LAB=rgb2lab(RGB);LAB(:,:,2:3)=0;PerceptualGray=lab2rgb(LAB);
Rotem

@Myndex मैंने L * को प्राप्त करने के लिए आपके फॉर्मूले का उपयोग किया है, लेकिन मुझे अभी भी कुछ अजीब परिणाम मिलते हैं, जो भी सूत्र मैं उपयोग करता हूं ... आपके साथ, # d05858 का L * # c51c2a के L * की तुलना में गहरा है ... कोई है यह अधिकार पाने का तरीका? कोई फॉर्मूला उम्मीद के मुताबिक काम क्यों नहीं करता है? :(
शेजान

1
@asdfasdfads हाँ, L*a*b*कई मनोवैज्ञानिक विशेषताओं को ध्यान में नहीं रखता है। हेल्महोल्टज़-कोहलराश प्रभाव एक है, लेकिन कई अन्य हैं। CIELAB किसी भी तरह से "पूर्ण" छवि मूल्यांकन मॉडल नहीं है। अपनी पोस्ट में मैं मूल अवधारणाओं को पूरी तरह से कवर करने की कोशिश कर रहा था, जो कि बहुत गहरी मीनूटी में उतरे बिना संभव था। हंट मॉडल, फेयरचाइल्ड के मॉडल, और अन्य लोग अधिक पूर्ण कार्य करते हैं, लेकिन साथ ही साथ अधिक जटिल भी हैं।
Myndex

1
@ मेनडेक्स, कभी नहीं, मेरा कार्यान्वयन थकान-आधारित था और मेरे खराब परिणाम उसी से आए थे :( आपकी मदद के लिए बहुत बहुत धन्यवाद और आपका पोस्ट जो एक महान मूल्य का है!
sjahan

11

मुझे यह कोड मिला (C # में लिखा गया) जो एक रंग की "चमक" की गणना करने का एक उत्कृष्ट काम करता है। इस परिदृश्य में, कोड यह निर्धारित करने का प्रयास कर रहा है कि रंग के ऊपर सफेद या काला टेक्स्ट डालना है या नहीं।


1
ठीक वैसा ही जैसा मुझे चाहिए था। मैं एक क्लासिक "रंग सलाखों" डेमो कर रहा था, और उन्हें सबसे अच्छा काले या सफेद विकल्प के साथ रंग के ऊपर लेबल करना चाहता था!
रफुसवीस

10

दिलचस्प है, आरजीबी => एचएसवी के लिए यह सूत्रीकरण केवल v = MAX3 (आर, जी, बी) का उपयोग करता है। दूसरे शब्दों में, आप एचएसवी में वी के रूप में अधिकतम (आर, जी, बी) का उपयोग कर सकते हैं ।

मैंने Hearn & Baker के पृष्ठ 575 पर जाँच की और बताया कि वे "वैल्यू" की गणना कैसे करते हैं।

हर्न एंड बेकर से पृष्ठ 319


सिर्फ रिकॉर्ड के लिए लिंक मृत है, यहां पुरालेख संस्करण - web.archive.org/web/20150906055559/http://…
पीटर

एचएसवी अवधारणात्मक रूप से समान नहीं है (और यह करीब भी नहीं है)। इसका उपयोग केवल रंग को समायोजित करने के लिए "सुविधाजनक" तरीके के रूप में किया जाता है, लेकिन यह धारणा के लिए प्रासंगिक नहीं है, और वी एल या वाई (CIE Luminance) के वास्तविक मूल्य से संबंधित नहीं है।
Myndex

9

यहां उल्लिखित सूत्रों के यादृच्छिक चयन के बीच खो जाने के बजाय, मेरा सुझाव है कि आप डब्ल्यू 3 सी मानकों द्वारा अनुशंसित सूत्र के लिए जाएं।

यहाँ WCAG 2.0 SC 1.4.3 सापेक्ष प्रकाश और विपरीत अनुपात के सूत्रों का सीधा लेकिन सटीक PHP कार्यान्वयन है । यह उन मानों का उत्पादन करता है जो इस पृष्ठ पर, जैसे कि WCAG अनुपालन के लिए आवश्यक अनुपातों का मूल्यांकन करने के लिए उपयुक्त हैं , और यह किसी भी वेब ऐप के लिए उपयुक्त और उपयुक्त है। यह अन्य भाषाओं में पोर्ट करने के लिए तुच्छ है।

/**
 * Calculate relative luminance in sRGB colour space for use in WCAG 2.0 compliance
 * @link http://www.w3.org/TR/WCAG20/#relativeluminancedef
 * @param string $col A 3 or 6-digit hex colour string
 * @return float
 * @author Marcus Bointon <marcus@synchromedia.co.uk>
 */
function relativeluminance($col) {
    //Remove any leading #
    $col = trim($col, '#');
    //Convert 3-digit to 6-digit
    if (strlen($col) == 3) {
        $col = $col[0] . $col[0] . $col[1] . $col[1] . $col[2] . $col[2];
    }
    //Convert hex to 0-1 scale
    $components = array(
        'r' => hexdec(substr($col, 0, 2)) / 255,
        'g' => hexdec(substr($col, 2, 2)) / 255,
        'b' => hexdec(substr($col, 4, 2)) / 255
    );
    //Correct for sRGB
    foreach($components as $c => $v) {
        if ($v <= 0.04045) {
            $components[$c] = $v / 12.92;
        } else {
            $components[$c] = pow((($v + 0.055) / 1.055), 2.4);
        }
    }
    //Calculate relative luminance using ITU-R BT. 709 coefficients
    return ($components['r'] * 0.2126) + ($components['g'] * 0.7152) + ($components['b'] * 0.0722);
}

/**
 * Calculate contrast ratio acording to WCAG 2.0 formula
 * Will return a value between 1 (no contrast) and 21 (max contrast)
 * @link http://www.w3.org/TR/WCAG20/#contrast-ratiodef
 * @param string $c1 A 3 or 6-digit hex colour string
 * @param string $c2 A 3 or 6-digit hex colour string
 * @return float
 * @author Marcus Bointon <marcus@synchromedia.co.uk>
 */
function contrastratio($c1, $c2) {
    $y1 = relativeluminance($c1);
    $y2 = relativeluminance($c2);
    //Arrange so $y1 is lightest
    if ($y1 < $y2) {
        $y3 = $y1;
        $y1 = $y2;
        $y2 = $y3;
    }
    return ($y1 + 0.05) / ($y2 + 0.05);
}

आप w3c परिभाषा क्यों पसंद करेंगे? व्यक्तिगत रूप से मैंने CCIR 601 को लागू किया है और w3c ने एक की सिफारिश की है और मैं CCIR 601 परिणामों से बहुत अधिक संतुष्ट
हूं

1
क्योंकि, जैसा कि मैंने कहा, यह W3C और WCAG दोनों द्वारा अनुशंसित है?
सिन्क्रो

1
W3C फॉर्मूला कई स्तरों पर गलत है। यह मानवीय धारणा को ध्यान में नहीं ले रहा है, वे "सरल" विपरीत का उपयोग कर रहे हैं luminance का उपयोग करते हुए जो रैखिक है और सभी अवधारणात्मक समान नहीं है। अन्य बातों के अलावा, ऐसा प्रतीत होता है कि वे कुछ मानकों पर आधारित हैं जो 1988 के रूप में पुराने हैं (!!!) जो आज प्रासंगिक नहीं हैं (वे मानक मोनोक्रोम मॉनिटर जैसे कि हरे / काले रंग पर आधारित थे, और कुल विपरीत इसके विपरीत से संदर्भित थे) , न तो ग्रीसेकेल और न ही रंगों पर विचार)।
Myndex

1
वह पूरी बकवास है। लूमा विशेष रूप से अवधारणात्मक है - यही कारण है कि इसमें लाल, हरे और नीले रंग के विभिन्न गुणांक हैं। आयु का इससे कोई लेना-देना नहीं है - 1976 से उत्कृष्ट CIE लैब अवधारणात्मक रंग अंतरिक्ष तिथियां। W3C स्थान उतना अच्छा नहीं है, हालांकि यह एक अच्छा व्यावहारिक सन्निकटन है जिसकी गणना करना आसान है। यदि आपके पास पेशकश करने के लिए कुछ रचनात्मक है, तो खाली आलोचना के बजाय पोस्ट करें।
सिन्क्रो

3
बस जोड़ने / अद्यतन करने के लिए : हम वर्तमान में प्रतिस्थापन एल्गोरिदम पर शोध कर रहे हैं जो बेहतर मॉडल अवधारणात्मक विपरीत (गितुब अंक 695 में चर्चा) । हालांकि, एक अलग मुद्दे के रूप में FYI करें sRGB के लिए दहलीज का स्थान है -4545 , न कि 0.03928 जिसे अप्रचलित शुरुआती sRGB ड्राफ्ट से संदर्भित किया गया था। आधिकारिक IEC एसटीडी, 0.04045 का उपयोग करता है और WCAG में इस त्रुटि को ठीक करने के लिए एक पुल अनुरोध सामने आ रहा है। (संदर्भ: IEC 61966-2-1: 1999) यह गितुब अंक 360 में है, हालांकि उल्लेख करने के लिए, 8bit में कोई वास्तविक अंतर नहीं है - थ्रेड के अंत के अंत में 360 में 845 में ऑर्टन 45 / 0.03928 सहित त्रुटियों के चार्ट हैं।
माईंडेक्स

8

सभी अन्य लोगों ने जो कहा है उसे जोड़ने के लिए:

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

गामा में अंतर्वर्धित गामा और उचित गामा करने के बीच का अंतर अंधेरे ग्रैज़ में 20% तक है।


2

मैं आज इसी तरह के कार्य को जावास्क्रिप्ट में हल कर रहा था। मैं getPerceivedLightness(rgb)एक HEX RGB रंग के लिए इस फ़ंक्शन पर बस गया हूं । यह ल्यूमिनेंस सुधार के लिए फेयरचाइल्ड और पेरोट्टा फार्मूला के माध्यम से हेल्महोल्टज़-कोहल्राश प्रभाव से संबंधित है।

/**
 * Converts RGB color to CIE 1931 XYZ color space.
 * https://www.image-engineering.de/library/technotes/958-how-to-convert-between-srgb-and-ciexyz
 * @param  {string} hex
 * @return {number[]}
 */
export function rgbToXyz(hex) {
    const [r, g, b] = hexToRgb(hex).map(_ => _ / 255).map(sRGBtoLinearRGB)
    const X =  0.4124 * r + 0.3576 * g + 0.1805 * b
    const Y =  0.2126 * r + 0.7152 * g + 0.0722 * b
    const Z =  0.0193 * r + 0.1192 * g + 0.9505 * b
    // For some reason, X, Y and Z are multiplied by 100.
    return [X, Y, Z].map(_ => _ * 100)
}

/**
 * Undoes gamma-correction from an RGB-encoded color.
 * https://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation
 * /programming/596216/formula-to-determine-brightness-of-rgb-color
 * @param  {number}
 * @return {number}
 */
function sRGBtoLinearRGB(color) {
    // Send this function a decimal sRGB gamma encoded color value
    // between 0.0 and 1.0, and it returns a linearized value.
    if (color <= 0.04045) {
        return color / 12.92
    } else {
        return Math.pow((color + 0.055) / 1.055, 2.4)
    }
}

/**
 * Converts hex color to RGB.
 * /programming/5623838/rgb-to-hex-and-hex-to-rgb
 * @param  {string} hex
 * @return {number[]} [rgb]
 */
function hexToRgb(hex) {
    const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
    if (match) {
        match.shift()
        return match.map(_ => parseInt(_, 16))
    }
}

/**
 * Converts CIE 1931 XYZ colors to CIE L*a*b*.
 * The conversion formula comes from <http://www.easyrgb.com/en/math.php>.
 * https://github.com/cangoektas/xyz-to-lab/blob/master/src/index.js
 * @param   {number[]} color The CIE 1931 XYZ color to convert which refers to
 *                           the D65/2° standard illuminant.
 * @returns {number[]}       The color in the CIE L*a*b* color space.
 */
// X, Y, Z of a "D65" light source.
// "D65" is a standard 6500K Daylight light source.
// https://en.wikipedia.org/wiki/Illuminant_D65
const D65 = [95.047, 100, 108.883]
export function xyzToLab([x, y, z]) {
  [x, y, z] = [x, y, z].map((v, i) => {
    v = v / D65[i]
    return v > 0.008856 ? Math.pow(v, 1 / 3) : v * 7.787 + 16 / 116
  })
  const l = 116 * y - 16
  const a = 500 * (x - y)
  const b = 200 * (y - z)
  return [l, a, b]
}

/**
 * Converts Lab color space to Luminance-Chroma-Hue color space.
 * http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html
 * @param  {number[]}
 * @return {number[]}
 */
export function labToLch([l, a, b]) {
    const c = Math.sqrt(a * a + b * b)
    const h = abToHue(a, b)
    return [l, c, h]
}

/**
 * Converts a and b of Lab color space to Hue of LCH color space.
 * /programming/53733379/conversion-of-cielab-to-cielchab-not-yielding-correct-result
 * @param  {number} a
 * @param  {number} b
 * @return {number}
 */
function abToHue(a, b) {
    if (a >= 0 && b === 0) {
        return 0
    }
    if (a < 0 && b === 0) {
        return 180
    }
    if (a === 0 && b > 0) {
        return 90
    }
    if (a === 0 && b < 0) {
        return 270
    }
    let xBias
    if (a > 0 && b > 0) {
        xBias = 0
    } else if (a < 0) {
        xBias = 180
    } else if (a > 0 && b < 0) {
        xBias = 360
    }
    return radiansToDegrees(Math.atan(b / a)) + xBias
}

function radiansToDegrees(radians) {
    return radians * (180 / Math.PI)
}

function degreesToRadians(degrees) {
    return degrees * Math.PI / 180
}

/**
 * Saturated colors appear brighter to human eye.
 * That's called Helmholtz-Kohlrausch effect.
 * Fairchild and Pirrotta came up with a formula to
 * calculate a correction for that effect.
 * "Color Quality of Semiconductor and Conventional Light Sources":
 * https://books.google.ru/books?id=ptDJDQAAQBAJ&pg=PA45&lpg=PA45&dq=fairchild+pirrotta+correction&source=bl&ots=7gXR2MGJs7&sig=ACfU3U3uIHo0ZUdZB_Cz9F9NldKzBix0oQ&hl=ru&sa=X&ved=2ahUKEwi47LGivOvmAhUHEpoKHU_ICkIQ6AEwAXoECAkQAQ#v=onepage&q=fairchild%20pirrotta%20correction&f=false
 * @return {number}
 */
function getLightnessUsingFairchildPirrottaCorrection([l, c, h]) {
    const l_ = 2.5 - 0.025 * l
    const g = 0.116 * Math.abs(Math.sin(degreesToRadians((h - 90) / 2))) + 0.085
    return l + l_ * g * c
}

export function getPerceivedLightness(hex) {
    return getLightnessUsingFairchildPirrottaCorrection(labToLch(xyzToLab(rgbToXyz(hex))))
}

1

HSV कलरस्पेस को चाल करना चाहिए, जिस भाषा में आप काम कर रहे हैं उसके आधार पर विकिपीडिया लेख देखें, जिससे आपको लाइब्रेरी रूपांतरण मिल सकता है।

H रंग है जो रंग के लिए एक संख्यात्मक मान है (यानी लाल, हरा ...)

S रंग का संतृप्ति है, अर्थात यह कितना 'तीव्र' है

V रंग की 'चमक' है।


7
HSV रंग स्थान के साथ समस्या यह है कि आपके पास नीले और पीले रंग के लिए समान संतृप्ति और मूल्य हो सकते हैं, लेकिन अलग-अलग रंग हैं । पीला नीले रंग की तुलना में बहुत उज्जवल है। वही HSL के लिए जाता है।
इयान बॉयड

hsv आपको तकनीकी अर्थ में एक रंग की "चमक" देता है। अवधारणात्मक चमक में hsv वास्तव में विफल रहता है
user151496

HSV और HSL अवधारणात्मक रूप से सटीक नहीं हैं (और यह करीब भी नहीं है)। वे सापेक्ष रंग को समायोजित करने के लिए "नियंत्रण" के लिए उपयोगी हैं, लेकिन अवधारणात्मक लपट की सटीक भविष्यवाणी के लिए नहीं। अवधारणात्मक लपट के लिए CIELAB से L * का प्रयोग करें।
Myndex

1

RGB ल्यूमिनेन्स मान = 0.3 R + 0.59 G + 0.11 B

http://www.scantips.com/lumin.html

यदि आप देख रहे हैं कि रंग को सफेद करने के कितने करीब है तो आप यूक्लिडियन से दूरी (255, 255, 255) का उपयोग कर सकते हैं

मुझे लगता है कि आरजीबी रंग की जगह एल 2 यूक्लिडियन दूरी के संबंध में अवधारणात्मक रूप से गैर-समान है। यूनिफ़ॉर्म स्पेस में CIE LAB और LUV शामिल हैं।


1

जिव डडसन द्वारा उलटा-गामा सूत्र को जावास्क्रिप्ट में लागू होने पर आधा समायोजित करने की आवश्यकता होती है, अर्थात फ़ंक्शन गम_एसआरजीबी से रिटर्न इंट (वी * 255) की आवश्यकता होती है; इंट इंट (v * 255 + .5) नहीं; आधा समायोजित दौर ऊपर, और यह एक आर = जी = बी यानी ग्रे रंग ट्रायड पर मूल्य एक बहुत अधिक पैदा कर सकता है। आर = जी = बी त्रय पर ग्रेस्केल रूपांतरण आर के बराबर मूल्य का उत्पादन करना चाहिए; यह एक प्रमाण है कि सूत्र मान्य है। कार्रवाई में सूत्र के लिए ग्रीन शेड्स के नौ शेड्स देखें (आधे-समायोजन के बिना)।


ऐसा लगता है कि आप अपने सामान को जानते हैं, इसलिए मैंने
जीव डैडसन

मैंने प्रयोग किया। C ++ में इसे +0.5 की आवश्यकता है, इसलिए मैंने इसे वापस रखा। मैंने अन्य भाषाओं में अनुवाद करने के बारे में एक टिप्पणी जोड़ी।
जीवे डडसन

1

मुझे आश्चर्य है कि उन आरजीबी गुणांक कैसे निर्धारित किए गए थे। मैंने स्वयं एक प्रयोग किया और मैंने निम्नलिखित कार्य पूरा किया:

Y = 0.267 R + 0.642 G + 0.091 B

बंद है, लेकिन स्पष्ट रूप से लंबे समय से स्थापित आईटीयू गुणांक से अलग है। मुझे आश्चर्य है कि अगर वे गुणांक प्रत्येक और हर पर्यवेक्षक के लिए भिन्न हो सकते हैं, क्योंकि हम सभी की आंखों में रेटिना पर शंकु और छड़ की एक अलग मात्रा हो सकती है, और विशेष रूप से विभिन्न प्रकार के शंकु के बीच का अनुपात भिन्न हो सकता है।

सन्दर्भ के लिए:

आईटीयू BT.709:

Y = 0.2126 R + 0.7152 G + 0.0722 B

ITU BT.601:

Y = 0.299 R + 0.587 G + 0.114 B

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

और हां, मेरे पास सामान्य रंग दृष्टि है।


अपने प्रयोगों में आपने पहले गामा घटक को हटाने के लिए रैखिककरण किया था? यदि आपने ऐसा नहीं किया है तो आपके परिणामों की व्याख्या कर सकते हैं। लेकिन यह भी, गुणांक CIE 1931 प्रयोगों से संबंधित हैं और वे औसतन 17 पर्यवेक्षक हैं, इसलिए हां परिणामों में व्यक्तिगत भिन्नता है।
मयंडेक्स

1

यहां सी कोड की एक बिट है जिसे कथित प्रकाश की गणना करना चाहिए।

// reverses the rgb gamma
#define inverseGamma(t) (((t) <= 0.0404482362771076) ? ((t)/12.92) : pow(((t) + 0.055)/1.055, 2.4))

//CIE L*a*b* f function (used to convert XYZ to L*a*b*)  http://en.wikipedia.org/wiki/Lab_color_space
#define LABF(t) ((t >= 8.85645167903563082e-3) ? powf(t,0.333333333333333) : (841.0/108.0)*(t) + (4.0/29.0))


float
rgbToCIEL(PIXEL p)
{
   float y;
   float r=p.r/255.0;
   float g=p.g/255.0;
   float b=p.b/255.0;

   r=inverseGamma(r);
   g=inverseGamma(g);
   b=inverseGamma(b);

   //Observer = 2°, Illuminant = D65 
   y = 0.2125862307855955516*r + 0.7151703037034108499*g + 0.07220049864333622685*b;

   // At this point we've done RGBtoXYZ now do XYZ to Lab

   // y /= WHITEPOINT_Y; The white point for y in D65 is 1.0

    y = LABF(y);

   /* This is the "normal conversion which produces values scaled to 100
    Lab.L = 116.0*y - 16.0;
   */
   return(1.16*y - 0.16); // return values for 0.0 >=L <=1.0
}

0

कृपया चमक को परिभाषित करें। यदि आप देख रहे हैं कि रंग को सफेद करने के कितने करीब है तो आप यूक्लिडियन से दूरी (255, 255, 255) का उपयोग कर सकते हैं


1
नहीं, आप sRGB मानों के बीच यूक्लिडियन दूरी का उपयोग नहीं कर सकते हैं, sRGB एक अवधारणात्मक समान रूप से कार्टेशियन / वेक्टर स्थान नहीं है। यदि आप यूक्लिडियन दूरी को रंग अंतर के माप के रूप में उपयोग करना चाहते हैं, तो आपको कम से कम CIELAB में कनवर्ट करने की आवश्यकता है, या बेहतर अभी तक, CIECAM02 जैसे CAM का उपयोग करें।
Myndex

0

एचएसवी का 'वी' शायद वही है जो आप खोज रहे हैं। MATLAB में एक rgb2hsv फ़ंक्शन है और पहले उद्धृत विकिपीडिया लेख pseudocode से भरा है। यदि RGB2HSV रूपांतरण संभव नहीं है, तो एक कम सटीक मॉडल छवि का ग्रेस्केल संस्करण होगा।


0

यह लिंक गहराई से सब कुछ बताता है, जिसमें आर, जी और बी मूल्यों से पहले उन गुणक स्थिरांक क्यों मौजूद हैं।

संपादित करें: इसका एक उत्तर यहां भी दिया गया है (0.299 * R + 0.587 * G + 0.114 * B)


0

आर के साथ एक रंग की चमक का निर्धारण करने के लिए, मैं एचएसवी सिस्टम रंग में आरजीबी सिस्टम रंग परिवर्तित करता हूं।

मेरी स्क्रिप्ट में, मैं अन्य कारणों से पहले HEX सिस्टम कोड का उपयोग करता हूं, लेकिन आप RGB सिस्टम कोड के साथ भी शुरू कर सकते हैं rgb2hsv {grDevices}। प्रलेखन यहाँ है

यह मेरे कोड का हिस्सा है:

 sample <- c("#010101", "#303030", "#A6A4A4", "#020202", "#010100")
 hsvc <-rgb2hsv(col2rgb(sample)) # convert HEX to HSV
 value <- as.data.frame(hsvc) # create data.frame
 value <- value[3,] # extract the information of brightness
 order(value) # ordrer the color by brightness

0

स्पष्टता के लिए, वर्गमूल का उपयोग करने वाले सूत्र होने चाहिए

sqrt(coefficient * (colour_value^2))

नहीं

sqrt((coefficient * colour_value))^2

इसका प्रमाण आर = जी = बी ट्रायड से ग्रेसीस्केल आर के रूपांतरण में निहित है। यह केवल तभी सच होगा जब आप रंग मान को मापेंगे, न कि रंग मान समय गुणांक को। देखिए ग्रीनस्केल के नौ शेड्स


5
कोष्ठक की गलतियाँ होती हैं
log0

जब तक आपके द्वारा उपयोग किया जाने वाला गुणांक सही गुणांक का वर्गमूल नहीं है।
रुफुसवीस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.