OpenCV 강좌, 경계 검출 후 이미지 후처리

OpenCV는 컴퓨터 비전 분야에서 가장 널리 사용되는 라이브러리 중 하나입니다. 이미지 인식, 비디오 분석, 객체 추적 등 다양한 기능을 제공하며, 이를 통해 강력한 이미지 처리 작업을 수행할 수 있습니다. 본 강좌에서는 OpenCV를 사용하여 이미지에서 경계를 검출한 후, 그 결과를 효과적으로 후처리하는 방법에 대해 알아보겠습니다.

1. 경계 검출이란?

경계 검출은 이미지에서 객체의 경계를 찾는 과정입니다. 이는 객체 인식 및 분할 작업의 핵심으로, 이미지의 특징을 포착하여 고유한 객체를 구분할 수 있게 해줍니다. 대표적인 경계 검출 알고리즘으로는 Canny, Sobel, Laplacian 등이 있습니다.

2. OpenCV 설치하기

먼저, OpenCV를 설치해야 합니다. Python 환경에서 OpenCV를 설치하는 가장 쉬운 방법은 pip를 사용하는 것입니다. 다음 명령어를 사용하여 OpenCV를 설치하십시오:

pip install opencv-python

3. Canny 경계 검출 알고리즘

Canny 경계 검출은 매우 효과적인 경계 검출 기법입니다. 이 알고리즘은 다음의 주요 단계를 따릅니다:

  1. 첫 번째 단계: Gaussian Blur를 사용하여 노이즈 제거
  2. 두 번째 단계: 이미지의 강도를 계산하여 그라디언트Magnitude와 방향을 얻음
  3. 세 번째 단계: 비최대 억제 (Non-maximum Suppression)
  4. 네 번째 단계: 이중 thresholds를 사용하여 경계선 결정

4. Canny 경계 검출 예제

다음은 Canny 경계 검출을 구현한 예제 코드입니다:

import cv2
import numpy as np

# 이미지 로드
image = cv2.imread('image.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Canny 경계 검출
edges = cv2.Canny(gray, 100, 200)

# 결과 표시
cv2.imshow('Original Image', image)
cv2.imshow('Canny Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. 경계 후처리

경계 검출을 한 후, 여러 가지 후처리 작업을 거쳐 결과를 개선할 수 있습니다. 예를 들어, 경계의 두께를 조정하거나 불필요한 노이즈를 제거할 수 있습니다. 일반적인 후처리 기법으로는 모폴로지 변환, 블러링, 윤곽선 추출 등이 있습니다.

6. 모폴로지 변환 (Morphological Transformations)

모폴로지 변환은 이미지의 형태에 대한 처리를 수행합니다. 이 기법은 일반적으로 이진 이미지를 처리하는 데 사용됩니다. 두 가지 주요 형태의 연산은 침식(Erosion)과 팽창(Dilation)입니다.

6.1 침식(Erosion)

침식은 이미지에서 작은 객체를 제거하고 경계를 축소하는 효과를 줍니다.

# 침식
kernel = np.ones((5,5), np.uint8)
eroded = cv2.erode(edges, kernel, iterations = 1)

cv2.imshow('Eroded Image', eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.2 팽창(Dilation)

팽창은 반대로 경계를 확장하고 작은 구멍을 메우는 역할을 합니다.

# 팽창
dilated = cv2.dilate(edges, kernel, iterations = 1)

cv2.imshow('Dilated Image', dilated)
cv2.waitKey(0)
cv2.destroyAllWindows()

7. 블러링 (Blurring)

블러링은 이미지의 세부 정보를 부드럽게 하고 노이즈를 줄이는 데 사용됩니다. Gaussian Blur는 가장 일반적으로 사용되는 블러링 기법입니다.

# Gaussian 블러
blurred = cv2.GaussianBlur(edges, (5, 5), 0)

cv2.imshow('Blurred Image', blurred)
cv2.waitKey(0)
cv2.destroyAllWindows()

8. 윤곽선 추출 (Contour Detection)

윤곽선을 사용하면 이미지에서 객체의 경계를 추출할 수 있습니다. cv2.findContours() 함수를 사용하여 윤곽선을 찾고, cv2.drawContours()를 사용하여 윤곽선을 그릴 수 있습니다.

# 윤곽선 추출
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_image = np.zeros_like(image)

cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)

cv2.imshow('Contours', contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

9. 최종 결과

위의 모든 기법들을 조합하여, 경계 검출 후의 최종 이미지를 생성할 수 있습니다. 예를 들어, Canny로 경계를 검출한 후, 모폴로지 변환을 적용하여 노이즈를 제거하고 윤곽선을 그릴 수 있습니다.

# 경계 검출 + 모폴로지 후처리 + 윤곽선 그리기
edges = cv2.Canny(gray, 100, 200)
dilated = cv2.dilate(edges, kernel, iterations=1)
contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

final_image = np.zeros_like(image)
cv2.drawContours(final_image, contours, -1, (0, 255, 0), 2)

cv2.imshow('Final Result', final_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

10. 결론

OpenCV를 사용한 경계 검출과 후처리는 컴퓨터 비전의 핵심 과정입니다. Canny 알고리즘을 통해 경계를 검출한 후, 다양한 후처리 기법을 적용하여 결과를 개선할 수 있습니다. 본 강좌를 통해 OpenCV의 기본적인 경계 검출 기법과 후처리 방법에 대해 익혔기를 바랍니다.

앞으로 더 많은 OpenCV의 기능을 탐구하시고, 실전 프로젝트에 활용해 보시기 바랍니다. Happy Coding!