---
# System prepended metadata

title: Object Tracking with Opencv and Python(使用版)

---

## 成果圖
![](https://hackmd.io/_uploads/ryXJb9unn.png)
## 使用到的函式庫
![](https://hackmd.io/_uploads/rJhV-5O32.png)

## 實作影片
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視窗
```

