더북(TheBook)

그림 5-5에 나타난 결과 영상 dst를 보면 영상 내부에 매우 밝은 영역과 어두운 영역이 비정상적으로 섞여 있는 것을 볼 수 있습니다. 이처럼 밝은 픽셀 주변에서 급격하게 어두운 픽셀이 나타나는 것은 앞에서 설명했던 포화 연산을 수행하지 않았기 때문에 발생하는 현상입니다. 그림 5-5와 같은 결과가 나타난 원인을 알아보기 위해 다음 C/C++ 코드를 살펴보겠습니다.

unsigned char a = 256;
cout << "a = " << a << endl;

이 코드를 실행하면 “a = 256”이 출력되는 것이 아니라 “a = 0”이 출력됩니다. C/C++의 unsigned char 자료형은 1바이트의 메모리 공간을 사용하고 0부터 255까지의 정수 값을 저장할 수 있습니다. 그러므로 변수 a에 256을 대입하려고 하면 자동으로 0으로 변환되어 저장됩니다. 좀 더 자세히 설명하면, 정수 256을 16진수로 표현하면 0x00000100이고, 이 값을 unsigned char 자료형에 대입하려고 하면 하위 1바이트만 대입되기 때문에 변수 a에는 0x00이 저장됩니다. 마찬가지 방식으로 unsigned char 자료형의 변수에 257을 대입하려고 하면 실제로는 1이 저장됩니다. 결국 코드 5-2를 실행할 경우, 입력 영상의 픽셀 중에서 밝기 100을 더하여 255보다 큰 값이 되는 픽셀은 오히려 픽셀 값이 0에 가까운 어두운 픽셀로 바뀌게 되는 것이죠.

그렇다면 어떻게 해야 정상적인 밝기 조절 결과 영상을 얻을 수 있을까요? 코드 5-2에서 12~16행 이중 for 반복문을 다음과 같이 변경하면 정상적인 밝기 조절 결과 영상을 만들 수 있습니다.

for (int j = 0; j < src.rows; j++) {
  for (int i = 0; i < src.cols; i++) {
      int v = src.at<uchar>(j, i) + 100;
      dst.at<uchar>(j, i) = v > 255 ? 255 : v < 0 ? 0 : v;
  }
}
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.