โมดูล 3/5 · สัปดาห์ 7–9 · 27 ชม.

การตรวจจับและติดตามวัตถุ

UAT 307 การมองเห็นด้วยคอมพิวเตอร์และเทคโนโลยีการรับรู้

เวลาเรียนประมาณ 90 นาทีร่าง รอตรวจปรับปรุงล่าสุด 28 กันยายน 2569

บทเรียน

เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ

  1. อธิบายการติดตามแบบตรวจจับทุกเฟรมแล้วจับคู่ (tracking-by-detection)
  2. เขียนตัวกรองคาลมานแบบความเร็วคงที่สำหรับติดตามตำแหน่งวัตถุ
  3. จับคู่กรอบระหว่างเฟรมด้วย IoU และนับการสลับหมายเลข
  4. ประเมินการติดตามด้วย MOTA

ความรู้พื้นฐานที่ควรมี: UAT 307 โมดูล 1–2 · UAT 306 โมดูล 4 (object detection) · UAT 305 โมดูล 3 (Kalman filter)

ทำไมต้องรู้

ตัวตรวจจับบอกว่าในเฟรมนี้มีวัตถุอยู่ตรงไหน แต่งานโดรนหลายงานต้องรู้ว่า วัตถุเดิมเคลื่อนไปทางไหน เช่น นับรถที่ผ่านแยก ติดตามคนในงานค้นหา หรือเฝ้าสัตว์ในพื้นที่อนุรักษ์ หน่วยความรู้เรื่องการวิเคราะห์วิดีโออัจฉริยะของคลังความรู้โดรนครอบคลุมการตรวจจับ ติดตาม นับ และแจ้งเตือนแบบเวลาจริง แนวทางที่ใช้กันแพร่หลายคือ tracking-by-detection เช่น SORT (Bewley และคณะ, 2016) ซึ่งใช้ตัวกรองคาลมานแบบความเร็วคงที่ทำนายตำแหน่ง แล้วจับคู่กับผลตรวจจับด้วย IoU ผ่านวิธี Hungarian กรณีของโมดูลนี้คือโดรนเฝ้าลานจอดรถ ข้อมูลเป็นข้อมูลจำลอง

ทำนายตำแหน่งด้วยตัวกรองคาลมาน

ตัวกรองคาลมานที่เรียนใน UAT 305 ใช้ติดตามวัตถุในภาพได้ สถานะคือตำแหน่งและความเร็วในภาพ ขั้นทำนายเลื่อนตำแหน่งตามความเร็ว ขั้นปรับแก้ใช้กรอบที่ตัวตรวจจับให้มา เมื่อตัวตรวจจับพลาดบางเฟรม เช่น รถถูกต้นไม้บัง ตัวกรองยังทำนายต่อได้ แต่ความไม่แน่นอนจะโตขึ้นทุกเฟรมที่ไม่มีข้อมูล

ตัวอย่างที่ 1 ติดตามรถที่ถูกบังสามเฟรม

รถเคลื่อนที่ 3 พิกเซลต่อเฟรมในแนวนอนและ 1.5 พิกเซลในแนวตั้ง ตัวตรวจจับมีความคลาดเคลื่อนราว 2 พิกเซล และพลาดเฟรมที่ 5–7

import math
import numpy as np

dt = 0.1
F = np.array([[1, 0, dt, 0], [0, 1, 0, dt], [0, 0, 1, 0], [0, 0, 0, 1]])   # [x, y, vx, vy]
Hm = np.eye(2, 4)
Q, R = np.eye(4) * 0.5, np.eye(2) * 4.0
truth = [(10 + 3 * k, 50 + 1.5 * k) for k in range(12)]
rng = np.random.default_rng(6)
meas = [(x + rng.normal(0, 2), y + rng.normal(0, 2)) for x, y in truth]
missing = {5, 6, 7}                             # เฟรมที่ถูกบัง

