머신 비전에서의 객체 탐지 및 NMS(Non-Maximum Suppression) 적용 <上편. IOU 구하기>

정다은_Danea·2025년 3월 13일

VISION

목록 보기
2/4
post-thumbnail

(2022년 자유학기 당시에 공부했던 것을 다시 포스팅합니다)

머신 비전 분야에서 객체 탐지는 중요한 역할을 하며, 특히 여러 개의 바운딩 박스가 검출될 경우 최적의 박스를 선택하는 과정이 필요하다. 본 글에서는 객체 탐지 후 바운딩 박스를 정리하는 Non-Maximum Suppression(NMS) 기법을 Python과 OpenCV를 활용하여 구현하는 과정을 설명한다.

1. 객체 탐지(Object Detection)란?

객체 탐지(Object Detection)는 이미지에서 특정 객체(예: 사람, 자동차, 상품 라벨 등)를 찾아내고, 그 위치를 바운딩 박스(Bounding Box)로 표시하는 기술이다. 이를 위해 딥러닝 기반 방법(YOLO, Faster R-CNN)과 전통적인 컴퓨터 비전 기법(색상, 경계선 분석) 등이 사용된다.

나는는 객체 탐지 후, 여러 개의 중복된 바운딩 박스를 정리하는 과정을 직접 구현하였다.

2. 바운딩 박스 정리의 필요성

객체 탐지 알고리즘은 종종 동일한 객체를 여러 개의 바운딩 박스로 검출하는 문제를 갖는다.
이 문제를 해결하기 위해 NMS(Non-Maximum Suppression) 기법을 적용한다.

그렇다면 왜 이러한 기법을 적용해야 할까?

예를 들어, 다음과 같은 상황을 생각해보자.

처음 객체를 검출시 하나의 객체에 대해 신뢰도가 높은 박스가 여러개 검출된다.

겹치는 영역이 많으므로, 각 객체별로 신뢰도가 높은 박스 1개만 남겨야 한다.

이를 해결하는 핵심 개념이 Intersection over Union(IoU)NMS이다.

3. NMS 과정의 필요성

아마 객체를 검출하고 나면 개발자에겐 바운딩 박스의 좌표값, 너비, 높이, confidence(신뢰도), 클래스(해당 객체가 어디에 속하는지)가 주어질 것이다.

Q. 그렇다면 왜 무작정 가장 높은 정확도를 선택하지 않느냐?

A.

바로 상단의 냉장고 사진은 각 카테고리의 개체가 하나씩만 존재하지만

이 사진을 다시 보시면 하나의 이미지에 자동차가 여러대 검출된다.

즉 한 종류의 클래스에 속한 객체가 다수 존재하는 것이다.

이런 경우에 가장 정확도가 높은 바운딩 박스만을 추출한다면 여러개의 자동차 중 오직 한가지의 자동차에만 바운딩 박스가 쳐지며 제대로 된 객체 검출이 되지 않는다.

따라서 각 객체 중 신뢰도가 높은 박스를 하나씩 남기기 위해 NMS 과정을 거치는 것이다.

4. IOU (Intersetction over Union)란?

IoU는 두 개의 바운딩 박스가 얼마나 겹치는지를 나타내는 척도이다.
식은 다음과 같다.

= 2개 박스가 겹치는 영역(너비)의 교집합 / 합집합 이다.

즉, 두 바운딩 박스가 많이 겹칠수록 IoU 값은 1에 가까워지고, 거의 겹치지 않으면 0에 가깝다.

이것이 어디에 쓰이는지는 간단하게 설명하자면,

만일 두 개의 박스가 겹치는 부분이 특정 임계값 이상(사용자가 설정하나 본인은 0.5로 설정)을 넘어간다면 그 두 개의 박스는 하나의 객체를 가리키고 있다고 판단, 둘 중 confidence가 더 높은 쪽을 남기는 것이다.

5. IOU를 구하는 방법

자, 개발자에게 (x,y,w,h)

  • x,y = 사각형의 좌상단 좌표
  • w = 사각형의 너비
  • h = 사각형의 높이

가 주어진다고 가정했을 때 2개의 사각형이 겹치는 영역을 구하기 전 먼저 어떤 것을 고려해야 할까?

.
.
.

바로 2개의 사각형이 겹치는 모든 케이스에 대해 생각해야한다.
(그래야 코드를 짤 수 있기 때문)

2개의 사각형이 겹쳐지는 케이스는 다음과 같다.
해당 개념에 대한 인용 링크

  1. 검은 사각형의 한 개의 모서리와 겹치는 경우
  2. 검은 사각형의 두 개의 모서리와 겹치는 경우
  3. 검은 사각형의 모서리와 겹치진 않지만 한 개의 변과 겹치는 경우
  4. 검은 사각형의 모서리와 겹치진 않지만 두 개의 변과 겹치는 경우
  5. 검은 사각형의 그 무엇과도 겹치지 않으며 내부에 존재하는 경우
  6. 검은 사각형의 그 무엇과도 겹치지 않으며 외부에 존재하는 경우
  7. 검은 사각형과의 접점이 아예 존재하지 않고 동떨어진 경우

