2012-12-18 1 views
4

이미지를 그레이 스케일로 변환하는 수식이있는 것처럼 이미지의 밝기를 높이고 같은 레벨에서 줄이는 수식이 있습니까? r, g 및 b 픽셀 각각에 값을 추가하려고했습니다. 밝기는 증가하지만 동일한 값을 줄이면 원래 값을 되 찾을 수 없습니다.캔버스의 밝기/대비를 조정하는 공식은 무엇입니까?

var pixels = context.getImageData(...); 

//loop over the pixel data and add a value 
p[i] = p[i]+100; 
p[i+1] = p[i+1]+100; 
p[i+2] = p[i+2]+100; 

이렇게하면 이미지가 밝아집니다. 그러나 모든 픽셀에서 100을 줄일 때 원래 이미지를 다시 얻지 못합니다.

나는 이것을 올바르게 계산할 수식이 있음을 웹에서 읽었습니다. 아무도 그것을 설명 할 수 있습니까? 그리고 대비와 감마에 대해서도 마찬가지입니까?

UPDATE :

감사 제안에 대한 모든. 나는 아래의 게시물 중 일부를 살펴본 후 이것을 시도했다.

var pixels = context.getImageData(...); 

//loop over the pixel data and add a value 
p[i] = p[i]+100 < 255 ? p[i]+100 : 255; 
p[i+1] = p[i+1]+100 < 255 ? p[i+1]+100 : 255; 
p[i+2] = p[i+2]+100 < 255 ? p[i+2]+100 : 255; 

그리고 밝기 감소 :

var pixels = context.getImageData(...); 

//loop over the pixel data and add a value 
p[i] = p[i]-100 >= 0 ? p[i]-100 : 0; 
p[i+1] = p[i+1]-100 >= 0 ? p[i+1]-100 : 0; 
p[i+2] = p[i+2]+100 >= 0 ? p[i+2]-100 : 0; 

내가 증가가 잘 작동 볼 수 있습니다,하지만 난 그것을 감소 ​​할 때, 난 여전히 원래의 이미지를 얻을하지 않습니다 증가 밝기

, 원본 이미지와 밝아진 이미지 사이에는 약간의 차이가 있습니다!

내가 뭘 잘못하고 있니?

+0

마지막으로 사용한 수식을 공유 하시겠습니까? – Kyle

답변

5

이 구글에 대한 빠른 검색은 보여 주었다 :

adjust bitmap image brightness/contrast using c++

링크 : 하나 :)를 게시하기 전에

http://www.kweii.com/site/color_theory/2007_LV/BrightnessCalculation.pdf

http://www.bobpowell.net/image_contrast.htm

remeber 비슷한 질문을 찾을 수 있습니다.

EDIT :

두 이상의 링크 :

이미지 처리 알고리즘 부품 5 : 콘트라스트 조정 :

http://thecryptmag.com/Online/56/imgproc_5.html

이미지 처리 알고리즘 4 부 : 밝기 조정 :

http://www.dfstudios.co.uk/articles/image-processing-algorithms-part-4/

편집 :

당신이 게시 코드의 두 번째 블록에 오류가 있습니다

: 요하네스 Jendersie의 말씀

var pixels = context.getImageData(...); 

//loop over the pixel data and add a value 
p[i] = p[i]-100 >= 0 ? p[i]-100 : 0; 
p[i+1] = p[i+1]-100 >= 0 ? p[i+1]-100 : 0; 
p[i+2] = p[i+2]+100 >= 0 ? p[i+2]-100 : 0; // <- Tha p[i+2]+100 should be a p[i+2]-100 right? 

는 사실을, 당신의 문제는 이것이다 이 값을 가진 픽셀이 있다고 가정하십시오.

R = 100; 
G = 210; 
B = 20; 
,210

는 그리고 당신은 지금 당신이, 각 색상에 100를 추가 :이 작업은 되돌릴 수 없습니다 왜 그

R = 100; // same 
G = 155; // different!, this have to be 210!! 
B = 20; // same 

:

R = 200; 
G = 255; // It was 310 but you have to clamp it to 255. 
B = 120; 

