Python OpenCV

객체 추적 (MeanShift, CamShift) - OpenCV 활용

PyExplorer 2025. 3. 11. 08:56
728x90

객체 추적 (MeanShift, CamShift) - OpenCV 활용

1. 서론

객체 추적(Object Tracking)은 비디오나 연속된 이미지 프레임에서 특정 객체를 지속적으로 추적하는 기술입니다. OpenCV에서는 여러 가지 방법을 제공하는데, 그중 대표적인 기법으로 MeanShiftCamShift가 있습니다. 이 글에서는 MeanShift와 CamShift 알고리즘을 활용하여 객체를 추적하는 방법을 소개하고, 예제 코드를 통해 실제 구현을 살펴보겠습니다.

2. MeanShift 알고리즘

2.1 MeanShift 개요

MeanShift는 주어진 데이터의 밀도 중심(Density Mode)을 찾아 이동하는 알고리즘입니다. 객체 추적에서 MeanShift는 초기 객체의 히스토그램을 기준으로, 가장 유사한 영역을 찾고 이동시키는 방식으로 동작합니다.

MeanShift의 기본 동작 방식은 다음과 같습니다:

  1. 추적할 객체의 초기 위치를 설정합니다.
  2. 해당 객체의 히스토그램을 계산합니다.
  3. 현재 프레임에서 가장 유사한 영역을 찾아 중심을 이동합니다.
  4. 이동된 위치를 새로운 객체의 중심으로 설정하고, 반복적으로 과정 3을 수행합니다.

MeanShift는 배경이 단순한 경우 비교적 안정적인 성능을 보이지만, 객체의 크기가 변화하거나 회전하는 경우에는 한계가 있습니다.

2.2 MeanShift 예제 코드

다음은 OpenCV의 cv2.meanShift() 함수를 이용하여 MeanShift 객체 추적을 수행하는 코드입니다.

import cv2
import numpy as np

# 비디오 캡처
cap = cv2.VideoCapture('video.mp4')

# 초기 추적할 객체의 ROI (Region of Interest) 설정
ret, frame = cap.read()
x, y, w, h = 300, 200, 100, 100  # 초기 객체 위치
track_window = (x, y, w, h)

# ROI의 히스토그램 계산
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)

# MeanShift 설정
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)

    # MeanShift 알고리즘 적용
    ret, track_window = cv2.meanShift(dst, track_window, term_crit)
    x, y, w, h = track_window

    # 결과 표시
    result = cv2.rectangle(frame, (x, y), (x + w, y + h), 255, 2)
    cv2.imshow('MeanShift Tracking', result)

    if cv2.waitKey(30) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

3. CamShift 알고리즘

3.1 CamShift 개요

CamShift(Continuously Adaptive MeanShift)는 MeanShift의 단점을 개선한 알고리즘으로, 객체의 크기와 방향 변화를 반영할 수 있습니다. MeanShift와 비슷한 방식으로 동작하지만, 프레임마다 추적 창의 크기와 방향을 업데이트하는 점이 특징입니다.

CamShift의 기본 동작 방식은 다음과 같습니다:

  1. MeanShift를 기반으로 객체의 중심을 찾습니다.
  2. 객체의 크기 변화를 감지하여 추적 창 크기를 조정합니다.
  3. 객체의 방향 정보를 반영하여 타원 형태로 추적 영역을 설정합니다.

CamShift는 움직이는 객체의 크기와 방향이 변하는 경우에도 안정적인 추적이 가능합니다.

3.2 CamShift 예제 코드

다음은 cv2.CamShift()를 이용하여 CamShift 알고리즘을 구현한 코드입니다.

import cv2
import numpy as np

# 비디오 캡처
cap = cv2.VideoCapture('video.mp4')

# 초기 추적할 객체의 ROI 설정
ret, frame = cap.read()
x, y, w, h = 300, 200, 100, 100
track_window = (x, y, w, h)

# ROI의 히스토그램 계산
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)

# CamShift 설정
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)

    # CamShift 알고리즘 적용
    ret, track_window = cv2.CamShift(dst, track_window, term_crit)
    pts = cv2.boxPoints(ret)
    pts = np.int0(pts)

    # 결과 표시
    result = cv2.polylines(frame, [pts], True, 255, 2)
    cv2.imshow('CamShift Tracking', result)

    if cv2.waitKey(30) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

4. MeanShift vs CamShift 비교

기법 특징 장점 단점
MeanShift 밀도 중심 기반 이동 빠르고 간단함 크기와 방향 변화를 반영하지 못함
CamShift MeanShift 개선, 크기 및 방향 반영 객체 변형에도 강함 MeanShift보다 약간 더 복잡함

5. 결론

MeanShift와 CamShift는 OpenCV에서 제공하는 강력한 객체 추적 기법입니다. MeanShift는 간단하고 빠르지만 크기와 방향 변화를 반영하지 못하는 반면, CamShift는 이러한 변화를 고려하여 보다 정확한 추적이 가능합니다. 다양한 환경에서 적절한 기법을 선택하여 활용하면 보다 효율적인 객체 추적을 수행할 수 있습니다.