# 객체 추적 알고리즘 소

움직이는 객체식별하고, 그 위적하는 방법을 의미합니다. 이를 해 동상이나 실시간 스트리데 이터에서 객체움직지하고, 객체적하는데 사됩니다. 다음은 일적으로 사되는 몇 가지 객 체 추적 알고리즘입니다.

 

평균 이동 추적 (Mean Shift Tracking):

1. 평균 이동추적은 객체의 히스토그램을 기반으로 추적하는 알고리즘입니다.
2. 초기위치를 선택하고, 해당 위치의 픽셀분포를 히스토그램으로 계산합니다.
3. 다음 프레임에서 히스토그램 유사도를 측정하여 객체의 새로운 위치를 찾습니다.

4. 이 과정을 반복하여 객체움직적합니다.

우선 전체 코드

 

import cv2

# 평균 이동 추적을 위한 초기 사각형 설정
track_window = None  # 객체의 위치 정보 저장할 변수
roi_hist = None  # 히스토그램을 저장할 변수
trem_crit = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT, 10,1)  # 반복횟수 10

"""
cv2.TERM_CRITERIA_EPS: 반복 알고리즘의 정지 기준 중 하나로, 
주어진 정지 기준 오차(epsilon)를 충족하는 경우 알고리즘을 중지합니다.
cv2.TERM_CRITERIA_COUNT: 반복 알고리즘의 정지 기준 중 하나로, 
주어진 반복 횟수(count)를 충족하는 경우 알고리즘을 중지합니다.
따라서 cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT는 이 두 가지 정지 기준을 모두 사용하겠다는 의미입니다. 
이러한 정지 기준을 설정한 후에는 알고리즘이 주어진 정지 기준에 도달하면 반복을 중지하게 됩니다.

또한, (10, 1)은 알고리즘의 최대 반복 횟수와 정지 기준 오차(epsilon) 값을 나타냅니다. 
예를 들어, 여기서는 최대 10번의 반복과 1의 정지 기준 오차를 설정하였습니다. 
따라서 알고리즘은 최대 10번 반복하거나 주어진 오차가 1 이하로 감소할 때까지 실행됩니다.
"""


# 영상 파일 열기 
cap = cv2.VideoCapture("MS/데이터전처리/0612/data/slow_traffic_small.mp4")

# 첫 프레임에서 추적할 객체 선택
ret, frame = cap.read()  # 영상 있냐없냐 T/F가 ret , Frame 저장
x, y, w, h = cv2.selectROI("selectROI", frame, False, False)
print("선택한 박스의 좌표 >>", x, y, w, h)


# 추적할 객체 초기 히스토그램 계산
roi = frame[y:y+h, x:x+w]  # 관심구역
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # (Hue 색상, Saturation 채도, Value 명도)
roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0,180]) # 히스토그램 계산
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 히스토그램을 0부터 255로 정규화 (정확도 높일려고)

# 추적할 객체의 초기 윈도우 설정 
track_window = (x, y, w, h)
# cv2.imshow("roi test", roi)
# cv2.waitKey(0)

# 평균 이동 추적
while True:
    # 프레임 읽기
    ret, frame = cap.read()
    if not ret:  
        break

    # 추적할 객체에 대한 채도 히스토그램 역투영계산
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    backproj = cv2.calcBackProject([hsv], [0], roi_hist, [0,180], 1)
    """
    [hsv]: 역투영을 계산할 대상 이미지의 HSV 채널입니다. HSV 채널은 색상 정보를 갖고 있어 역투영에 활용됩니다.
    [0]: 역투영에 사용할 채널 인덱스입니다. 여기서는 색상 채널(Hue)인 0번 인덱스를 사용합니다.
    roi_hist: ROI(Region of Interest)의 히스토그램입니다. 이 히스토그램은 역투영에 사용됩니다.
    [0,180]: 히스토그램의 범위를 나타냅니다. 여기서는 Hue 채널의 범위가 0부터 180까지로 설정되었습니다.
    1: 확대 비율(scale)입니다. 픽셀의 값을 히스토그램의 값으로 나누어 정규화합니다.
    """
    

    # 평균 이동으로 새 위치 검색
    ret, track_window = cv2.meanShift(backproj, track_window, trem_crit)

    # 검색된 새 위치에 사각형 그리기
    x, y, w, h = track_window
    print("새 위치 좌표 >>", x, y, w, h)
    cv2.rectangle(frame, (x,y), (x+w, y+h), (0,255,0), 2)
    """
    frame: 이미지 또는 비디오 프레임을 나타내는 변수입니다.
    (x, y): 사각형의 왼쪽 위 모서리의 좌표입니다.
    (x + w, y + h): 사각형의 오른쪽 아래 모서리의 좌표입니다. 여기서 w는 사각형의 너비, h는 사각형의 높이입니다.
    (0, 255, 0): 사각형의 선 색상을 나타내는 RGB 값입니다. (R, G, B) 형식으로 표현됩니다. 여기서 (0, 255, 0)은 녹색을 나타냅니다.
    2: 사각형 선의 두께를 나타냅니다.
    """
    

    # 화면에 출력
    cv2.imshow("backproj", backproj)
    cv2.imshow("frame", frame)

    # 'q'를 누르면 종료
    if cv2.waitKey(60) == ord('q'):
        exit()

# 해제
cap.release()
cv2.destroyAllWindows()

 

import cv2

# 평균 이동 추적을 위한 초기 사각형 설정
track_window = None  # 객체의 위치 정보 저장할 변수
roi_hist = None  # 히스토그램을 저장할 변수
trem_crit = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT, 10,1)  # 반복횟수 10

# 영상 파일 열기 
cap = cv2.VideoCapture("MS/데이터전처리/0612/data/slow_traffic_small.mp4")

# 첫 프레임에서 추적할 객체 선택
ret, frame = cap.read()
x, y, w, h = cv2.selectROI("selectROI", frame, False, False)
print("선택한 박스의 좌표 >>", x, y, w, h)


# 추적할 객체 초기 히스토그램 계산
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # (Hue, Saturation, Value)
roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0,180]) # 히스토그램 계산
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 히스토그램을 0부터 255로 정규화 (정확도 높일려고)

# 추적할 객체의 초기 윈도우 설정 
track_window = (x, y, w, h)
# cv2.imshow("roi test", roi)
# cv2.waitKey(0)

# 평균 이동 추적
while True:
    # 프레임 읽기
    ret, frame = cap.read()
    if not ret:
        break

    # 추적할 객체에 대한 채도 히스토그램 역투영계산
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    backproj = cv2.calcBackProject([hsv], [0], roi_hist, [0,180], 1)

    # 평균 이동으로 새 위치 검색
    ret, track_window = cv2.meanShift(backproj, track_window, trem_crit)

    # 검색된 새 위치에 사각형 그리기
    x, y, w, h = track_window
    print("새 위치 좌표 >>", x, y, w, h)
    cv2.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 2)

    # 화면에 출력
    cv2.imshow("backproj", backproj)
    cv2.imshow("frame", frame)

    # 'q'를 누르면 종료
    if cv2.waitKey(60) == ord('q'):
        break

# 해제
cap.release()
cv2.destroyAllWindows()

 

 

 

+ Recent posts