x = np.array([meas[0][0], meas[0][1], 0.0, 0.0])
P = np.diag([4.0, 4.0, 100.0, 100.0])
for k in range(1, 12):
    x, P = F @ x, F @ P @ F.T + Q
    if k not in missing:
        S = Hm @ P @ Hm.T + R
        K = P @ Hm.T @ np.linalg.inv(S)
        x = x + K @ (np.array(meas[k]) - Hm @ x)
        P = (np.eye(4) - K @ Hm) @ P
    err = math.dist(x[:2], truth[k])
    print(f"frame {k:>2} {'predict only' if k in missing else 'updated     '} error {err:4.2f} px, position sigma {math.sqrt(P[0, 0]):.2f} px")
frame  1 updated      error 3.41 px, position sigma 1.52 px
frame  2 updated      error 2.30 px, position sigma 1.46 px
frame  3 updated      error 1.95 px, position sigma 1.46 px
frame  4 updated      error 1.31 px, position sigma 1.44 px
frame  5 predict only error 1.75 px, position sigma 2.00 px
frame  6 predict only error 2.57 px, position sigma 2.58 px
frame  7 predict only error 3.51 px, position sigma 3.17 px
frame  8 updated      error 2.69 px, position sigma 1.77 px
frame  9 updated      error 2.63 px, position sigma 1.47 px
frame 10 updated      error 0.93 px, position sigma 1.35 px
frame 11 updated      error 0.66 px, position sigma 1.29 px

ช่วงที่ถูกบัง ความไม่แน่นอนโตขึ้นและความคลาดเคลื่อนเพิ่มขึ้นทีละเฟรม เมื่อได้ผลตรวจจับกลับมา ตัวกรองดึงตำแหน่งกลับได้ภายในไม่กี่เฟรม ความไม่แน่นอนที่โตขึ้นนี้ใช้ขยายเขตค้นหาเพื่อจับคู่กับวัตถุเดิมเมื่อกลับมาปรากฏ ถ้าถูกบังนานเกินไป ระบบควรปิดเส้นทางนั้นแทนการทำนายไปเรื่อย ๆ

กราฟความคลาดเคลื่อนของตำแหน่งตามเฟรม 1 ถึง 11 แท่งสีฟ้าเป็นเฟรมที่มีผลตรวจจับ แท่งสีชมพูเฟรม 5 ถึง 7 ที่ถูกบังสูงขึ้นทีละเฟรม เส้นสีทองคือส่วนเบี่ยงเบนมาตรฐานของตำแหน่งที่โตขึ้นช่วงถูกบัง
ภาพที่ 1 ความคลาดเคลื่อนและความไม่แน่นอนช่วงที่วัตถุถูกบัง

จับคู่และประเมินด้วย MOTA

เมื่อมีหลายวัตถุ ต้องจับคู่กรอบในเฟรมใหม่กับเส้นทางเดิม ถ้าจับคู่ผิด วัตถุสองตัวจะสลับหมายเลขกัน (ID switch) ซึ่งทำให้การนับผิด ตัวชี้วัด MOTA ของ CLEAR MOT (Bernardin และ Stiefelhagen, 2008) รวมความผิดพลาดสามแบบ คือ พลาดวัตถุ (FN) ตรวจพบสิ่งที่ไม่มี (FP) และสลับหมายเลข (IDSW) หารด้วยจำนวนวัตถุจริงทั้งหมด

ตัวอย่างที่ 2 รถสองคันแล่นสวนกัน

รถ A และ B แล่นเข้าหากันห้าเฟรม เทียบผลของตัวติดตามกับคำตอบ ถือว่าจับคู่ได้เมื่อ IoU ตั้งแต่ 0.5 (ข้อมูลจำลอง)

def iou(p, q):
    ix = max(0, min(p[2], q[2]) - max(p[0], q[0]))
    iy = max(0, min(p[3], q[3]) - max(p[1], q[1]))
    inter = ix * iy
    return inter / ((p[2] - p[0]) * (p[3] - p[1]) + (q[2] - q[0]) * (q[3] - q[1]) - inter)

