yeon_vision_
[가상현실] tracking 2 본문
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