RGB 색상의 밝기를 결정하는 공식
RGB 값이 주어진 색상의 밝기를 결정하는 일종의 수식이나 알고리즘을 찾고 있습니다. RGB 값을 합산하고 더 높은 합계를 갖는 것이 더 간단 할 수는 없지만 어디서부터 시작 해야할지에 대한 손실이 있습니다.
밝기를 의미합니까? 지각 된 밝기? 휘도?
- 휘도 (특정 색 공간에 대한 표준) :
(0.2126*R + 0.7152*G + 0.0722*B)
[1] - 휘도 (지각 옵션 1) :
(0.299*R + 0.587*G + 0.114*B)
[2] - 휘도 (옵션 2로 인식, 계산 속도가 느림) :
→ ( @MatthewHerbst 덕분에 ) [3]
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 )
나는 당신이 찾고있는 것이 RGB-> Luma 변환 공식 이라고 생각합니다 .
광도 / 디지털 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
3 번째 사진 -HSP 컬러 모델
sqrt(0.299 * R^2 + 0.587 * G^2 + 0.114 * B^2)
네 번째 사진 -WCAG 2.0 SC 1.4.3 상대 휘도 및 명암비 공식 ( 여기 @Synchro의 답변 참조 )
한 행의 색상 수에 따라 첫 번째 및 두 번째 사진에서 패턴이 때때로 표시 될 수 있습니다. 3 번째 또는 4 번째 알고리즘에서 어떤 패턴도 발견하지 못했습니다.
내가 선택해야한다면 구현하기가 훨씬 쉽고 알고리즘보다 약 33 % 더 빠르기 때문에 알고리즘 번호 3을 사용합니다.
아래는 브라우저 등에서 사용되는 sRGB 이미지를 그레이 스케일로 변환하는 유일한 CORRECT 알고리즘입니다.
내부 제품을 계산하기 전에 색상 공간에 대해 감마 함수의 역을 적용해야합니다. 그런 다음 감마 기능을 감소 된 값에 적용합니다. 감마 기능을 통합하지 않으면 최대 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)
);
}
흥미롭게도 RGB => HSV에 대한이 공식 은 v = MAX3 (r, g, b) 만 사용합니다. 즉, 최대 (r, g, b)를 HSV의 V로 사용할 수 있습니다 .
나는 Hearn & Baker의 575 페이지에서 이것이 "가치"를 계산하는 방법입니다.
색상의 "밝기"를 계산하는 훌륭한 작업을 수행하는 이 코드 (C #으로 작성)를 찾았습니다 . 이 시나리오에서 코드는 흰색 또는 검은 색 텍스트를 색상 위에 넣을지 여부를 결정하려고합니다.
"허용 된"답변이 잘못되고 불완전합니다
정확한 답변은 @ jive-dadson 및 @EddingtonsMonkey 답변이며 @ nils-pipenbrinck 지원 합니다. 다른 답변 (허용됨 포함) 은 잘못되었거나 관련이 없거나 오래되었거나 파손 된 출처를 연결하거나 인용합니다.
간단히:
- 계수를 적용하기 전에 sRGB를 LINEARIZED 해야합니다 .
- 휘도 (L 또는 Y)는 빛과 마찬가지로 선형입니다.
- 지각 된 밝기 (L *)는 인간의 지각과 마찬가지로 비선형입니다.
- HSV와 HSL은 인식 측면에서 원격으로 정확하지도 않습니다.
- sRGB에 대한 IEC 표준은 0.04045의 임계 값을 지정하며 0.03928이 아닙니다 (이전의 초기 초안에서 나온 것임).
- 유용성 (즉 , 인식에 대한) , 유클리드 거리는 CIELAB와 같이 지각 적으로 균일 한 데카르트 벡터 공간을 필요로합니다. sRGB는 하나가 아닙니다.
다음은 정확하고 완전한 답변입니다.
이 스레드는 검색 엔진에 많이 나타나기 때문에 주제에 대한 다양한 오해를 명확히하기 위해이 답변을 추가하고 있습니다.
밝기 는 지각적인 속성이며 직접 측정 할 수 없습니다.
지각 된 밝기 는 CIELAB과 같은 일부 비전 모델에 의해 측정되며, 여기서 L * (Lstar)는 지각의 밝기 의 측정치이며 인간의 비전 비선형 반응 곡선에 근접하기 위해 비선형입니다.
휘도 는 빛의 선형 측정으로, 보통 시력에 대해서는 스펙트럼 가중치를 적용하지만 밝기에 대한 비선형 인식에는 조정되지 않습니다.
루마 ( Y ' 프라임)는 일부 비디오 인코딩에 사용되는 감마 인코딩 된 가중치 신호입니다. 선형 휘도와 혼동되어서는 안됩니다.
감마 또는 전송 곡선 (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의 전력 곡선이 필요합니다.
여기서 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에 대한 표준 계수를 적용하십시오.
위 함수를 사용한 의사 코드 :
Y = (0.2126 * sRGBtoLin(vR) + 0.7152 * sRGBtoLin(vG) + 0.0722 * sRGBtoLin(vB))
인식 된 빛을 찾는 방법 :
4 단계 :
위에서 휘도 Y를 가져 와서 L *로 변환
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의 감마 FAQ
다른 사람들이 말한 것을 추가하려면 :
이 모든 방정식은 실제로는 잘 작동하지만 매우 정밀 해야하는 경우 먼저 색상을 선형 색상 공간으로 변환해야하고 (역 이미지 감마 적용) 기본 색상의 가중치 평균을 수행하고 원하는 경우 색상 표시-휘도를 모니터 감마로 다시 가져옵니다.
감마를 무시하고 적절한 감마를 수행하는 것 사이의 휘도 차이는 어두운 회색에서 최대 20 %입니다.
여기에 언급 된 임의의 수식 중에서 손실되는 대신 W3C 표준에서 권장하는 수식을 사용하는 것이 좋습니다.
다음은 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.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);
}
HSV 색상 공간은 트릭을 수행해야 합니다. 작업중인 언어에 따라 Wikipedia 기사를 참조하십시오 . 라이브러리 변환이 발생할 수 있습니다.
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의 리턴은 return int (v * 255) 여야합니다. int (v * 255 + .5)를 반환하지 않습니다. 반 조정은 반올림되며, 이로 인해 R = G = B, 즉 회색 트라이어드에서 값이 너무 높아질 수 있습니다. R = G = B 트라이어드에서 그레이 스케일 변환은 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 트라이어드를 그레이 스케일 R로 변환하는 데 있습니다. 이는 색상 값과 계수가 아닌 색상 값을 제곱 한 경우에만 해당됩니다. 그레이 스케일의 9 가지 음영 참조
참고 URL : https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
'development' 카테고리의 다른 글
Spring Framework에서 applicationContext.xml과 spring-servlet.xml의 차이점 (0) | 2020.02.29 |
---|---|
Java의 HTTP URL 주소 인코딩 (0) | 2020.02.29 |
데이터 프레임의 열 이름 변경 (0) | 2020.02.28 |
노드 / 익스프레스 : EADDRINUSE, 이미 사용중인 주소-서버 종료 (0) | 2020.02.28 |
파이썬과 핍, 사용 가능한 패키지의 모든 버전을 나열합니까? (0) | 2020.02.28 |