지금 당신이 그 같은 100을 뺍니다. 당신이 할 수있는 것은 항상 원본 이미지의 복사본을 가지고 있으며, 값을 변경할 때마다 밝기 보정을 다시 적용합니다.

그래서 100을 추가하는 작업을 취소하는 방법은 100을 뺀 것이 아니라 밝기 보정 값을 0으로 설정하는 것입니다. 이것은 이미지 편집 프로그램이 작동하는 방법이며 슬라이더가 있고 슬라이더 창을 변경하는 동안 0으로 설정하면 원래 이미지를 얻을 수있는 값이지만 보정을 적용한 후에는 취소 할 수 없습니다. 슬라이더 창을 다시 열면 "0"이 이전에 필터링 된 이미지가됩니다.

따라서 이미지의 백업과 brightnesCorrection 값을 어딘가에 유지하고 값이 변경 될 때마다 이미지에 보정을 다시 적용하거나 사용하지 않을 것이라는 사실을 수락해야합니다. 이미지를 이전의 영광 xD로 복원 할 수 있습니다 (적어도 이러한 종류의 밝기 보정에서는 더 좋은 방법이 있는지 확실하지 않음).

희망이 있습니다.

+0

감사합니다. 이것들을 체크 할 것이다! 나는 주변의 책을 읽었지 만, 일반적인 공식을 찾고 있기 때문에이 하나를 확인하지 못했습니다! –

+1

밝기에 관한 논문은 일반적이며, 어떤 언어에도 묶여 있지 않으며, 다른 하나는 C#에 관한 코드를 가지고 있습니다. 나는 좀 더 일반적인 접근 방식으로 응답에 2 개의 링크를 추가했다. – AngelCastillo

+0

내 편집 된 답변 확인 : – AngelCastillo

5

이미지의 많은 연산은 값의 반올림 및 클램핑의 사실로 인해 변환이 불가능합니다.

각 색상 채널 p[i]은 아마도 바이트 유형입니까? 그렇다면 0과 255 사이의 값만 저장할 수 있습니다. 예를 들어 223에 100을 추가하면 323으로 끝나고 1 바이트에는 저장할 수 없습니다. 이로 인해 오버플로가 67 또는 255 (가장 큰 가능한 수)로 고정됩니다. 100을 빼면 223이 복구되지 않지만 155가됩니다.

오프셋을 추가하는 대신 색상을 곱 해보십시오. 그러나 그것은 AngelCastillo의 대답에 의해 보호됩니다.업데이트에


반응 (이 너무 정보의 손실이있을 것이다, 그러나 결과는 좋네요) : 나는 것을 의미 무엇

의 값 (예를 들어, 실제 구현) 결과를 클램핑 데이터 손실. 위의 설명 된 예와 같이 너무 큰 값은 255가됩니다. 따라서 100을 다시 빼면 모든 색상이 155 또는 그보다 큰 인 155로 설정됩니다. 더 밝은 색상 (> 155)의 정보가 손실됩니다.

반올림은 이전의 다른 색상을 동일한 값으로 설정하기 때문에 다른 경우 (대비 및 감마 변경)의 경우 손실 정보가 표시됩니다.

채널 당 더 많은 정보가 포함 된 다른 형식을 사용하는 것을 피할 수있는 유일한 방법입니다. 예 : > 16 비트 부호있는 정수 또는 부동 소수점. 나는 당신의 캔버스에 그렇게 할 수있는 선택의 여지가 없다는 사실을 알고 있으므로 자신의 배경 복사본 (더 높은 가치 범위를 가짐)을 보유해야합니다. 복사본의 모든 변형을 수행하고 이미지를 캔바스에 고정시킵니다.

+0

감사! 나는 255의 상한선과 0의 하한선을 더하고 줄이려고 시도했다. 나의 최신의 질문을 확인해 보라! –

+0

부호가있는 int 또는 부동 소수점을 사용하여이를 수행 할 수있는 방법을 제안 해 주시겠습니까? –

+0

죄송합니다. HTML5에 익숙하지 않습니다. 하지만 당신은 두 번째 백업 이미지를 사용하여 솔루션을 실행할 것입니다 :-) –

관련 문제