모폴로지는 영상 내의 구조를 연구하고, 경계를 명확하게 하기 위해 사용된다.
모폴로지는 침식과 팽창으로 이루어진다.
침식은 이미지 객체의 튀어나온 부분을 제거하고, 배경의 노이즈를 제거하는데 유용하다. 다만 내부의 잡음을 확대시킬 수 있는 단점이 있다.
침식 연산을 진행하면 물체의 크기는 줄어들고 배경은 확대된다.
int kernel_size = nKernel;
int half_kernel = kernel_size / 2;
for (int y = half_kernel; y < IMAGE_HEIGHT - half_kernel; y++) {
for (int x = half_kernel; x < IMAGE_WIDTH - half_kernel; x++) {
BYTE min_val = 255;
for (int ky = -half_kernel; ky <= half_kernel; ky++) {
for (int kx = -half_kernel; kx <= half_kernel; kx++) {
int idx = (y + ky) * IMAGE_WIDTH + (x + kx);
if (m_threshold[idx] < min_val) { // m_threshold[idx]가 min_val보다 작으면
min_val = m_threshold[idx]; // min_val 업데이트
}
}
}
m_result[y * IMAGE_WIDTH + x] = min_val;
}
}
팽창은 배경의 잡음은 확대되지만 객체 내부의 잡음을 제거하는 연산을 진행한다. 따라서 객체의 크기가 커지고 배경은 줄어드는 침식과 반대의 역할을 수행한다.
int half_kernel = kernel_size / 2;
for (int y = half_kernel; y < IMAGE_HEIGHT - half_kernel; y++) {
for (int x = half_kernel; x < IMAGE_WIDTH - half_kernel; x++) {
BYTE max_val = 0;
for (int ky = -half_kernel; ky <= half_kernel; ky++) {
for (int kx = -half_kernel; kx <= half_kernel; kx++) {
int idx = (y + ky) * IMAGE_WIDTH + (x + kx);
max_val = max(max_val, input[idx]);
}
}
m_result[y * IMAGE_WIDTH + x] = max_val;
}
}
Erode(nKernel);
Dilate(nKernel);
열림은 제거연산으로 침식 연산 후에 팽창 연산을 사용한다.
즉, 물체의 형상은 보존하면서도 튀어나온 부분을 제거하고, 외곽선을 부드럽게 만든다.
Dilate(nKernel);
Erode(nKernel);
닫힘은 팽창 연산 후에 침식 연산을 사용하여, 작은 구멍이나 틈을 채워 영상의 외곽선을 부드럽게 만든다.