## 成果圖

## 使用到的函式庫

## 實作影片
https://youtu.be/l4bwW-TMbR8
## 參考網址
https://www.youtube.com/watch?v=O3b8lVF93jU
## 完整程式碼(都有附上註解)
```
import cv2
from tracker import *
tracker = EuclideanDistTracker() # 創建追蹤器物件
cap = cv2.VideoCapture("white_plastic_2.mp4") # 讀取影片
object_detector = cv2.createBackgroundSubtractorMOG2(history=100, varThreshold=40) # 創建背景消除物件,以便進行物體檢測
while True:
ret, frame = cap.read() # 讀取影片中的一幀
height, width, _ = frame.shape # 獲取影片幀的高度和寬度
roi = frame[350:500,250:650] # 從原始影像中提取出感興趣區域
# 1. 物體檢測
mask = object_detector.apply(roi) # 將背景消除應用於感興趣區域,生成遮罩
_, mask = cv2.threshold(mask, 254, 255, cv2.THRESH_BINARY) # 將遮罩二值化,使檢測物體更為明顯
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 找到遮罩中的輪廓
detections = [] # 創建一個空的列表,用於儲存檢測到的物體
for cnt in contours: # 遍歷所有的輪廓
# 計算面積並移除小元素
area = cv2.contourArea(cnt) # 計算輪廓的面積
if area > 100: # 如果面積大於100,則認為該輪廓是一個物體
x, y, w, h = cv2.boundingRect(cnt) # 獲取該物體的邊界框座標
detections.append([x, y, w, h]) # 將物體的座標添加到檢測列表中
# 2. 物體追蹤
boxes_ids = tracker.update(detections) # 更新追蹤器,得到帶有ID的邊界框
for box_id in boxes_ids: # 遍歷所有的邊界框
x, y, w, h, id = box_id # 獲取邊界框和ID
cv2.putText(roi, str(id), (x, y - 15), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 0), 2) # 在物體上方顯示ID
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) # 每30毫秒檢查一次鍵盤,並將鍵盤的輸入儲存到key中
if key == 27: # 如果按下ESC(其ASCII值為27),則結束循環
break
cap.release() # 釋放影片
cv2.destroyAllWindows() # 關閉所有OpenCV視窗
```