본문 바로가기
코딩/OpenCV

[C++ opencv] 가장 쉽게 이미지 밝기 조절 하는 방법

by DIYver 2020. 6. 25.

본문 목표

OpenCV를 사용해서 영상처리를 할 때, 전에도 말했지만 무조건 흑백(grayscale) 이미지에서 연산을 처리해야 한다고 했다. 

 

그 이유로는 연산처리 속도가 빨라지고 명확하게 할 수 있으므로, 오히려 정확도가 올라간다고 할 수 있다.

 

아무튼 이번에는 grayscale 이미지에서 밝기를 조절하는 방법을 알아보도록 한다.

 

 

키워드 :  사칙연산 ( + , - , * , / )

 

 

 

원리

 

원리는 단순하다.

 

grayscale은 0~255 의 값을 갖고있고, 이는 픽셀의 밝기 정도를 나타낸다.

 

(1,1) 좌표의 픽셀의 밝기 값이 50 인데, 100으로 증가시키려면 어찌해야될지 생각해보자.

 

그러면 가장 단순하게 50만큼을 더해도 되고, 값을 2배로 증가시켜도 된다.

 

이미 초등학교를 다 뗏다면 방법은 다 알고 있는 것이다.

 

OpenCV의 이미지들은 0~255 까지의 값들을 갖는 행렬이다.

 

고등수학을 해보면 A 라는 행렬에 5를 더하면 어떻게 될까?

(정확한 표현이 아닐 수 있지만, 이해하고 넘어가자.)

위와 같이 A 행렬 원소들이 5씩 증가할 것이다.

 

즉, 전체 밝기가 5만큼 증가하게 되는 것이다.

 

여기서 하나 짚고 가야 하는게 있다.

 

그러면 원본 이미지에서 제일 밝은 255 는 어떻게 될까? 하는 궁금증이 떠올라야한다.

 

다행히도 OpenCV 에서는 별다른 장치를 하지 않아도 255를 넘기면 255로 처리가 된다.

 

반대로 0 미만으로 떨어지는 값들은 0으로 처리가 된다.

위처럼 128을 더하고 뺐을 때, 선형적으로 증감된 것을 확인 할 수 있고, 255와 0을 넘지 않게 된다.

 

다른 기반의 영상처리에서는 필히 짚고 넘어가야하는 부분인데, OpenCV 라서 이정도로만 하고 넘어간다.

 

 

 

곱셈 연산은 또 덧셈과 다르다.

 

덧셈은 모든 픽셀이 균일하게 밝아지는데,

 

곱셈은 밝은 부분은 더 밝아지게 된다.

 

예를 들면,

1*5 = 5

5*5 = 25

25*5 = 125

라고 하면 원본 픽셀 값에 5를 곱한 경우이다.

 

기존 픽셀값이 1, 5, 25는 셋다 어두워서 자세히 보지 않으면 검은색으로 보인다.

 

그런데 5를 곱하게 되면서 5, 25, 125 의 값을 띄게 되는데

 

5와 25는 곱셈 연산을 한 결과임에도 불구하고 어두운 검은색으로 보일 것이다.

 

반면에 125는 0~255 값 중에서 중간값인 회색을 띄게 된다.

 

이처럼 기존의 픽셀 값이 클 수록 곱셈 연산이 들어가면 더 밝아지거나 어두워지게 된다.

 

따라서 연산처리에 있어서 생각을 많이 해야한다.

 

전체를 균등하게 조절할 것인지, 밝거나 어두운 영역만 집중해서 조절할 것인지를 말이다.

 

 

 

 

 

 

 

 

 

코드 테스트 결과

- 덧셈 뺄셈 CODE

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int ac, char** av) {

	Mat img_1 = imread("Lenna.png",0);	//이미지를 grayscale로 불러옴

	Mat img_2 = img_1 + 100;
	Mat img_3 = img_1 - 100;

	imshow("original", img_1);
	imshow("img_sum", img_2);
	imshow("img_sub", img_3);

	waitKey(0);

	return 0;
}

 

- RESULT

원본 이미지
뎃셈 연산 이미지
뺄셈 연산 이미지

결과는 위와 같이 나온다.

 

이미지가 확실히 전체적으로 밝아지고, 어두워졌음을 확인할 수 있었다.

 

사칙연산 중에서 덧셈과 뺄셈은 전체적인 밝기 조절을 할 수 있다는 결론이 나온다.

 

 

 

 

 

- 곱셈 나눗셈 CODE

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int ac, char** av) {

	Mat img_1 = imread("Lenna.png",0);	//이미지를 grayscale로 불러옴

	Mat img_2 = img_1 * 2;
	Mat img_3 = img_1 / 2;

	imshow("original", img_1);
	imshow("img_mul", img_2);
	imshow("img_div", img_3);

	waitKey(0);

	return 0;
}

 

- RESULT

 

원본 이미지
곱셈 연산 이미지
나눗셈 연산 이미지 

결과는 위와 같이 나온다.

 

곱셈 연산에 있어서는 원래 밝았던 부분은 훨씬 밝아진 것을 확인할 수 있었고,

 

나눗셈 연산에 있어서는 안정적으로 어두워졌음을 확인할 수 있었다.

 

특히 뺄셈 연산은 연산 후 픽셀값이 0 으로 떨어지는 값들이 많아서 전체적으로 검은 이미지를 띄었다면, 나눗셈 연산에 있어서는 안정적으로 이미지의 밝기가 어두워졌음을 확인할 수 있다.

 

 

 

 

우리가 어떤 연산을 사용해야 하는지는 상황에 맞춰서 결정해야 한다.

 

노이즈를 제거하거나, 보다 명확하게 목표물(object)을 확인할 경우에 사용하는 밝기 조절인만큼 상황에 맞게 사용할 줄 아는것이 중요하다.

 

 

필자가 느낀 결론은,

이미지를 전체적으로 밝게 해서 object를 명확하게 하고 싶다 : 덧셈 연산

이미지를 전체적으로 어둡게해서 object를 명확하게 하고 싶다 : 나눗셈 연산

이렇게 사용하는 것이 좋을 것 같다.

 

 

 

이 외에도 자동으로 밝기를 조절해서 object를 명확하게 해주는 방법이 있다.

 

Histogram 을 통한 방법인데, 포토샵을 해본 분들이라면 익숙할 것이다.

 

다음시간에 Histogram 을 이용한 이미지 밝기 조절을 다뤄보도록 하겠다.

 

 

 

 

 

 

 

 

 

도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!

감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^

댓글