문제

RGB 값을 감안할 때 색상의 밝기를 결정하기 위해 일종의 공식이나 알고리즘을 찾고 있습니다. RGB 값을 함께 추가하고 합계가 더 밝아지는 것만 큼 간단 할 수는 없지만 어디서부터 시작 해야하는지에 대한 손실이 있습니다.

도움이 되었습니까?

해결책

밝기를 의미합니까? 인식 된 밝기? 휘도?

  • 휘도 (특정 색상 공간의 표준) : (0.2126*R + 0.7152*G + 0.0722*B) [1]
  • 휘도 (인식 된 옵션 1) : (0.299*R + 0.587*G + 0.114*B) [2]
  • 휘도 (인식 된 옵션 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]

다른 팁

나는 당신이 찾고있는 것이 RGB->라고 생각합니다. 루마 변환 공식.

광도/디지털 ITU BT.709:

Y = 0.2126 R + 0.7152 G + 0.0722 B

디지털 ITU BT.601 (R 및 B 구성 요소에 더 많은 가중치를 부여) :

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

허용 된 답변에서 세 가지 알고리즘을 비교했습니다. 약 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

세 번째 사진 - HSP 색상 모델

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

네 번째 사진 - WCAG 2.0 SC 1.4.3 상대적인 휘도 그리고 명암비 공식 (참조 @Synchro 's 대답 여기)

한 행의 색상 수에 따라 패턴이 1 번째 및 두 번째 사진에서 때때로 발견 될 수 있습니다. 3 번째 또는 4 번째 알고리즘의 그림에서 패턴을 발견 한 적이 없습니다.

내가 선택해야한다면 나는 구현하기가 훨씬 쉽고 4 번째보다 약 33% 빠르기 때문에 알고리즘 번호 3을 사용합니다.

Perceived brightness algorithm comparison

아래는 브라우저 등에 사용되는 SRGB 이미지를 회색 스케일로 변환하기위한 유일한 정확한 알고리즘입니다.

내부 제품을 계산하기 전에 색상 공간에 감마 기능의 역수를 적용해야합니다. 그런 다음 감마 기능을 감소 된 값에 적용합니다. 감마 기능을 통합하지 않으면 최대 20%의 오류가 발생할 수 있습니다.

일반적인 컴퓨터 제품의 경우 색상 공간은 SRGB입니다. SRGB의 올바른 숫자는 약입니다. 0.21, 0.72, 0.07. SRGB 용 감마는 지수에 근사한 복합 기능입니다. 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)
    );
}

재미있게, RGB => HSV에 대한이 제제 v = max3 (r, g, b) 만 사용합니다. 다시 말해, 당신은 그것을 사용할 수 있습니다 최고 HSV의 V로 (R, G, B).

나는 575 페이지를 확인했다 Hearn & Baker 이것이 그들이 "가치"를 계산하는 방법입니다.

From Hearn&Baker pg 319

나는 찾았다 이 코드 (C#로 작성) 색상의 "밝기"를 계산하는 훌륭한 작업을 수행합니다. 이 시나리오에서 코드는 색상 위에 흰색 또는 검은 색 텍스트를 넣을지 여부를 결정하려고합니다.

다른 모든 사람들이 말한 것을 추가하기 위해 :

이 모든 방정식은 실제로는 잘 작동하지만 매우 정확해야한다면 먼저 색상을 선형 색상 공간으로 변환해야합니다 (역 이미지 감마를 적용). 1 차 색상의 중량 평균을 수행하고 원하는 경우. 색상 표시 - 모니터 감마로 휘도를 다시 가져옵니다.

Ingnoring gamma와 적절한 감마를하는 것의 휘도 차이는 다크 회색에서 최대 20%입니다.

여기에 언급 된 공식의 무작위 선택에서 길을 잃지 않고 W3C 표준에서 권장하는 공식을 찾는 것이 좋습니다.

다음은 간단하지만 정확한 PHP 구현입니다. WCAG 2.0 SC 1.4.3 상대적인 휘도 그리고 명암비 방식. 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.03928) {
            $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);
}

