Object tracking with OpenCV in python
Face detection with FaceNet, OpenCV for tracking
อีกหนึ่ง Topic ที่น่าสนใจเกี่ยวกับงาน Computer vision นอกเหนือจาก Object detection แล้วคือ Object tracking ที่นิยมใช้งานร่วมกันเพื่อให้เกิดผลลัพธ์ที่ดีขึ้น เช่น การใช้งาน Tracking ในกล้องวงจรปิดทั้งหลาย Blog ตอนนี้เป็นการนำ Object tracking มาใช้ร่วมกับ Face detection ด้วย OpenCV ในภาษา Python
Object tracking
Object tracking คือ Process ต่อเนื่องจาก Object detection เป็นขั้นตอนที่ช่วยลดการใช้ทรัพยากรจากการประมวลผล ยกตัวอย่างกรณีที่ Object tracking เข้ามามีบทบาท เช่นกรณีที่ Object ไม่ได้มี Movement มากนัก ตัวอย่างเช่น หากต้องการ Detect หน้าของผู้ประกาศข่าวที่อยู่ในโทรทัศน์ โดยธรรมชาติของรายการข่าว ส่วนมากแล้วผู้ประกาศข่าว ต้องมองที่กล้อง (หน้าจอทีวี) และอ่านข่าวไปเรื่อย ๆ
การที่ต้องใช้งาน Model ในการ Detect หน้าผู้ประกาศข่าว (Face detection) ซ้ำแบบ Frame by frame ตลอดเวลา อาจทำให้เสียทรัพยากรมากเกินไป ดังนั้นสามารถใช้ Object tracking เข้ามาลดการทำงานของ Face detection ส่วนนี้ได้
การทำงานของ Object tracking เกิดขึ้นต่อเนื่องทันทีหลังจากที่ Object detection ทำงานเสร็จแล้ว เมื่อใช้ Face detection ตรวจจับใบหน้าผู้ประกาศข่าวได้แล้ว สามารถใช้ Object tracker รับ Frame ที่เกิดขึ้นหลังจากนั้น และ Track object นั้น ๆ ต่อไปได้ โดยสามารถปิดการใช้งาน Face detection model เพื่อลดการใช้ทรัพยากรของเครื่อง
และเมื่อตัว Tracker ไม่สามารถจับ Object ได้อีกต่อไป เช่นในกรณีที่เปลี่ยน Frame อย่างรวดเร็ว ก็สามารถเรียก Detection model ขึ้นมาเพื่อ Detect ใหม่ และส่ง Frame ต่อให้ Tracker อีกทีตาม Process เดิมวนไปเรื่อย ๆ
Code
ส่วนที่เป็น Code ตอนนี้ไม่ได้ยาวมาก ดูจาก Libraries ที่ใช้งานจริง ๆ แค่ 2 ตัวเท่านั้น
จาก Process ที่ได้อธิบายไปก่อนหน้านี้ เริ่มแรกจำเป็นต้องมี Model สำหรับ Detect object ก่อน ซึ่ง Blog ตอนนี้ของใช้เป็นใบหน้าต่าง ๆ ที่อยู่ภายในคลิป Video ในตอนแรกได้ลอง HaarCascade classifier ใน OpenCV ตรง ๆ โดยใช้ไฟล์ XML haarcascade_frontalface_default.xml
แต่ปรากฎว่า Detect หน้าพลาดไปพอสมควร ดังนั้นจึงใช้เป็น FaceNet model ในการช่วย Detect object แทน
ต่อมาเป็น Object tracker ใน OpenCV มีให้เลือกใช้งานหลายตัว แต่ละตัวมีข้อดีข้อเสียแตกต่างกันไป เช่น BOOSTING Tracker ใช้ Machine learning ทำงานอยู่เบื้องหลัง หรือ KCF Tracker ที่มีจุดเด่นเรื่องความเร็ว แต่อาจแม่นยำน้อยกว่า เป็นต้น (Blog ตอนนี้ใช้ KCF Tracker)
Code ด้านบนทั้งหมดนี้เป็นการทำงานของ Face detection ร่วมกับ Object tracking อาจไม่ได้ลงรายละเอียดแบบ Line by line แต่จะอธิบายให้เห็นการทำงานของ Process นี้ทั้งหมด
- เริ่มต้นจากใช้
cv2.VideoCapture()
ในการอ่านไฟล์ Video และกำหนดขนาด Video เพื่อใช้ในการ Export cv2.VideoWriter()
ใช้สำหรับสร้าง Output object โดยให้เขียนเป็นไฟล์.avi
เนื่องจากมีปัญหาน้อยกว่า- เกิดใช้ While statement ให้กำหนดตัวแปร
tracking = False
หมายถึงยังไม่ให้ Object tracker เริ่มทำงาน เพราะต้องให้ Face detector ทำงานก่อน - ใช้ While statement รับตัวแปรจาก
cv2.VideoCapture()
เช็คเงื่อนไขที่ว่าtracking = False
จึงให้ Face detector เริ่มต้นทำงาน - ใช้ FaceNet model ในการ Detect ใบหน้า เมื่อเจอใบหน้าให้ Return ออกมาเป็นตำแหน่ง (x, y, x + w, y + h) จากนั้นวาดกรอบสีเหลี่ยมจากตำแหน่งที่เจอใบหน้า โดยที่กำหนดให้เป็นสีแดง เพื่อให้รู้ว่าใบหน้านี้เกิดจาก Face detection
- ต่อมาเมื่อได้ใบหน้าแล้วให้เริ่มการทำงานของ Object tracker ให้ใช้ Tracker ที่สร้างไว้
.init()
โดยรับค่าเป็น Frame นั้น ๆ และพิกัดของใบหน้าที่หาเจอ โดยที่ต้องรับค่าเป็น (x, y, w, h) ไม่ใช่ (x, y, x + w, y + h) ดังนั้นจึงคำนวณ w, h จาก FaceNet model ขึ้นมาใหม่ - สิ่งที่ Return จาก
.init()
เป็น Boolean(True/False) ให้เช็คเงื่อนไขว่าถ้า Tracker สามารถ Track object ได้ให้เปลี่ยนtracking = True
- เมื่อ
tracking = True
แล้ว เงื่อนไขที่ให้ Face detection เริ่มทำงานจึงไม่ Valid อีกต่อไป เนื่องจาก Tracker ยังสามารถทำงานได้อยู่ ให้.update()
ข้อมูลที่ผ่านเข้ามาทีละ Frame ไปเรื่อย ๆ - ถ้าสามารถ
.update()
Tracker ได้ให้วาดกรอบสีเหลี่ยมใหม่ โดยกำหนดให้เป็นสีเขียว เพื่อให้รู้ว่าใบหน้านี้เกิดจาก Object tracker ไม่ใช่จาก Face detector - แต่ถ้าไม่สามารถ
.update()
Tracker ได้ ให้เปลี่ยนtracking = False
และ Assign ตัวแปร Object tracker ใหม่ เพื่อให้ Face detector ทำงานแทนอีกครั้ง
Process ทั้งหมดนี้เกิดขึ้นตลอดจากความยาวของ Video บันทึกเป็นไฟล์ .avi
Result
ผลลัพธ์ที่ได้จาก Code ทั้งหมดเป็นไฟล์ Video ซึ่งได้ Upload ไว้บน YouTube แล้วตาม Link ด้านบน แต่หาก Play video ดูแล้วจะพบว่ากรอบที่วาดบนใบหน้า แทบจะเป็นสีเขียวตลอดเวลา เนื่องจากการเปลี่ยน Frame แล้วเปลี่ยนจาก Face detection เป็น Tracking อาจเกิดขึ้นอย่างรวดเร็ว (Frame by frame) ดังนั้นการดูทีละ Frame อาจทำให้เห็นผลลัพธ์ได้ชัดเจนกว่า
เริ่มต้น Video จะเห็นได้ว่า Face detection ทำงานเพียงประมาณ 2 Frames ก่อนเปลี่ยนไปใช้ Object tracking ทำงานต่อ
หรือเป็นภาพ 3 Frames นี้ โดยเริ่มจาก Frame แรกที่ Face detection ไม่สามารถจับใบหน้าได้ เพราะเพิ่ง Cut มาจาก Frame ก่อนหน้า แต่พอ Frame ต่อมา Face detection ทำงานและตรวจใบหน้าได้ และ Frame สุดท้ายถูกส่งต่อไปให้ Object tracking
Scene นี้เป็นจังหวะที่ Object มีการเคลื่อนที่อย่างรวดเร็ว (สบัดหัว) การทำงานของ Face detection ผิดพลาดตั้งแต่ตรวจจับใบหน้าพลาดไป ทำให้ส่ง Frame ต่อให้ Object tracking พลาดต่อเช่นกัน
ทั้งหมดนี้เป็นผลลัพธ์พร้อมการวิเคราะห์อย่างง่าย เพื่อให้เห็นภาพการทำงานของ Object trakcing ที่เกิดขึ้นจากการใช้งาน
Conclusion
ในความเป็นจริงแล้ว Object tracking สามารถสร้างอะไรได้เยอะกว่านี้มาก Blog ตอนนี้เป็นเพียงตัวอย่างการทำงานของ Tracker ใน OpenCV อย่างง่าย ในตอนต่อ ๆ ไปอาจมีการทำเป็น Multiple object tracking ที่มีความซับซ้อนมากขึ้น และใช้งานได้หลากหลายขึ้น
สำหรับ Colab notebook ของเนื้อหาตอนนี้ สามารถติดตามได้ที่ Link ด้านบน