관련글
OpenCV 영상 3번째 글입니다. 첫번째 포스팅에서 임계값과 관련된 주요 문제 2가지를 언급하였는데요,
1) 특정 영상의 최적 임계값은 어떻게 선택하는가? → Otsu, Triangle 알고리즘 활용을 소개하였습니다.
2) 임계값은 고정 or 변동이 유리한가? → 이 문제를 해결하기 위해, 적응형 이진화 방법을 소개하고자 합니다.
적응형 이진화
영상 이진화를 위해 꼭 임계값을 고정할 필요는 없습니다. 아래 영상처럼 조명이 균일하지 않을 경우에 고정 임계값을 사용하면 특정영역에서는 이진화가 잘 안될 가능성이 있습니다. 적응형 이진화는 픽셀마다 임계값을 구하여 이진화를 하는 방법입니다.
가장자리는 다소 어둡고, 가운데 쪽이 조금 더 밝습니다.
필터를 적용할 때 3×3, 5×5 사이즈의 마스크를 사용하였던 것처럼, 적응형 이진화도 픽셀을 중심으로 주변 영역을 활용합니다. 주변 영역의 대표값을 구해서 임계값으로 활용하는 것입니다. 픽셀 $(x, y)$의 임계값 $T$는 다음 식으로 구할 수 있습니다.
$$T(x, y) = AdaptiveMethod(x, y) – C$$
여기서 $C$는 Constant(상수)로, 임계값을 조절하는 용도로 사용됩니다.
OpenCV의 adaptiveThreshold 함수에서 $AdaptiveMethod$은 2가지 중에 선택할 수 있는데, ① Mean과 ② Gaussian-weighted sum입니다.
adaptiveThreshold 함수
void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType,
int blockSize, double C)
- InputArray src: 입력영상
- OutputArray dst: 출력영상
- double maxValue: 이진화 영상에 적용할 최대값. 즉, 0과 maxValue로 영상이 이진화 됨.
- int adaptiveMethod: 적응형 이진화 방법 지정 – ADAPTIVE_THRESH_MEAN_C 또는 ADAPTIVE_THRESH_GAUSSIAN_C 중에 선택함.
- int thresholdType: thresholding 타입으로 THRESH_BINARY 또는 THRESH_BINARY_INV 중에 선택함.
- int blockSIze: 주변부 픽셀 사이즈, 3 이상의 홀수여야 함. (3, 5, 7…)
- double C: 임계값 조절 상수
적응형 이진화 적용 예제
예제 코드
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("text.jpg", IMREAD_GRAYSCALE);
if(src.empty())
{
cerr << "file error" << endl;
return 1;
}
Mat dst;
adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 25, 5);
imshow("dst", dst);
waitKey();
destroyAllWindows();
return 0;
}
실행 결과
Method – Gaussian weighted sum(좌) / Mean(우)
Method – Gaussian weighted sum(좌) / Mean(우)
각각 다른 adaptive method를 사용하고 그 외 parameter값은 고정하였는데요, 결과 영상에는 아주 큰 차이는 없는 것 같습니다.
이진화는 굉장히 많이 사용되기 때문에 조금 더 자세하게 포스팅을 해 보았는데요, 모든 방법에는 장단점이 있으므로 입력 영상 및 시스템 성능 등의 요소를 고려하여 최적의 방법을 선택하시면 되겠습니다.
※ 참조: OpenCV 사이트