본문 목표
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 을 이용한 이미지 밝기 조절을 다뤄보도록 하겠다.
도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!
감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^
'코딩 > OpenCV' 카테고리의 다른 글
[C++ opencv] 평균필터 적용하여 노이즈 제거하기 average filter, filter2d() (2) | 2020.06.26 |
---|---|
[C++ opencv] 효율적인 Histogram 이용한 이미지 밝기 조절 (4) | 2020.06.25 |
[C++ opencv] 동영상 불러오기 VideoCapture() (1) | 2020.06.24 |
[C++ opencv] 카메라, 웹캠 영상 입력받기 VideoCapture() (0) | 2020.06.24 |
[C++ opencv] Grayscale 변환에 대한 고찰 1 (4) | 2020.06.17 |
댓글