이번 포스팅은 OpenCV에서 Camshift를 이용한 Object Detection에 대해 알아보겠습니다.
포스팅 관련 내용은 아래에서 출처를 얻어 사용하였습니다.
https://docs.opencv.org/4.5.2/d7/d00/tutorial_meanshift.html
GOAL
- Meanshift를 보완하여 만든 Camshift에 대해 이해하고 알아보겠습니다.
Camshift
- 앞서 Meanshift의 결과를 보시면 추적하는 윈도우의 크기가 고정되어 객체를 추적하여 물체의 크기와 상관없이 결과가 나오는 것을 볼 수 있었습니다. 대상의 크기와 위치에 따라 창을 조절해야 하는데 이것을 보완하기 위해 만든 것이 바로 Camshift입니다.
- 그림을 먼저 보고 설명하겠습니다.
- CAMshift란 Continuously Adaptive Mean Shift로 이름에서 알 수 있듯이 '연속적인 적응성 평균 이동' 입니다.
Meanshift를 사용하여 윈도우 크기를 스스로 조정한다는 의미인데,
동작 순서는
1) meanshift로 이동 위치를 계산하고
2) meanshift가 수렴했다고 판단하면 그 위치에서 윈도우의 크기를 약간씩 키웁니다(10 픽셀)
3) 키운 윈도우 안에서 객체 위치를 찾아냅니다.
4) 특징이 잘 들어간 타원을 만들고 그 타원의 크기만큼 윈도우를 키웁니다.
5) 객체가 작아지면 타원이 작아집니다.
6) 타원이 작아지므로 윈도우 크기도 작아짐
7) 이 과정을 반복하여 수행
Using CamShift With OpenCV
- 이제 OpenCV에서 Camshift가 어떻게 쓰이는지 알아봅시다.
OpenCV에서는 cv2.CamShift() 함수로 제공하고 있는데 Meanshift와 유사하지만 조금 다릅니다.
retval, window = cv2.Camshift(probImage, window, criteria)
입력 매개변수
- probImage : 관심 객체에 대한 히스토그램 역투영 영상
- window : 초기 검색 영역 윈도우 & 결과 영역 반환, 튜플
- criteria : 알고리즘 종료 기준, 튜플
출력 매개변수
- retval : 회전된 사각형 정보 -> 추적하는 객체 모양 ((cx, cy), (width, height), angle)) -> 튜플
- window : 회전이 안된 사각형
코드)
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('./images/slow_traffic_small.mp4')
# 비디오의 프레임을 가져온다.
ret,frame = cap.read()
# 창의 초기 위치 설정
x, y, w, h = 300, 200, 100, 50 # 단순히 위치 값을 설정
track_window = (x, y, w, h)
# 추적을 위해 ROI 설정
roi = frame[y:y+h, x:x+w]
hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)
# 종료 기준 설정, 10회 반복하거나 최소 1pt 이동해야함
term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )
while(1):
ret, frame = cap.read()
if ret == True:
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1)
# camshift를 이용하여 새 위치를 얻음
ret, track_window = cv.CamShift(dst, track_window, term_crit)
# 이미지에 그린다.
pts = cv.boxPoints(ret)
pts = np.int0(pts)
img2 = cv.polylines(frame,[pts],True, 255,2)
cv.imshow('img2',img2)
k = cv.waitKey(30) & 0xff
if k == 27:
break
else:
break
결과)
- 결과를 보시면 Meanshift와는 다르게 차가 가까이 오지만 계속해서 윈도우의 크기를 조절하며 추적하는 것을 볼 수 있지만 마지막에 추적할 대상을 잃어버려 윈도우가 이상해지는 것을 볼 수 있었습니다.
- 하지만 조금 더 유연하게 추적하는 객체의 회전과 크기에 반응하는 것을 알 수 있었습니다.
이번 포스팅은 여기까지이며
틀린 점이나 질문이 있으시면 댓글로 남겨주세요.
감사합니다 :)
'영상처리' 카테고리의 다른 글
Python - OpenCV (16) : Meanshift (0) | 2021.08.06 |
---|---|
Python - OpenCV (15) : Face Detection (0) | 2021.08.03 |
Python - OpenCV (14) : Image Pyramid (0) | 2021.07.26 |
Python - OpenCV (13) : SVM(Support Vector Machines) (0) | 2021.07.20 |
Python - OpenCV (12) : Segmentation with Watershed (0) | 2021.07.19 |