본문 바로가기
openCV

[openCV] 밝기 값 변환

by _eunji_ 2020. 1. 18.

Intensity transformation 밝기 값 변환

입력 영상의 픽셀들의 값을 mapping 함수를 통해 다른 값으로 mapping 시키는 것

그림을 보면 x축이 입력 영상의 각 픽셀들의 값이고 사전에 정의한 mapping함수를 통해 mapping시키는 것이다. 즉, r0라는 값을 가진 픽셀은 s0라는 값으로 변환
어떠한 그래프  (mapping) 를 활용하느냐에 따라 결과 영상이 달라진다.

 

Image negatives 반전 함수

  • 이미지의 intensity level이 [0,L-1]일때 반전을 수행하면 s = L-1–r (s: output r: input)
  • 이미지 반전은 어두운 영역의 디테일이 숨겨진 경우 육안으로 확인하기 좋다.

 

Log transformation 로그 함수

  • s=c log(1+r) , c: constant, r: input, s: output
  • (1+r) 의 로그를 취하는 이유는 입력영상이 가질 수 있는 값의 범위에 있다. 왜냐하면 입력 영상의 각 픽셀의 값은 0~255인데 log 0은 정의 되어있지 않으므로 +1을 해준다.
  • 낮은 intensity 값의 범위가 좁은 경우에 넓혀주는 역할을 한다. 즉, 어두운 영역의 디테일이나 인접 픽셀의 차이를 향상시키는 것이다.  밝아지는 것이 아니라 차이를 확대시키는 것.

어두운 영역의 디테일은 개선시키고 밝은 영역은 저하시킨다 .

 

Power-Law (Gamma) transformation

𝑠 = 𝑐𝑟 𝛾 (c:constant, s:output, r:input)

𝛾=1인 경우 입력 값고 출력 값은 같다.

  • 𝛾가 1보다 작은 경우 어두운 부분의 디테일이 살아나고 밝은 부분의 디테일이 죽고, 1보다 큰 경우 어두운 부분의 디테일이 감소하고 밝은 부분의 디테일이 살아난다.
  • 즉, 감마 값에 따라 어두운 부분의 픽셀들의 범위가 증가하기도 하고 감소하기도 한다.

 

Piecewise-linear transformation functions

사용자가 임의로 함수를 만들어 낼 수 도 있다.

입력 영상이 전반적으로 회색조, 그레이 스케일 영상이므로 픽셀들이  128에 가까운 픽셀값을 가진다 .  따라서 아래 함수를 사용하면 디테일이 살아난다 .

 

또한 상수 k를 기준으로 k보다 크면 255, 작으면 0으로 mapping하는 함수를 적용하면 결과는 아래와 같다. (=thresholding)

 

Example code(Image negative)

int main() {
Mat image = imread("lena.png", 0);
Mat negative_img = image.clone();
for (int i = 0; i < image.rows; i++)
for (int j = 0; j < image.cols; j++)
 //입력 영상 픽셀 엑세스
negative_img.at<uchar>(i, j) = 255 - image.at<uchar>(i, j); //반전 영상 
imshow("Input image", image);
imshow("Negative transformation", negative_img);
waitKey(0);
return 0;
}

Example code(Log transformation)

int main() {
Mat image = imread("lena.png", 0);
Mat f_img, log_img;
double c = 1.5f; // scale constant
image.convertTo(f_img, CV_32F); //32비트 float형으로 변환시켜줌 -> log함수에 적용시킬 수 있는 값이 float형이기 때문
f_img = abs(f_img) + 1; //절댓값 + 1 
log(f_img, f_img);
normalize(f_img, f_img, 0, 255, NORM_MINMAX); // 값의 범위를 (0~255) 로 정규화
convertScaleAbs(f_img, log_img, c); // scaling by c, conversion to an unsigned 8-bit type
imshow("Input image", image);
imshow("Log transformation", log_img);
waitKey(0);

Example code(Gamma correction)

int main() {
Mat image = imread("lena.png", 0);
Mat gamma_img;
MatIterator_<uchar> it, end;
float gamma = 0.5;
unsigned char pix[256]; //배열 선언
for (int i = 0; i < 256; i++) {
//i는 0~255까지 변화하기 때문에 i/255는 [0~1]사이 값을 갖게 된다.
//((i/255)^gamma)*255 => [0,255]
//픽셀 값의 값의 범위를 줄여 빠르게 계산하기 위해 이 작업을 수행한다.
pix[i] = saturate_cast<uchar>(pow((float)(i / 255.0), gamma) * 255.0f);
}
gamma_img = image.clone();
for (it = gamma_img.begin<uchar>(), end = gamma_img.end<uchar>(); it != end; it++) {
*it = pix[(*it)];
}
imshow("Input image", image);
imshow("Gamma transformation", gamma_img);
waitKey(0);
}

 

출처 - 컴퓨터 비전 한동대학교 황성수

http://www.kocw.net/home/cview.do?cid=1b1f5b73413060b5

'openCV' 카테고리의 다른 글

[openCV] 공간 도메인 필터링  (0) 2020.01.18
[openCV] 히스토그램 평활화  (0) 2020.01.18
[openCV] 메모리 관리 및 픽셀 엑세스  (0) 2020.01.11
[openCV] Drawing함수  (0) 2020.01.11
[openCV] Mat연산자  (0) 2020.01.11

댓글