Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상의 객체 추적 - 평균 이동(Mean Shift) 방법 - cv2.meanShift, cv2.calcBackProject

AI 꿈나무 2020. 10. 20. 15:06
반응형

추적 - Tracking

 평균 이동 알고리즘을 공부하기 전에 Detection(검출), Recognition(인식), Tracking(추적)에 대해 알아보겠습니다.

 

 Detection(검출) : 영상에서 찾고자 하는 대상의 위치와 크기를 알아내는 작업

 Recognition(인식) : 주어진 영상이 무엇인지 판별하는 작업 - classification, identification

 Tracking(추적) : 동영상에서 특정 대상의 위치 변화를 알아내는 작법 - Mean Shift, CamShift, Trackers in OpenCV

 

 이번 포스팅에서 공부할 내용은 추적중 한 가지 방법인 Mean Shift(평균 이동) 방법에 대해 공부해보겠습니다.

 

1. 평균 이동 알고리즘 - Mean Shift

 평균 이동 알고리즘은 데이터사이언스에서 데이터를 분석하는 방법 중 하나입니다.

 분포되어 있는 데이터에서 가장 밀집되어 있는 부분을 찾아내기 위한 기법입니다.

 데이터가 가우시안 분포로 분포되어있으면 가우시안의 평균 위치를 찾아냅니다.

 가우시안 평균은 mode와 동일하기 때문에 모드 검출(mode seeking) 알고리즘 이라고도 합니다.

 

출처 : OpenCV 튜토리얼 홈페이지

 

 데이터가 가장 밀집되어 있는 위치를 찾기 위해서 임의의 원을 데이터 공간에 그립니다.

 원 안에 포함되어 있는 점들을 다 파악하여 x좌표, y좌표의 평균을 구합니다.

 평균의 x,y좌표를 표시하고 그 좌표를 원의 중심으로 원을 움직입니다.

 이를 Mean Shift vertor라고 합니다.

 이 작업을 반복적으로 하다보면 가우시안 분포의 중심으로 이동하게 됩니다.

 

 영상에서 Mean Shift 방법은 평균 이동 알고리즘을 이용하여 관심 영역을 추적합니다.

 

출처 : OpenCV 튜토리얼

 

 위 알고리즘은 살색영역을 추적하는 알고리즘 입니다.

 입력 영상에서 살색 영역에 대한 히스토그램 백투영 확률적인 정보를 얻어냅니다.

 기존 위치가 빨간 박스라고 가정하고 빨간 박스 안에 있는 픽셀들의 평균 값을 계산합니다.

 평균이 살색의 픽셀값과 비슷한 곳으로 조금조금씩 이동합니다.

 이 작업을 반복하다보면 어느 순간 움직임이 없어지게 됩니다.

 그때 Mean Shift 알고리즘이 수렴했다고 합니다.

 

2. 평균 이동 알고리즘을 이용한 트랙킹 - cv2.meanShift

  OpenCV에서는 cv2.meanShift 함수를 제공하고 있습니다.

 

cv2.meanShift(probImage, window, criteria) -> retval, window

• probImage: 관심 객체에 대한 히스토그램 역투영 영상 (확률 영상)

• window: 초기 검색 영역 윈도우 & 결과 영역 반환, 튜플

• criteria: 알고리즘 종료 기준. (type, maxCount, epsilon) 튜플.
 (ex) term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) ➔ 최대 10번 반복하며, 정확도가 1이하이면 (즉, 이동 크기가 1픽셀보다 작으면) 종료.

• retval: 알고리즘 내부 반복 횟수.

 히스토그램을 이용해서 히스토그램 역투영 정보를 얻는다면 확률적인 의미를 갖고 있는 영상이 생성됩니다.

 이 영상을 cv2.meanShift 함수에 입력하면 추적할 수 있습니다.

 

3. 평균 이동 객체 추적 예제 코드

 예제 코드 출처 :  황선규 박사님 github홈페이지 sunkyoo.github.io/opencv4cvml/

 

# 비디오 파일 열기
cap = cv2.VideoCapture('camshift.avi')

if not cap.isOpened():
    print('Video open failed!')
    sys.exit()

# 초기 사각형 영역: (x, y, w, h)
# ROI로 선택해도 되지만 강제로 입력함
x, y, w, h = 135, 220, 100, 100
rc = (x, y, w, h)

# 영상의 정보 받아오기
ret, frame = cap.read()

if not ret:
    print('frame read failed!')
    sys.exit
    
roi = frame[y:y+h, x:x+w]
roi_hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)

# HS 히스토그램 계산
channels = [0,1] # H와 S만 이용. V는 안씀
ranges = [0, 180, 0, 256]
hist = cv2.calcHit([roi_hsv], channels, None, [90, 128], ranges)

# Mean Shift 알고리즘 종료 기준
term_crit = (cv2.TERM_CRITERIA_EPA | cv2.TERM_CRITERIA_COUNT, 10, 1)

# 비디오 매 프레임 처리
while True:
    ret, frame = cap.read()
    if not ret:
        break
        
    # HS 히스토그램에 대한 역투영
    # frame을 HSV로 변환
    frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    # 히스토그램 역투영 확률 데이터 얻기
    backproj = cv2.calcBackProject([frame_hsv], channels, hist, ranges, 1)
    
    # Mean Shift
    # 역투영 확률값을 Mean shift 인자에 입력
    _, rc = cv2.meanShift(backproj, rc, term_crit)
    
    # 추적 결과 화면 출력
    cv2.rectangle(frame, re, (0, 0, 255), 2)
    cv2.imshow('frame', frame)
    
    if cv2.waitKey(60) == 27:
        break
        
cap.release()
cv2.destroyAllWindows()

 

 

 이처럼 귤 색상의 히스토그램을 추적하여 빨강색 박스가 이동하는 것을 확인할 수 있습니다. 

 Mean Shift의 단점은 window 크기를 튜플 형태로 입력하여 객체의 크기에 따라 추적 사각형의 크기가 변하지 않습니다.

 

 다음 포스팅에서는 Mean Shfit의 단점을 보완한 Cam Shift에 대해 공부해보겠습니다.

 


OpenCV 튜토리얼과 황선규 박사님의 'OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝' 을 공부하면서 정리해 보았습니다.

docs.opencv.org/master/d7/d00/tutorial_meanshift.html

 

OpenCV: Meanshift and Camshift

Prev Tutorial: How to Use Background Subtraction Methods Next Tutorial: Optical Flow Goal In this chapter, We will learn about the Meanshift and Camshift algorithms to track objects in videos. Meanshift The intuition behind the meanshift is simple. Conside

docs.opencv.org

반응형