Python OpenCV

OpenCV 윤곽선 그리기 및 특징 분석 (cv2.boundingRect(), cv2.minAreaRect())

PyExplorer 2025. 3. 8. 09:27
728x90

윤곽선 그리기 및 특징 분석 (cv2.boundingRect(), cv2.minAreaRect())

OpenCV를 이용하면 이미지에서 객체의 윤곽선을 검출하고 이를 분석할 수 있습니다. 특히 cv2.boundingRect()cv2.minAreaRect()를 활용하면 객체의 경계 상자를 구하고, 이를 분석하는 것이 가능합니다. 이번 포스팅에서는 윤곽선 검출, 경계 상자 그리기, 최소 면적 회전된 사각형 계산 등의 과정을 단계적으로 설명하겠습니다.

1. 윤곽선 검출과 경계 상자 개요

객체의 윤곽선을 검출한 후, 해당 윤곽선을 감싸는 경계 상자(Bounding Box) 를 찾는 방법에는 두 가지가 있습니다.

  • cv2.boundingRect(contour): 가장 작은 크기의 직사각형을 반환 (회전 X)
  • cv2.minAreaRect(contour): 최소 면적을 가지는 회전된 직사각형을 반환 (회전 O)

두 방식은 각각의 장점이 있으며, 분석 목적에 따라 적절히 선택해야 합니다.

2. 실습: 윤곽선 검출 및 경계 상자 그리기

아래의 실습에서는 윤곽선을 검출한 후, cv2.boundingRect()cv2.minAreaRect()를 사용하여 객체의 경계 상자를 시각화하는 과정을 살펴보겠습니다.

2.1 라이브러리 불러오기 및 이미지 로드

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 이미지 로드
image = cv2.imread("sample.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 이진화
_, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)

# 결과 출력
plt.imshow(binary, cmap='gray')
plt.title("Binary Image")
plt.show()

여기서는 cv2.threshold()를 사용하여 이진화(binary thresholding) 를 수행했습니다. 이는 윤곽선 검출을 위해 중요한 전처리 과정입니다.

2.2 윤곽선 검출 및 cv2.boundingRect() 적용

# 윤곽선 검출
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 원본 이미지 복사
image_bbox = image.copy()

for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    cv2.rectangle(image_bbox, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 결과 출력
plt.imshow(cv2.cvtColor(image_bbox, cv2.COLOR_BGR2RGB))
plt.title("Bounding Rect")
plt.show()

위 코드에서는 cv2.boundingRect()를 사용하여 객체를 감싸는 사각형을 그리는 방법을 설명하고 있습니다. 이는 회전되지 않은 정렬된 직사각형입니다.

2.3 cv2.minAreaRect() 적용

# 원본 이미지 복사
image_min_rect = image.copy()

for contour in contours:
    rect = cv2.minAreaRect(contour)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    cv2.drawContours(image_min_rect, [box], 0, (0, 0, 255), 2)

# 결과 출력
plt.imshow(cv2.cvtColor(image_min_rect, cv2.COLOR_BGR2RGB))
plt.title("Min Area Rect")
plt.show()

cv2.minAreaRect()객체를 감싸는 최소 면적의 회전된 직사각형을 찾는 데 사용됩니다. cv2.boxPoints()를 이용하여 사각형의 꼭짓점을 찾고, 이를 cv2.drawContours()로 그릴 수 있습니다.

3. cv2.boundingRect() vs cv2.minAreaRect() 비교

두 방법의 차이점을 비교해 보겠습니다.

함수 설명 특징
cv2.boundingRect() 가장 작은 크기의 직사각형 회전되지 않음, 단순한 형태
cv2.minAreaRect() 최소 면적을 가지는 직사각형 회전 가능, 보다 정확한 경계
  • boundingRect()는 빠르고 직관적이지만, 회전된 물체에 대해서는 정확도가 떨어질 수 있습니다.
  • minAreaRect()는 회전된 물체를 고려하지만, boxPoints()를 사용해 변환해야 하는 과정이 필요합니다.

4. 추가 실습: 경계 상자 활용 예제

경계 상자는 다양한 응용 분야에서 활용될 수 있습니다. 예를 들어 텍스트 인식, 객체 추적, ROI(Region of Interest) 설정 등에 사용됩니다. 다음은 윤곽선을 이용하여 이미지 내에서 ROI를 추출하는 예제입니다.

# ROI 추출 예제
for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    roi = image[y:y+h, x:x+w]

    # ROI 출력
    plt.imshow(cv2.cvtColor(roi, cv2.COLOR_BGR2RGB))
    plt.title("Extracted ROI")
    plt.show()

이 코드에서는 cv2.boundingRect()로 얻은 좌표를 사용하여 이미지에서 특정 객체를 잘라내는 방법을 설명하고 있습니다.

5. 결론

이번 포스팅에서는 OpenCV를 활용하여 윤곽선 검출 후 경계 상자를 그리는 방법을 살펴보았습니다. cv2.boundingRect()cv2.minAreaRect()를 비교하면서 각각의 특징을 이해하고, 실제로 객체의 위치 및 크기 정보를 추출하는 방법을 익혔습니다.

이 기법은 다양한 영상 처리 작업에서 활용되며, 특히 객체 검출 및 추적, 영역 관심 (ROI) 설정 등에 유용하게 사용됩니다. 추가적으로 cv2.contourArea()cv2.arcLength() 등을 활용하여 윤곽선의 면적이나 둘레를 분석하는 방법도 고려해 볼 수 있습니다.

728x90