자 여기에서 논리적으로 알 수 있듯 7번의 경우 값은 0이다.

그렇다면 IOU 함수를 구현시 계산 로직 전 if문에서 두 사각형이 겹치지 않는다면 0을 반환 후 종료를 하면 더 효율적인 코드가 될 것이라고 판단했다.

6. IOU 코딩하기

우선, 본인이 짠 코드를 봐보자

def IOU(o, m):
    w = h = 0
    if o[2] > m[2] + m[4]:
        return 0
    if o[2] + o[4] < m[2]:
        return 0
    if o[3] > m[3] + m[5]:
        return 0
    if o[3] + o[5] < m[3]:
        return 0
    x = max(o[2], m[2])
    y = max(o[3], m[3])
    w = min(o[2] + o[4], m[2] + m[4]) - x
    h = min(o[3] + o[5], m[3] + m[5]) - y

    intersection = w * h
    union = o[4] * o[5] + m[4] * m[5] - intersection
    return intersection / union

두 사각형이 겹치지 않을시 0 반환 후 종료

if o[2] > m[2] + m[4]:
    return 0
if o[2] + o[4] < m[2]:
    return 0
if o[3] > m[3] + m[5]:
    return 0
if o[3] + o[5] < m[3]:
    return 0

이 부분에 해당하는데 이 알고리즘을 언어화하면

X축에서 겹치지 않는 경우:

  • (첫 번째 박스의 x 좌표) > (두 번째 박스의 x 좌표 + width)
    -> 첫 번째 박스가 더 오른쪽 박스고, 두 번째 박스가 더 왼쪽 박스일 때
    왼쪽 박스의 x 좌표 + 너비 보다 오른쪽 박스의 x 좌표가 더 크다면, 두 박스는 겹치지 않기 때문

  • (첫 번째 박스의 x + width) < (두 번째 박스의 x)
    -> 첫 번째 박스가 더 왼쪽 박스고, 두 번재 박스가 더 오른쪽 박스일 때
    위와 동일

Y축에서 겹치지 않는 경우:

  • (첫 번째 박스의 y 좌표) > (두 번째 박스의 y + height)
    -> 첫 번재 박스가 더 아래쪽에 있고, 두 번째 박스가 더 위쪽일 때
    위쪽 박스의 y 좌표 + 높이보다 아래쪽 박스의 y값이 더 크다면, 두 박스는 겹치지 않기 때문

  • (첫 번째 박스의 y + height) < (두 번째 박스의 y)
    -> 첫 번째 박스가 더 위쪽에 있고, 두 번째 박스가 더 아래쪽일 때
    위와 동일

즉, 한 박스가 다른 박스의 완전한 바깥쪽에 있을 경우 0을 반환해서 불필요한 연산을 줄이는 알고리즘이다.

두 사각형이 겹치는 사각형의 정보 구하기

x = max(o[2], m[2]) # 좌표 x값
y = max(o[3], m[3]) # 좌표 y값
w = min(o[2] + o[4], m[2] + m[4]) - x # 너비
h = min(o[3] + o[5], m[3] + m[5]) - y # 높이

각 값들을 어떻게 할당한건지 작성할건데 만일 이해가 가지 않는다면 위의 사각형이 겹치는 7가지 경우에 대해 보면서 생각해보면 쉽다
(해당 좌표들은 전부 사각형의 좌상단 좌표이다)

  • x : 두 개의 사각형의 x값 중 더 오른쪽에 있는 x값
  • y : 두 개의 사각형의 y값 중 더 아래쪽에 있는 y값
  • w : 두 개의 사각형의 우상단 x 좌표에서(좌상단 x좌표 + 너비) 더 작은 쪽 값에서 x를 뺀다.
  • h : 두 개의 사각형의 좌하단 y 좌표에서(좌상단 y좌표 + 너비) 더 작은 쪽에서 y를 뺀다.
    (w와 h를 구할 때의 x와 y는 앞서 구한 2개의 변수 명)

합집합과 교집합 구하기

교집합 : 구해진 사각형의 값을 바탕으로 넓이 구하기
합집합 : 두 개의 사각형 넓이를 각각 구해서 더한 후 교집합 빼기

자! 여기까지 하면 드디어 IOU 구하기는 끝이 났다.

다음 포스팅에서는 구해진 IOU를 가지고 어떻게 NMS 과정을 거치는지 알아볼 것이다.

profile
IT 개발 기록장 web, app, vision, ai, git, etc. https://github.com/0JDaEun

0개의 댓글