클러스터의 중심으로 이동하는 알고리즘


| roi를 추출한 이미지 | BackProjection을 적용할 이미지 | BackProjection을 적용한 결과 |
|---|---|---|
![]() | ![]() | ![]() |
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
# 처음에만 얼굴을 탐지하고, 이후 meanshift에 의해서 추적하게 하도록
# haar cascade 방법 사용
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_rects = face_cascade.detectMultiScale(frame)
(face_x, face_y, w, h) = tuple(face_rects[0])
track_window = (face_x, face_y, w, h)
# 얼굴을 찾고, 찾은부의 roi 계산 및 히스토그램 추출
roi = frame[face_y:face_y+h, face_x:face_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 ret == True:
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 히스토그램 역추적
dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
# 객체 추적
ret, track_window = cv2.meanShift(dst, track_window, term_crit)
x, y, w, h = track_window
img2 = cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 5)
cv2.imshow('img', img2)
k = cv2.waitKey(1) & 0xff
if k == 27:
break
else:
break
cap.release()
cv2.destroyAllWindows()
dst = cv2.calcBackProject(images, channels, hist, ranges, scale)
images:
[image].channels:
[0]가 됩니다. 색상 히스토그램을 계산할 때 2개의 채널을 사용할 수도 있습니다(예: [0, 1] for H and S channels).hist:
cv2.calcHist를 사용하여 미리 계산한 히스토그램입니다.ranges:
[0, 180]로 설정할 수 있습니다. 각 채널마다 범위를 지정해야 합니다.scale:
dst:ret, track_window = cv2.meanShift(probImage, window, criteria)
probImage:cv2.calcBackProject 함수를 사용하여 생성된 이미지입니다.window:(x, y, w, h) 형식의 튜플입니다. x, y는 창의 좌상단 좌표이고, w, h는 창의 너비와 높이입니다.criteria:criteria는 일반적으로 cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, max_iter, epsilon 형태로 설정됩니다.ret:track_window:MeanShift에서 영역의 크기가 고정되어있는 단점을 극복한 알고리즘, 지속적으로 영역의 크기를 계산해 업뎅이트 한다.

################################
ret, track_window = cv2.CamShift(dst, track_window, term_crit)
pts = cv2.boxPoints(ret)
pts = np.int0(pts)
img2 = cv2.polylines(frame, [pts], True, (0, 0, 255), 5)
################################