"허용 된"답변은 부정확하고 불완전합니다

정확한 유일한 답은 다음과 같습니다 @jive-dadson 그리고 @eddingtonsmonkey 답변 및 지원 @nils-pipenbrinck. 다른 대답 (허용 된 사람 포함) 잘못, 관련이 없거나, 쓸모 없거나, 깨진 소스와 연결되거나 인용하고 있습니다.

간단히:

  • SRGB가 있어야합니다 선형화 계수를 적용하기 전에.
  • 휘도 (L 또는 Y)는 빛과 같이 선형입니다.
  • 인식 된 가벼움 (L*)은 인간의 인식과 마찬가지로 비선형입니다.
  • HSV와 HSL은 인식 측면에서 원격으로 정확하지 않습니다.
  • SRGB의 IEC 표준은 0.04045의 임계 값을 지정합니다. 아니다 0.03928 (쓸모없는 초기 초안에서 온 것).
  • 유용합니다 (즉, 인식에 비해), 유클리드 거리에는 Cielab과 같은 지각 적으로 균일 한 직교 벡터 공간이 필요합니다. SRGB는 하나가 아닙니다.

다음은 정확하고 완전한 답변입니다.

이 스레드는 검색 엔진에 매우 높아지기 때문에이 답변을 추가하여 주제에 대한 다양한 오해를 명확히합니다.

명도 지각 속성이며 직접적인 측정이 없습니다.

인식 된 가벼움 Cielab, 여기 L* (lstar)와 같은 일부 비전 모델로 측정됩니다. 지각 적 가벼움, 인간 비전 비선형 응답 곡선에 근사하기위한 비선형입니다.

휘도 빛의 선형 척도이며, 정상적인 시력을 위해 스펙트럼으로 가중되었지만 가벼운 비선형 인식을 위해 조정되지 않았습니다.

루마 (와이 Prime)은 일부 비디오 인코딩에 사용되는 감마 인코딩 된 가중 신호입니다. 선형 휘도와 혼동해서는 안됩니다.

감마 또는 전송 곡선 (TRC)은 종종 지각 곡선과 유사한 곡선이며, 지각 된 노이즈를 줄이고 데이터 활용 (및 관련 이유)을 향상시키기 위해 저장 또는 방송의 이미지 데이터에 일반적으로 적용됩니다.

인식 된 가벼움을 결정합니다, 먼저 감마를 인코딩 된 r´g´b '이미지 값을 선형 휘도로 변환합니다 (L 또는 Y ) 그런 다음 비선형 인식 된 가벼움에 (L*)


휘도를 찾기 위해 :

... 분명히 어딘가에서 길을 잃었 기 때문에 ...

1 단계 :

모든 SRGB 8 비트 정수 값을 10 진수 0.0-1.0으로 변환하십시오.

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

2 단계 :

감마 인코딩 된 RGB를 선형 값으로 변환하십시오. 예를 들어 SRGB (컴퓨터 표준)는 대략 v^2.2의 전력 곡선이 필요하지만 "정확한"변환은 다음과 같습니다.

sRGB to Linear

여기서 v´는 srgb의 감마에 인코딩 된 r, g 또는 b 채널입니다.
의사 코드 :

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

3 단계 :

휘도 (y)를 찾으려면 SRGB의 표준 계수를 적용하십시오.

Apply coefficients Y = R * 0.2126 + G * 0.7152 + B *  0.0722

위의 함수를 사용한 의사 코드 :

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

인식 된 가벼움을 찾기 위해 :

4 단계 :

위에서 휘도를 가져 가서 l*로 변환하십시오.

L* from Y equation
의사 코드 :

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
Charles Poynton의 Gamma Faq

HSV Colorspace는 트릭을 수행해야합니다. 위키 백과 기사 당신이 일하는 언어에 따라 당신은 라이브러리 변환을 얻을 수 있습니다.

H는 색상의 수치 값 인 색조입니다 (예 : 빨간색, 녹색 ...)

