yeon_vision_

[가상현실] tracking 2 본문

OTHER COURSE WORK/2023-1 가상현실

[가상현실] tracking 2

lim__ 2023. 5. 11. 16:01

object_tracking.zip 압축풀고 동일 폴더에 camshit.py 옮기기

 

저번 시간에 한건 tracking은 아니였음

 

이번에는 배경을 지우고 윤곽선 따서

이동하는 물체를 따라서 box가 tracking되는 실습.

 

 

main.py

: 실행할 파일

: tracking은 유클리디안 디스턴스를 이용해서 tracking할 것임. EuclideanDistTracker().

cf) 카테시안 디스턴스 : 격자무늬 안에서 최단거리.

import cv2
from tracker import *

# Create tracker object
tracker = EuclideanDistTracker()

cap = cv2.VideoCapture("highway.mp4")

# Object detection from Stable camera
# 픽셀값이 거의 변화가 없는 부분을 배경이라고 인식.
# 입력에 따라 parameter tuning해주면 좋은데 우리는 안함.
# 그렇게 인식된 배경을 뺀다. BackgroundSubtractor.
object_detector = cv2.createBackgroundSubtractorMOG2(history=100, varThreshold=40)

while True:
    ret, frame = cap.read() #frame 읽어오기
    height, width, _ = frame.shape

    # Extract Region of interest
    roi = frame[340: 720,500: 800] #화면에서 관심있는 영역만 데려오기 (roi : region of interst)

    # 1. Object Detection
    mask = object_detector.apply(roi) #해당 영역만큼을 mask. 
    _, mask = cv2.threshold(mask, 254, 255, cv2.THRESH_BINARY)
    contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #findContour로 윤곽선 구하기
    detections = []
    for cnt in contours:
        # Calculate area and remove small elements
        area = cv2.contourArea(cnt)
        # 윤곽선으로 묶인 것의 크기가 100보다 크면 물체로 보고 bounding box치고
        # 이보다 작은거는 noise라고 판단.
        if area > 100: 
            #cv2.drawContours(roi, [cnt], -1, (0, 255, 0), 2)
            x, y, w, h = cv2.boundingRect(cnt)


            detections.append([x, y, w, h]) #detections 에 추가해줌.

    # 2. Object Tracking
    # id를 부여하고 부여한 id로 tracking을 한다.
    # 해당 뭉치가 어디로 이동했는지 갱신
    boxes_ids = tracker.update(detections) 
    
    # 동영상에 box 쳐서 시각화
    for box_id in boxes_ids:
        x, y, w, h, id = box_id
        cv2.putText(roi, str(id), (x, y - 15), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 0), 2)
        cv2.rectangle(roi, (x, y), (x + w, y + h), (0, 255, 0), 3)

    cv2.imshow("roi", roi)
    cv2.imshow("Frame", frame)
    cv2.imshow("Mask", mask)

    key = cv2.waitKey(30)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()

 

tracker.py

: main에서 호출하는 tracking 하는 함수

매번 업데이트하고, 물체의 중심점.

 

새로운 물체라고 생각되는 것의 중심점 계산. 테두리에 박스 치고 박스의 대각선 교점 구함.

import math


class EuclideanDistTracker:
    def __init__(self):
        # Store the center positions of the objects
        self.center_points = {}
        # Keep the count of the IDs
        # each time a new object id detected, the count will increase by one
        self.id_count = 0


    def update(self, objects_rect):
        # Objects boxes and ids
        objects_bbs_ids = []

        # Get center point of new object
        # 새로운 물체라고 생각되는 것의 중심점 계산. 테두리에 박스 치고 박스의 대각선 교점 구함.
        for rect in objects_rect:
            x, y, w, h = rect
            cx = (x + x + w) // 2
            cy = (y + y + h) // 2

            # Find out if that object was detected already
            same_object_detected = False
            for id, pt in self.center_points.items():
                dist = math.hypot(cx - pt[0], cy - pt[1])
				
                # 기존 물체랑 새로운 물체 사이의 거리가 25이상 난다면 새로운 물체라고 판단.
                if dist < 25:
                    self.center_points[id] = (cx, cy) # 가까운 기존 물체의 id를 구한다.
                    print(self.center_points)
                    objects_bbs_ids.append([x, y, w, h, id])
                    same_object_detected = True
                    break

            # New object is detected we assign the ID to that object
            # 새로운 물체라면
            if same_object_detected is False:
                self.center_points[self.id_count] = (cx, cy) 
                objects_bbs_ids.append([x, y, w, h, self.id_count])
                self.id_count += 1 # 총 id 개수 늘린다

        # Clean the dictionary by center points to remove IDS not used anymore
        new_center_points = {}
        for obj_bb_id in objects_bbs_ids:
            _, _, _, _, object_id = obj_bb_id
            center = self.center_points[object_id]
            new_center_points[object_id] = center

        # Update dictionary with IDs not used removed
        self.center_points = new_center_points.copy()
        return objects_bbs_ids

 

camshit.py

 

 

 

meanshift.py

: 이것을 보완한게 camshit.py

: meanshift.py tracking하는 것의 크기가 고정되어있고,

camshift.py는 tracking하는 것의 크기가 유동적이다.

'OTHER COURSE WORK > 2023-1 가상현실' 카테고리의 다른 글

[가상현실] tracking1  (0) 2023.05.04
[가상현실] Vuforia Engine  (0) 2023.04.20
[가상현실] ML Agent  (0) 2023.04.13
[가상현실] Unity NavMesh  (0) 2023.04.09
[가상현실] 2D game tutorial  (0) 2023.03.30
Comments