#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 15
11장 이진화와 모폴로지
11.1 영상의 이진화
영상에서 관심있는 객체 영역과 배경 영역을 구분하기 위한 용도로 사용
11.1.1 이진화
영상의 각 픽셀을 두 개의 부류로 나누는 작업
입력 영상을 주요 객체 영역과 배경 영역으로 나누거나 또는 영상에서 중요도가 높은 관심 영역(ROI Region Of Interest)과 그렇지 않은 비관심 영역으로 구분하는 용도로 사용
영상의 이진화에서는 픽셀 값을 0 또는 255로 설정 : 이진화가 적용된 이진 영상은 흰색과 검은색 픽셀로만 구성됨
그레이스케일 영상에 대해 이진화를 수행하려면 영상의 픽셀 값이 특정 값보다 크면 255로 설정, 작으면 0으로 설정함
이때 각 픽셀과의 크기 비교 대상이 되는 값을 임계값(threshold) 또는 문턱치라고 함
임계값은 그레이스케일 범위인 0~255 사이의 정수를 지정함
이진화 수식 : dst(x, y) = 255(src(x, y) > T(임계값)) or 0(그 외)
// 트랙바를 이용한 이진화
int main(int argc, char* argv[])
{
Mat src;
if (argc < 2)
{
src = imread("neutrophils.png", IMREAD_GRAYSCALE);
}
else
{
src = imread(argv[1], IMREAD_GRAYSCALE);
}
if (src.empty())
{
return -1;
}
imshow("src", src);
namedWindow("dst");
createTrackbar("Threshold", "dst", 0, 255, on_threshold, (void*)&src);
setTrackbarPos("Threshold", "dst", 128);
waitKey();
return 0;
}
void on_threshold(int pos, void* userdata)
{
Mat src = *(Mat*)userdata;
Mat dst;
threshold(src, dst, pos, 255, THRESH_BINARY);
imshow("dst", dst);
}
11.1.2 적응형 이진화
불균일한 조명 성분을 가지고 있는 영상에 대해 하나의 임계값으로 객체와 배경을 제대로 구분하기 어렵기 때문에 각 픽셀마다 서로 다른 임계값을 사용
영상의 모든 픽셀에서 정해진 크기의 사각형 블록 영역을 설정하고, 블록 영역 내부의 픽셀 값 분포로부터 고유의 임계값을 결정하는 방식
T(x, y) = u(x, y)(주변 블록 영역의 픽셀 값 평균) - C(임계값의 크기)
// 적응형 이진화
int main()
{
Mat src = imread("sudoku.jpg", IMREAD_GRAYSCALE);
if (src.empty())
{
return -1;
}
imshow("src", src);
namedWindow("dst");
createTrackbar("Block Size", "dst", 0, 200, on_trackbar, (void*)&src);
setTrackbarPos("Block Size", "dst", 11);
waitKey();
return 0;
}
void on_trackbar(int pos, void* userdata)
{
Mat src = *(Mat*)userdata;
int bsize = pos;
if (bsize % 2 == 0)
bsize--;
if (bsize < 3)
bsize = 3;
Mat dst;
adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, bsize, 5);
imshow("dst", dst);
}
11.2 모폴로지 연산
영상 내부 객체의 형태와 구조를 분석하고 처리하는 기법
그레이스케일 영상과 이진 영상에 모두 적용이 가능하지만 주로 이진 영상에서 객체의 모양을 변형하는 용도로 사용
11.2.1 이진 영상의 침식과 팽창
모폴로지 : 형태 또는 모양에 관한 학문
영상에서 객체의 형태 및 구조에 대해 분석하고 처리하는 기법, 수학적 모폴로지라고도 함
주로 이진 영상에서 객체의 모양을 단순화시키거나 잡음을 제거하는 용도로 사용
모폴로지 연산을 정의하려면 구조 요소를 정의해야 함, 기본이 되는 연산은 침식과 팽창이 있음
구조 요소 : 모폴로지 연산의 동작을 결정하는 작은 크기의 행렬, 대부분 3x3 정방향 구조 요소를 사용
구조 요소의 중심을 고정점으로 사용
침식 연산 : 객체 영역이 축소되고 배경 영역이 확대됨, 구조 요소를 영상 전체에 대해 스캔하면서, 구조 요소가 객체 영역 내부에 완전히 포함될 경우 고정점 위치 픽셀을 255로 설정함
팽창 연산 : 객체 영역이 확대되고 배경 영역이 축소됨, 구조 요소를 영상 전체에 대해 이동시키면서, 구조 요소와 객체 영역이 한 픽셀이라도 만날 경우 고정점 위치 픽셀을 255로 설정함
// 이진 영상의 침식과 팽창
int main()
{
erode_dilate();
return 0;
}
void erode_dilate()
{
Mat src = imread("milkdrop.bmp", IMREAD_GRAYSCALE);
if (src.empty())
{
return;
}
Mat bin;
threshold(src, bin, 0, 255, THRESH_BINARY | THRESH_OTSU);
Mat dst1, dst2;
erode(bin, dst1, Mat()); // 침식 연산
dilate(bin, dst2, Mat()); // 팽창 연산
imshow("src", src);
imshow("bin", bin);
imshow("dst1", dst1);
imshow("dst2", dst2);
waitKey();
destroyAllWindows();
}
11.2.2 이진 영상의 열기와 닫기
열기 연산 : 입력 영상에 대해 침식 연산을 수행한 후, 팽창 연산을 수행. 한 두 픽셀짜리 영역이 제거된 후 팽창 연산을 수행하기 때문에 이진 영상에 존재하는 작은 크기의 객체가 효과적으로 제거됨
닫기 연산 : 입력 영상에 대해 팽창 연산을 수행한 후, 침식 연산을 수행. 객체 내부의 작은 구멍이 메워진 후 침식 연산을 수행하기 때문에 이진 영상에 존재하는 작은 구멍을 제거함
// 이진 영상의 열기와 닫기 연산
int main()
{
open_close();
return 0;
}
void open_close()
{
Mat src = imread("milkdrop.bmp", IMREAD_GRAYSCALE);
if (src.empty())
{
return;
}
Mat bin;
threshold(src, bin, 0, 255, THRESH_BINARY | THRESH_OTSU);
Mat dst1, dst2;
morphologyEx(bin, dst1, MORPH_OPEN, Mat()); // 열기 연산
morphologyEx(bin, dst2, MORPH_CLOSE, Mat()); // 닫기 연산
imshow("src", src);
imshow("bin", bin);
imshow("dst1", dst1);
imshow("dst2", dst2);
waitKey();
destroyAllWindows();
}