gt = {1: [("A", (10, 10, 30, 40)), ("B", (60, 10, 80, 40))], 2: [("A", (14, 10, 34, 40)), ("B", (56, 10, 76, 40))],
      3: [("A", (18, 10, 38, 40)), ("B", (52, 10, 72, 40))], 4: [("A", (22, 10, 42, 40)), ("B", (48, 10, 68, 40))],
      5: [("A", (26, 10, 46, 40)), ("B", (44, 10, 64, 40))]}
tracks = {1: [(1, (11, 11, 31, 41)), (2, (59, 10, 79, 40))], 2: [(1, (15, 10, 35, 41)), (2, (55, 11, 75, 40))],
          3: [(1, (19, 10, 39, 40))], 4: [(2, (22, 11, 42, 40)), (1, (47, 10, 67, 41))],
          5: [(2, (27, 10, 47, 40)), (1, (43, 10, 63, 40)), (3, (90, 50, 110, 80))]}

last, fn, fp, idsw, total = {}, 0, 0, 0, 0
for f in sorted(gt):
    total += len(gt[f])
    used = set()
    for gid, gbox in gt[f]:
        best = max(((iou(gbox, tb), tid) for tid, tb in tracks[f] if tid not in used), default=(0, None))
        if best[0] >= 0.5:
            used.add(best[1])
            if gid in last and last[gid] != best[1]:
                idsw += 1
                print(f"frame {f}: {gid} switched from track {last[gid]} to track {best[1]}")
            last[gid] = best[1]
        else:
            fn += 1
    fp += sum(1 for tid, _ in tracks[f] if tid not in used)
print(f"FN {fn}, FP {fp}, IDSW {idsw}, objects {total} -> MOTA {1 - (fn + fp + idsw) / total:.2f}")
frame 4: A switched from track 1 to track 2
frame 4: B switched from track 2 to track 1
FN 1, FP 1, IDSW 2, objects 10 -> MOTA 0.60

ตัวติดตามพลาดรถ B หนึ่งเฟรม มีกรอบเกินหนึ่งกรอบ และสลับหมายเลขของรถทั้งสองคันเมื่อแล่นใกล้กัน MOTA จึงเหลือ 0.60 ทั้งที่แต่ละเฟรมตรวจพบรถเกือบครบ ถ้าใช้ผลนี้นับรถ รถแต่ละคันจะถูกนับผิดทิศทาง การใช้ความเร็วจากตัวกรองคาลมานช่วยจับคู่ และลักษณะภาพของวัตถุ ช่วยลดการสลับหมายเลขได้

แผนภาพตำแหน่งแนวนอนตามเฟรม 1 ถึง 5 เส้นทางจริงของรถ A สีฟ้าไปทางขวาและรถ B สีเขียวไปทางซ้าย จุดของตัวติดตามหมายเลข 1 และ 2 สลับเส้นทางกันที่เฟรม 4 จุดกากบาทสีชมพูคือการพลาดที่เฟรม 3 และกรอบเกินที่เฟรม 5
ภาพที่ 2 การติดตามรถสองคันและการสลับหมายเลข

ปฏิบัติการประจำโมดูล

ปฏิบัติการ: ติดตามรถในวิดีโอจากโดรน

  1. รันตัวตรวจจับจากวิชา UAT 306 บนวิดีโอลานจอดรถทุกเฟรม บันทึกกรอบ
  2. เขียนตัวติดตามจากตัวอย่างที่ 1 และการจับคู่ด้วย IoU
  3. ติด label เส้นทางจริง 100 เฟรม แล้วคำนวณ MOTA ด้วยตัวอย่างที่ 2
  4. ทดลองเปลี่ยนขีดแบ่ง IoU ของการจับคู่และจำนวนเฟรมที่ยอมให้หายก่อนปิดเส้นทาง
  5. นับรถที่ผ่านเส้นกำหนด เทียบกับการนับด้วยตา

