Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상의 객체 추적 - 캠시프트(CamShift) 방법 - cv2.CamShift

AI 꿈나무 2020. 10. 21. 14:50
반응형

캠시프트 - CamShift

 캠시프트는 민시프트의 단점을 보완해서 만든 추적 방법입니다.

 추적하는 객체의 크기가 변하더라도 검색 윈도우의 크기가 고정되어 있는 평균 이동 알고리즘의 단점을 보완했습니다.

 

 민시프트(Mean Shift)에 대한 내용은 여기에서 확인할 수 있습니다.

 

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

추적 - Tracking  평균 이동 알고리즘을 공부하기 전에 Detection(검출), Recognition(인식), Tracking(추적)에 대해 알아보겠습니다.  Detection(검출) : 영상에서 찾고자 하는 대상의 위치와 크기를 알아내는..

deep-learning-study.tistory.com

 

캠시프트 동작 방법

 (1) 우선 평균 이동 알고리즘으로 이동 위치 계산합니다.

 

 (2) 민시프트가 수렴했다고 판단되면 이 위치에서 검색 윈도우의 윈도우 크기를 약간씩 키웁니다.(OpenCV에서는 10픽셀씩 키우도록 구현되어 있습니다.)

 

 (3) 키운 윈도우 안에서 객체의 위치를 찾아냅니다.

 

 (4) 특징 공간을 가장 잘 표현하는 타원을 만들어서 타원의 크기만큼 윈도우 크기를 키웁니다.

 

 (5) 객체가 작아졌으면 타원의 크기가 작아지게 됩니다.

 

 (6) 검색 윈도우도 타원의 크기에 맞추어 작아지게 됩니다.

 

 (7) 새로운 크기의 윈도우를 이용하여 다시 평균 이동 수행합니다.

 

출처 : OpenCV 튜토리얼

 

캠시프트 추적 함수 - cv2.CamShift

 사용방법은 MeanShift와 비슷합니다.

 

cv2.CamShift(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: 추적하는 객체의 모양을 나타내는 회전된 사각형 정보를 반환. ((cx, cy), (width, height), angle) 튜플

 MeanShift와 CamShift 함수의 차이점은 반환값입니다.

 MeanShift는 반환값으로 반복을 몇번 했는지에 대한 값을 반환했지만

 CamShift 반환값은 회전되어 있는 사각형을 표현하는 정보를 반환합니다.

 이 값을 이용하면 객체를 타원형으로 표현 가능합니다.

 window는 회전이 안된 사각형, retval은 회전된 사각형 정보를 반환합니다.  

 

캠시프트 알고리즘을 이용한 객체 추적 예제 코드

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

 

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

if not cap.isOpened():
    print('Video open failed!')
    sys.exit()
    
# 초기 사각형 영역 : (x, y, w, h)
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]
ranges = [0, 180, 0, 256]
hist = cv2.calcHist([roi_hsv], channels, None, [90, 128], ranges)

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

# 비디오 매 프레임 처리
while True:
    ret, frame = cap.read()
    
    if not ret:
        break
        
    # HS 히스토그램에 대한 역투영
    frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    backproj = cv2.calcBackProject([frame_hsv], channels, hist, ranges, 1)
    
    # CamShift
    ret, rc = cv2.CamShift(backproj, rc, term_crit)
    
    # 추적 결과 화면 출력
    cv2.rectangle(frame, rc, (0, 0, 255), 2)
    # 타원 그리는 함수, 사각형 좌표 주어지면 사각형에 내접하는 타원을 그려줌
    cv2.ellipse(frame, ret, (0, 255, 0), 2)
    cv2.imshow('frame', frame)
    
    if cv2.waitKey(60) == 27:
        break
        
cap.release()
cv2.destroyAllWindows()

  

 

 

 이처럼 객체의 크기에 따라 윈도우 사이즈가 변경됩니다.

 

 

 CamShift 함수는 확률에 대한 이미지를 입력으로 줘야합니다.

 확률에 대한 이미지를 역투영을 입력할 수도 있고 데이터 자료를 입력으로 줄 수 있어 응용에 따라 적절하게 입력하면 됩니다.

 색상정보를 이용할 때는 히스토그램 역투영 방법이 좋습니다.

 


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

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

 

OpenCV: Meanshift and Camshift

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. Consider you have a set of points. (It can be a pixel distribution like histogram backprojec

docs.opencv.org

 

반응형