s는 색상의 채도, 즉 '강렬한'

V는 색상의 '밝기'입니다.

RGB 휘도 값 = 0.3 R + 0.59 g + 0.11 B

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

색상이 얼마나 가까운 지 찾고 있다면 (255, 255, 255)에서 유클리드 거리를 사용할 수 있습니다.

RGB 색상 공간은 L2 유클리드 거리에 대해 지각 적으로 불균일하다고 생각합니다. 균일 한 공간에는 CIE Lab 및 LUV가 포함됩니다.

Jive Dadson의 역 감마 공식은 JavaScript에서 구현 될 때 하프 조정을 제거해야합니다. 즉, 함수에서의 수익은 gam_srgb가 int (v*255)이어야합니다. 리턴 int (v*255+.5); 하프 조정이 반올림하면 r = g = b, 회색 색상 트라이어드에서 너무 높은 값을 유발할 수 있습니다. r = g = b 트라이어드에서의 Greyscale 변환은 r과 동일한 값을 생성해야합니다. 공식이 유효하다는 증거 중 하나입니다. 보다 그리스 스케일의 9 가지 음영 작동중인 공식의 경우 (하프 조정없이).

다음은 인식 된 휘도를 올바르게 계산 해야하는 약간의 C 코드입니다.

// 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
}

이러한 RGB 계수가 어떻게 결정되었는지 궁금합니다. 나는 직접 실험을했고 나는 다음과 같이 끝났다.

Y = 0.267 R + 0.642 G + 0.091 B

긴장된 ITU 계수와 밀접하지만 분명히 다릅니다. 우리 모두는 우리 눈의 망막에 다른 양의 원뿔과 막대가있을 수 있기 때문에 이러한 계수가 각각의 관찰자마다 다를 수 있는지 궁금합니다. 특히 다른 유형의 원뿔 사이의 비율이 다를 수 있기 때문입니다.

참조 :

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

나는 작은 회색 막대를 밝은 빨간색, 밝은 녹색 및 밝은 파란색 배경으로 빠르게 움직여서 가능한 한 혼합 될 때까지 회색을 조정하여 테스트를 수행했습니다. 또한 다른 색조로 그 테스트를 반복했습니다. 나는 다른 디스플레이에서 테스트를 반복했으며, 고정 감마 계수가 3.0 인 하나조차도 나에게 동일하게 보입니다. 더 나아가서, ITU 계수는 문자 그대로 내 눈에 잘못되었습니다.

그리고 네, 아마도 정상적인 색상을 가지고있을 것입니다.

밝기를 정의하십시오. 색상이 얼마나 가까운 지 찾고 있다면 사용할 수 있습니다. 유클리드 거리 (255, 255, 255)에서

HSV의 'V'는 아마도 당신이 찾고있는 것일 것입니다. MATLAB에는 RGB2HSV 기능이 있으며 이전에 인용 된 Wikipedia 기사는 의사 코드로 가득합니다. RGB2HSV 변환이 가능하지 않으면 덜 정확한 모델은 이미지의 회색차 버전입니다.

이 링크 R, G 및 B 값 앞에 해당 승수 상수가 존재하는 이유를 포함하여 깊이있는 모든 것을 설명합니다.

편집 : 여기서 답변 중 하나에 대한 설명이 있습니다 (0.299*R + 0.587*g + 0.114*b)

r로 색상의 밝기를 결정하기 위해 RGB 시스템 색상을 HSV 시스템 색상으로 변환합니다.

내 스크립트에서는 다른 이유로 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

명확성을 위해서는 제곱근을 사용하는 공식은

sqrt(coefficient * (colour_value^2))

~ 아니다

sqrt((coefficient * colour_value))^2

이것의 증거는 r = g = b 트라이어드를 Greyscale R로 변환하는 데 있습니다. 이것은 색상 값 시간 계수가 아니라 색상 값을 제곱하는 경우에만 해당됩니다. 보다 그리스 스케일의 9 가지 음영

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top