ข้อผิดพลาดที่พบบ่อย

ระวัง

  • ประเมินแค่การตรวจจับรายเฟรม โดยไม่ดูการสลับหมายเลข
  • ทำนายต่อไปเรื่อย ๆ เมื่อวัตถุหายนาน
  • ตั้งขีดแบ่ง IoU สูงเกินไป กับวัตถุที่เคลื่อนเร็ว
  • ไม่ชดเชยการเคลื่อนของโดรน ทำให้ทุกวัตถุดูเหมือนเคลื่อนที่
  • นับวัตถุจากหมายเลขเส้นทาง โดยไม่ตรวจการสลับ

สรุป

  • tracking-by-detection ทำนายตำแหน่งด้วยตัวกรองคาลมาน แล้วจับคู่กับผลตรวจจับ
  • ความไม่แน่นอนโตขึ้นเมื่อวัตถุถูกบัง ใช้ขยายเขตค้นหาและตัดสินใจปิดเส้นทาง
  • การสลับหมายเลขทำให้การนับและการวิเคราะห์เส้นทางผิด
  • MOTA รวม FN, FP และ IDSW หารด้วยจำนวนวัตถุจริง

แบบฝึกตรวจความเข้าใจ

  1. วัตถุอยู่ที่ x = 100 px ความเร็ว 20 px/s ทำนายหลัง 0.5 s ได้ที่ใด
  2. FN 5 FP 3 IDSW 2 วัตถุจริงรวม 50 MOTA เท่าใด
  3. ทำไมความไม่แน่นอนจึงโตขึ้นเมื่อไม่มีผลตรวจจับ
  4. ID switch คืออะไร
  5. ทำไมต้องชดเชยการเคลื่อนของโดรนเมื่อติดตามวัตถุบนพื้น
เฉลย
  1. px
  2. ขั้นทำนายเพิ่ม ทุกเฟรม แต่ไม่มีขั้นปรับแก้ลดความไม่แน่นอน
  3. วัตถุจริงตัวเดิมถูกจับคู่กับหมายเลขเส้นทางต่างจากเฟรมก่อน
  4. ภาพทั้งภาพเลื่อนเมื่อโดรนเคลื่อน วัตถุที่หยุดนิ่งจะดูเหมือนเคลื่อนที่

สรุปสูตรสำคัญ

แบบจำลองความเร็วคงที่
MOTA

แหล่งอ้างอิงหลัก

  1. Bewley, A., Ge, Z., Ott, L., Ramos, F., & Upcroft, B. (2016). Simple online and realtime tracking. In 2016 IEEE International Conference on Image Processing (pp. 3464–3468). link
  2. Bernardin, K., & Stiefelhagen, R. (2008). Evaluating multiple object tracking performance: The CLEAR MOT metrics. EURASIP Journal on Image and Video Processing, 2008, 246309. link
  3. Szeliski, R. (2022). Computer vision: Algorithms and applications (2nd ed.). Springer. link
  4. Corke, P. (2023). Robotics, vision and control: Fundamental algorithms in Python. Springer. link

อ่านเพิ่มเติม

ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล

ในชั้นเรียน / ภาคสนาม

ปฏิบัติการในห้องแล็บหรือภาคสนามตามใบงาน พร้อม checklist ความปลอดภัย

หลักฐานการเรียนรู้: ใบงานที่ผ่านการตรวจและผล quiz

แบบทดสอบประจำโมดูล

แบบทดสอบนี้ใช้ตรวจความเข้าใจ (formative) ไม่ใช่การสอบเก็บคะแนน

โดเมนความรู้: ปัญญาประดิษฐ์และคอมพิวเตอร์วิทัศน์ · การตรวจสอบ อุตสาหกรรม และการเฝ้าระวัง