이번글에서는 영상의 명암에 대해 알아보겠습니다.
영상에서 명암비란 밝기 차이의 강도를 의미하고, 전반적으로 비슷한 밝기의 픽셀로 이루어질 경우 명암비가 낮다고 하고 밝은 픽셀과 어두운 픽셀이 골고루 있을 경우 명암비가 높다고 합니다.
![](https://3001ssw.com/wp-content/uploads/2023/08/img-min-1.jpg)
오른쪽 레나가 왼쪽 레나보다 명암비가 높습니다.
![](https://3001ssw.com/wp-content/uploads/2023/08/img_1-min-1.jpg)
오른쪽 레나가 왼쪽 레나보다 명암비가 높습니다.
영상에서 명암비를 높이기 위해서는 어두운 부분을 더 어둡게 만들고, 밝은 부분을 더 밝게 만들어야 합니다.
어두운 부분과 밝은 부분의 기준이 되는 값은, 그레이스케일에서 중간 값을 가지는 128입니다.
![](https://3001ssw.com/wp-content/uploads/2023/08/Cap-2022-03-31-22-45-04-750-min.png)
이 값보다 낮은 값은 더 낮게, 높은 값은 더 높게 하는 소스는 아래와 같습니다.
Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
if (src.empty())
{
cerr << "image load fail" << endl;
return;
}
Mat dst(src.rows, src.cols, CV_8UC1);
for (int iRow = 0 ; iRow < src.rows ; iRow++)
{
for (int iCol = 0 ; iCol < src.cols ; iCol++)
{
uchar pixel = src.at<uchar>(iRow, iCol);
uchar alpha = 50;
if (128 < pixel)
pixel = saturate_cast<uchar>(pixel + alpha); // 밝은 픽셀을 더 밝게
else if (pixel < 128)
pixel = saturate_cast<uchar>(pixel - alpha); // 어두운 픽셀을 더 어둡게
dst.at<uchar>(iRow, iCol) = pixel;
}
}
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
위 소스를 실행할 경우 아래와 같이 출력합니다.
![](https://3001ssw.com/wp-content/uploads/2023/08/img_2-min.jpg)
![](https://3001ssw.com/wp-content/uploads/2023/08/img_3-min.jpg)
위 코드를 통해 명암비가 더 높아졌지만 이미지가 부자연스러워 졌습니다. 모든 영역에 대해 같은 알파값을 연산해서 그렇습니다.
자연스럽게 명암비를 올리려면 아래 수식을 사용하면 됩니다.
dst(x, y) = src(x, y) + (src(x, y) - 128) * alpha;
위 수식을 코드로 변환하면 아래와 같습니다.
Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
if (src.empty())
{
cerr << "image load fail" << endl;
return;
}
float alpha = 1.0f;
Mat dst = src + (src - 128) * alpha;
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
실행 결과는 아래와 같습니다.
![](https://3001ssw.com/wp-content/uploads/2023/08/img_4-min.jpg)
![](https://3001ssw.com/wp-content/uploads/2023/08/img_5-min.jpg)
alpah값이 0보다 큰 경우 명암비가 높아지며, 0보다 작은 경우 명암비가 낮아집니다.
다음 글에서는 히스토그램을 이용한 명암비 조절에 대해 알아보겠습니다.