모션 트래킹

김성빈·2024년 5월 5일
0

Modern Computer Vision

목록 보기
27/117

목표

Motion Tracking with Mean Shift and CAMSHIFT

Mean Shift 및 CAMSHIFT를 이용한 모션 트래킹

Mean Shift 설명

한글로 번역하면 "평균 이동" 이며 객체 추적에 사용되는 알고리즘이다.

작은 윈도우(박스)에서 시작해 윈도우 내에 픽셀 밀도가 가장 높은곳으로 이동한다.

이렇게 밀도가 가장 높은곳으로 이동하고, 결국 수렴할 때까지 이 과정을 반복한다.

아래 애니메이션을 보면 이해하기에 도움이 된다.

gif 출처

Mean Shift 실습

영상을 확인하면 퀄리티는 낮지만 Mean Shift의 "밀도가 높은곳으로 이동한다"

라는 개념을 이해할수 있다.

https://youtu.be/DqCY0oskuUo

저번에 도로 트래킹할때 모델을 사용했던것과 똑같이

영상을 분석하고 Html에 바로 출력하는 코드이다.

22초의 영상으로 이루어져있으며 11초씩 두번 반복하는데,

초기 추적된 결과는 추적 윈도우의 위치로 나타나며, 이 위치는 이후의 프레임에서 객체를 추적하는 데 사용된다.

cap = cv2.VideoCapture('slow.flv')

# 비디오의 첫번째 프레임을 읽어옴
ret,frame = cap.read()

# 프레임의 높이와 너비를 가져옵니다(인터거로 사용해야 함)
width = int(cap.get(3)) 
height = int(cap.get(4))

# 코덱을 정의하고 VideoWriter 객체를 만듭니다. 출력은 '*.avi' 파일에 저장
out = cv2.VideoWriter('car_tracking_mean_shift.avi', cv2.VideoWriter_fourcc('M','J','P','G'), 30, (width, height))

# 창 초기 위치 설정
r,h,c,w = 250,90,400,125  # 간단하게 값 하드코딩
track_window = (c,r,w,h)

# 추적을 위해 ROI를 설정
roi = frame[r:r+h, c:c+w]
hsv_roi =  cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)

# 종료 기준을 설정합니다. 10번 반복하거나 최소 1pt 이상 이동
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )

while(1):
    ret, frame = cap.read()

    if ret == True:
        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
        img2 = cv2.rectangle(frame, (x,y), (x+w,y+h), (255,255,255),2)
        out.write(img2)
        #imshow('Tracking', img2)

    else:
        break

cap.release()
out.release()

!ffmpeg -i /content/car_tracking_mean_shift.avi car_tracking_mean_shift.mp4 -y

from IPython.display import HTML
from base64 import b64encode

mp4 = open('car_tracking_mean_shift.mp4','rb').read()
data_url = "data:video/mp4;base64," + b64encode(mp4).decode()

HTML("""
<video controls>
      <source src="%s" type="video/mp4">
</video>
""" % data_url)

Camshift in OpenCV

둘의 객체 추적 알고리즘은 거의 유사하나,

캠쉬프트는 객체의 크기 변화와 회전에 대해 더 강건하며,

결과적으로 보다 정확한 추적을 제공한다.

cap = cv2.VideoCapture('slow.flv')

# take first frame of the video
ret,frame = cap.read()

# Get the height and width of the frame (required to be an interger)
width = int(cap.get(3)) 
height = int(cap.get(4))

# Define the codec and create VideoWriter object. The output is stored in '*.avi' file.
out = cv2.VideoWriter('car_tracking_cam_shift.avi', cv2.VideoWriter_fourcc('M','J','P','G'), 30, (width, height))

# setup initial location of window
r,h,c,w = 250,90,400,125  # simply hardcoded the values
track_window = (c,r,w,h)

# set up the ROI for tracking
roi = frame[r:r+h, c:c+w]
hsv_roi =  cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)

# Setup the termination criteria, either 10 iteration or move by atleast 1 pt
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )

while(1):
    ret ,frame = cap.read()

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

        # apply meanshift to get the new location
        ret, track_window = cv2.CamShift(dst, track_window, term_crit)

        # Draw it on image
        pts = cv2.boxPoints(ret)
        pts = np.int0(pts)
        img2 = cv2.polylines(frame,[pts],True, 255,2)
        out.write(img2)
        #imshow('img2',img2)

    else:
        break

cap.release()
out.release()

코드 차이점

meanShift

# 새로운 위치에 meanshift 적용
ret, track_window = cv2.meanShift(dst, track_window, term_crit)

CamShift

# 캠쉬프트 알고리즘을 적용하여 새로운 위치를 찾음
ret, track_window = cv2.CamShift(dst, track_window, term_crit)
profile
감사합니다. https://www.youtube.com/channel/UCxlkiu9_aWijoD7BannNM7w

0개의 댓글