Tag Archives: object tracking

OpenCV tracking API with GOTURN

ก็ตามสไตล์ของบล็อคนี้นะครับ ต้องเกริ่นน้ำเยอะหน่อย เข้าเรื่องเลยเดี๋ยวมันจบเร็ว โดยวันนี้เราจะมาพูดถึงการติดตามวัตถุ (Tracking) นอกจากการตรวจจับวัตถุแล้วเนี่ย การติดตามวัตถุก็สำคัญไม่แพ้กันเพราะหากเราต้องการนับวัตถุ หรือตรวจจับว่าเป็นชิ้นเดิมกับที่เราเคยตรวจจับได้รึเปล่านั้นต้องใช้อัลกอริทึมการติดตามวัตถุอย่างแน่นอน จบการเกริ่น อยากเห็นผลลัพธ์เลื่อนไปล่างสุดของโพสได้เลย แต่อ่านหน่อยเถอะอุตส่าห์เขียนมานะ

สำหรับโพสนี้เป็นโพสแชร์ผลลัพธ์ของการใช้งาน Tracking API ของ OpenCV ซึ่งก็มีประสิทธิภาพดี และยังมีให้เลือกทดลองอยู่หลากหลาย Algorithm เช่น MIL KCF GOTURN CSRT Boosting MOSSE MedianFlow TLD ทั้งหมดที่กล่าวมีทั้งข้อดีข้อเสียแตกต่างกันไปตามสถานะการณ์ ลองไปเลือกใช้กันได้นะครับ มีทั้งแบบช้าแบบเร็ว ตัวโค้ดเองเขียนง่ายมาก แต่ถ้าใครจะใช้สำหรับติดตามวัตถุหลายชิ้นพร้อมกันนี่ก็สามารถทำได้เช่นกัน แต่ยังมีข้อจำกัดอีกมาก

แต่วันนี้ที่เลือกมาคือ GOTURN เพราะเป็นอัลกอริทึมเดียวใน Tracking API ที่ใช้ Deep Learning ในการติดตามวัตถุ ซึ่งต้องบอกว่าผลลัพธ์ของการติดตามนั้นขึ้นอยู่กับการเรียนรู้ของโมเดล เราสามารถปรับใช้ได้หลายวัตถุ แต่นั่นคือเราต้องไปสร้างโมเดลขึ้นมาเอง แต่สำหรับอัลกอริทึมอื่นๆใน API นี้จะเป็นการเทียบภาพเป็นหลัก ทำให้อัลกอริทึมส่วนมากเมื่อวัตถุถูกบดบังจะไม่สามารถติดตามต่อได้ เพราะภาพมีความแตกต่างกันมากระหว่างภาพวัตถุแบบเต็มและแบบบดบัง

สำหรับการที่จะใช้ GOTURN ต้องมีการดาวน์โหลดไฟล์โมเดลจาก Reference ด้านล่างโพสนะครับ ส่วนตัว OpenCV ผมใช้ opencv เวอร์ชัน 4.5.2 โดยต้องลงจาก pip install opencv-contrib-python ตัวไลบรารี่นี้มีฟังก์ชันมากกว่าไลบรารี่ opencv-python พอลงไลบรารี่และดาวน์โหลดโมเดล GOTURN มาแล้วก็ไปดูโปรแกรม Python ที่เขียนกันได้เลยครับ

import cv2

cap = cv2.VideoCapture('sea_walk2.mp4')
video_type = cv2.VideoWriter_fourcc('M','P','4','V')
out = cv2.VideoWriter('output.mp4', video_type, 25, (1920,1080))
tracker = cv2.TrackerGOTURN_create()
initial = False

while True:

    (grabbed, frame) = cap.read()

    if not grabbed:
        print('\n End of the video file...')
        break

    if not initial:
        bbox = cv2.selectROI(frame, False)
        initial = True
        tracker.init(frame, bbox)
    else:
        ret, bbox = tracker.update(frame)
        
    p1 = (int(bbox[0]), int(bbox[1]))
    p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
    position = (int(bbox[0] + bbox[2]/2), int(bbox[1] + bbox[3]/2))

    cv2.rectangle(frame, p1, p2, (255,0,0), 4, 1)
    cv2.circle(frame, position, 1, (255,0,0), 5)
    cv2.imshow("Tracking", frame)
    out.write(frame)

    cv2.waitKey(1)

ตัวโปรแกรม Python ด้านบนจะใช้วีดีโอเป็นข้อมูลนำเข้า จากนั้นจะให้ผู้ใช้จำกัดขอบเขตของวัตถุที่จะติดตามจากนั้นก็จะติดตามวัตถุไปจนจบวีดีโอ โดยผลลัพธ์จะออกมาเป็นวีดีโอไฟล์ (output.mp4) ซึ่งหากต้องการเปลี่ยนไปใช้อัลกอริทึมอื่นสามารถปรับบรรทัด cv2.TrackerGOTURN_create() เป็นอย่างอื่นได้หาก OpenCV มีอัลกอริทึมอื่นรองรับ ส่วนด้านล่างนี้เป็นผลลัพธ์ที่เราทำการติดตามตัวบุคคลในวีดีโอ

เป็นไงบ้างครับการติดตามวัตถุโดยใช้ OpenCV Tracking API สามารถทำได้ง่ายขึ้นกว่าแต่ก่อนมาก จากการใช้งานพบว่าของบางชนิดที่ไม่ได้เรียนรู้ไว้ไม่สามารถทำงานได้ดีเทียบกับอัลกอริทึมแบบไม่ใช้ Deep Learning จึงยังมีข้อจำกัดในการใช้งานอยู่มาก ซึ่งผมพยายามสร้างโมเดลใหม่อยู่ครับ ถ้ามีผลอย่างไรจะเอามาแชร์ในครั้งถัดไปนะครับ