เบื้องหลังระบบตรวจจับและระบุพิกัดโดรนบน Raspberry Pi 5
ระบบที่ใช้กล้องตัวเดียวตรวจจับโดรนบนท้องฟ้า ติดตามการเคลื่อนที่ และคำนวณพิกัด GPS กับความสูงของโดรน โดยทำงานบนบอร์ด Raspberry Pi 5 ที่ไม่มีชิป AI เสริม พัฒนาขึ้นสำหรับการแข่งขัน TESA Top Gun Rally 2025 สาย Defensive (ทำ 3 วัน 11–13 พ.ย. 2568) หลังการแข่งขันได้นำระบบกลับมาทดสอบใหม่อย่างเข้มงวด พบข้อผิดพลาดหลายจุด จึงแก้ไขแล้ววัดผลซ้ำ ตัวเลขทุกตัวในบทความนี้วัดจากข้อมูลที่โมเดลไม่ได้ใช้ฝึก
ผลลัพธ์โดยสรุป
-
ตรวจจับโดรนในภาพที่โมเดลไม่เคยเห็น (โดรน 10 ลำ): จากเจอ 0 ลำ → เจอ 9 ลำ
-
นับจำนวนโดรนในภาพได้ถูกต้อง (43 ภาพ): 62.8% → 90.7%
-
ความคลาดเคลื่อนของพิกัด (คะแนนตามสูตรการแข่งขัน ยิ่งต่ำยิ่งดี): 8.84 → 6.96
-
เป้าหลอกที่ถูกติดตามในวิดีโอ 64 วินาที: 9 → 2
-
ความเร็วบน Raspberry Pi 5 (วิดีโอ 1080p): 12.5–16.9 เฟรมต่อวินาที
คลิปตัวอย่างผลลัพธ์จากระบบจริง
ผลลัพธ์จริงของระบบบนวิดีโอจากการแข่งขัน: โดรนทั้ง 2 ลำคงหมายเลข 1 และ 2 ตลอดวิดีโอ 65 วินาที
โจทย์และข้อจำกัด
การแข่งขันมี 3 โจทย์:
-
ตรวจจับโดรนในภาพ: หาโดรนทุกลำในภาพความละเอียด 1920×1080
-
ระบุพิกัด: บอกละติจูด ลองจิจูด และความสูงของโดรน จากภาพของกล้องที่ตั้งอยู่กับที่
-
ติดตามในวิดีโอ: ให้หมายเลขประจำโดรนแต่ละลำ แสดงพิกัดบนจอ และส่งข้อมูลแจ้งเตือน (First Alert)
ข้อจำกัดสำคัญคือต้องรันบน Raspberry Pi 5 ด้วย CPU อย่างเดียว ไม่มีชิป AI และไม่มีเซนเซอร์วัดระยะอย่าง LiDAR ส่วนความยากหลักคือโดรนที่บินอยู่ไกลมีขนาดในภาพเพียง 10–30 พิกเซล
ระบบทำงานอย่างไร: 5 ขั้นตอน
ขั้นตอนที่ 1: ภาพจากกล้องสถานีตรวจการณ์
ภาพท้องฟ้ามุมกว้าง โดรนที่อยู่ไกลมีขนาดเล็กมากและกลืนไปกับก้อนเมฆ

ขั้นตอนที่ 2: หาจุดต้องสงสัยด้วยการประมวลผลภาพ (Morphology)
แปลงภาพเป็นขาวดำ แยกวัตถุสีเข้มออกจากท้องฟ้าสว่าง แล้วขยายจุดเล็ก ๆ ของลำตัวและใบพัดให้รวมเป็นก้อนเดียว พร้อมตัดแถบตัวเลขวันที่บนภาพและแนวต้นไม้ด้านล่างทิ้ง ขั้นตอนนี้ใช้เวลาเพียงราว 12 มิลลิวินาทีต่อภาพบน Raspberry Pi 5

ขั้นตอนที่ 3: ยืนยันด้วย AI เฉพาะบริเวณที่สงสัย (YOLO11-OBB)
แทนที่จะย่อภาพทั้งภาพให้ AI ดู ระบบจะ ครอปภาพความละเอียดเต็มขนาด 320×320 พิกเซล รอบจุดต้องสงสัยแต่ละจุด แล้วให้โมเดล YOLO11 ขนาดเล็ก (Nano) ตรวจทีละส่วน แนวคิดนี้ได้แรงบันดาลใจจาก SAHI ที่หั่นภาพใหญ่เป็นชิ้นเล็กเพื่อรักษารายละเอียด แต่ระบบนี้ตรวจเฉพาะจุดที่มีวัตถุ จึงประหยัดเวลากว่ามาก จุดใดที่ AI ยืนยันแต่การประมวลผลภาพไม่ได้พบด้วย จะถูกตัดทิ้ง วิธีนี้กำจัดวัตถุที่อยู่นิ่ง เช่น ตัวเลขวันที่และหลังคาสนาม ซึ่ง AI มักคิดว่าเป็นโดรนแต่ว่ามันไม่ใช่

ขั้นตอนที่ 4: ติดตามเป้าหมาย (Tracking)
จับคู่ตำแหน่งโดรนระหว่างเฟรมเพื่อให้หมายเลขประจำตัว (track_id) คงที่
-
ยืนยันเป้าหมาย: ต้องเห็นต่อเนื่อง 3 เฟรมจึงจะนับเป็นโดรน
-
ทนต่อการหายชั่วคราว: จำเป้าหมายไว้ได้นานถึง 30 เฟรมเมื่อมองไม่เห็นชั่วขณะ
-
กันนกและเศษวัตถุ: การเริ่มติดตามเป้าหมายใหม่ต้องมี AI ยืนยันเสมอ

ขั้นตอนที่ 5: คำนวณพิกัดและแสดงผล
นำตำแหน่งและขนาดของกรอบโดรนไปคำนวณพิกัดจริง (ละติจูด ลองจิจูด ความสูง) ด้วยโมเดล Machine Learning น้ำหนักเบา ใช้เวลาราว 1–1.5 มิลลิวินาทีต่อโดรนบน Raspberry Pi 5 แล้วแสดงผลบนหน้าจอ

สิ่งที่ค้นพบเมื่อทดสอบจริง ๆ
ช่วงแข่งขันมีเวลาเพียง 3 วัน ตัวเลขที่รายงานในตอนนั้นดูดีมาก เช่น ความแม่นยำ 97.7% แต่เมื่อตรวจสอบย้อนหลังพบว่าวัดจากภาพตรวจสอบเพียง 3 ภาพ และส่วนระบุพิกัดวัดบนภาพชุดเดียวกับที่ใช้ฝึก จึงได้ทดสอบใหม่ด้วยข้อมูลที่โมเดลไม่เคยเห็น และพบปัญหา 4 จุด
1. ขั้นตอนเตรียมภาพทำให้ AI มองไม่เห็นโดรน
ระบบเดิมหรี่ส่วนอื่นของภาพให้มืดลง แล้วย่อทั้งภาพให้เล็กก่อนส่งเข้า AI ทำให้โดรนเหลือเพียงราว 4×3 พิกเซล ผลคือบนภาพทดสอบชุดใหม่ ระบบตรวจไม่พบโดรนเลยแม้แต่ลำเดียว เมื่อเปลี่ยนเป็นครอปภาพความละเอียดเต็มรอบจุดต้องสงสัย ระบบตรวจพบ 9 จาก 10 ลำ

2. AI ทักวัตถุที่อยู่นิ่งว่าเป็นโดรนในทุกภาพ
โมเดลมองหลังคาสนามและตัวเลขวันที่บนภาพว่าเป็นโดรนซ้ำทุกเฟรม แก้โดยให้นับเฉพาะกรอบที่การประมวลผลภาพพบวัตถุตรงจุดเดียวกันด้วย
3. ข้อมูลที่ใช้ฝึกไม่ตรงกับตอนใช้งานจริง
สคริปต์ฝึกโมเดลพิกัดเลือกกรอบด้วยวิธีที่ต่างจากตอนใช้งาน และใน 322 จาก 438 ภาพ เลือกไปโดนตัวเลขวันที่บนภาพแทนโดรน แก้โดยให้ทั้งการฝึกและการใช้งานผ่านขั้นตอนตรวจจับชุดเดียวกัน
4. วิธีวัดผลเดิมให้ตัวเลขดีเกินจริง
ภาพสำหรับระบุพิกัด 438 ภาพเป็นเฟรมต่อเนื่องจากเที่ยวบินเพียง 4–5 เที่ยว ถ้าสุ่มแบ่งภาพไปฝึกและทดสอบ ภาพทดสอบจะมีภาพข้างเคียงที่แทบเหมือนกันอยู่ในชุดฝึก จึงได้คะแนนดีเกินจริงราว 2 เท่า การวัดผลใหม่จึงกันทั้งช่วงเที่ยวบินออกไปทดสอบ (blocked cross-validation) ซึ่งใกล้เคียงการใช้งานจริงมากกว่า

ระบุพิกัด 3 มิติจากกล้องตัวเดียว
กล้องตั้งอยู่กับที่และรู้ตำแหน่ง GPS ของตัวเอง ตำแหน่งของโดรนในภาพจึงบอกข้อมูลได้มาก:
-
ทิศทาง (ซ้าย–ขวา) และมุมเงย (บน–ล่าง): ดูจากตำแหน่งของโดรนในภาพ
-
ระยะห่าง: ดูจากขนาดของกรอบโดรน ยิ่งไกล กรอบยิ่งเล็ก
โมเดลทำนายทิศทาง ระยะห่าง และความสูงเทียบกับกล้อง แล้วแปลงเป็นละติจูด ลองจิจูด และความสูงจากระดับน้ำทะเล การทำนายค่าในมุมมองของกล้องแทนการทำนายพิกัด GPS ตรง ๆ ช่วยลดความคลาดเคลื่อนลงได้ชัดเจน

ผลบนช่วงเที่ยวบินที่โมเดลไม่ได้ใช้ฝึก (ค่ากลาง หรือ median):
-
ทิศทางจากกล้อง: คลาดเคลื่อน 3.4 องศา
-
ระยะห่างแนวราบ: คลาดเคลื่อน 6.4 เมตร
-
ความสูง: คลาดเคลื่อน 6.2 เมตร
จุดอ่อนที่เห็นชัดในกราฟคือ โดรนที่บินไกลและสูงกว่าที่เคยเห็นตอนฝึก (ช่วงภาพที่ 100–180) ระบบจะทายระยะและความสูงต่ำกว่าความจริง เพราะไม่มีตัวอย่างระยะนั้นในข้อมูลฝึก
รันบน Raspberry Pi 5 จริง
ทดสอบบน Raspberry Pi 5 (แรม 8 GB) ที่ติดพัดลมระบายความร้อน ใช้ CPU อย่างเดียว รวมทุกขั้นตอน ตั้งแต่อ่านวิดีโอไปจนถึงบันทึกวิดีโอผลลัพธ์

-
NCNN ทำให้เร็วขึ้นมาก: แปลงโมเดลไปใช้ NCNN ซึ่งเป็นตัวรันโมเดลที่ออกแบบมาสำหรับชิป ARM ทำให้ AI ตรวจแต่ละจุดใช้เวลา 16 มิลลิวินาที จากเดิม 105 มิลลิวินาที (เร็วขึ้นราว 6.7 เท่า) โดย ความแม่นยำเท่าเดิมทุกตัวเลข
-
ไม่ร้อนจนช้าลง: อุณหภูมิสูงสุด 60 °C และบอร์ดไม่ลดความเร็วจากความร้อนตลอดการทดสอบ
-
ยังไม่ถึงความเร็ววิดีโอ: ได้ 12.5–16.9 เฟรมต่อวินาที เทียบกับวิดีโอ 25 เฟรมต่อวินาที จึงประมวลผลแบบสดได้ราวครึ่งถึงสองในสามของเฟรมทั้งหมด
การแจ้งเตือนฉุกเฉิน (First Alert)
เมื่อยืนยันพบโดรนครั้งแรก ระบบสร้างข้อมูลแจ้งเตือนเป็น JSON พร้อมภาพหลักฐาน และส่งผ่าน HTTP ไปยังศูนย์บัญชาการได้ (ปิดไว้เป็นค่าเริ่มต้น) ตัวอย่างด้านล่างเป็นผลลัพธ์จริงจากวิดีโอการแข่งขัน ระบบยืนยันโดรนทั้ง 2 ลำได้ตั้งแต่เฟรมที่ 3
{
"station_id": "STATION_ALPHA",
"camera_position": { "latitude": 14.305029, "longitude": 101.17301, "altitude_msl": 37.2 },
"alert_type": "FIRST_DETECTION",
"total_drones_detected": 2,
"objects": [
{
"frame_id": 3, "track_id": 1, "classification": "Drone", "confidence": 0.9527,
"latitude": 14.304929, "longitude": 101.172532, "altitude_msl": 46.39,
"velocity_mps": null, "direction_deg": null,
"bbox": { "center_x": 1739, "center_y": 497, "width": 34, "height": 20 }
},
{
"frame_id": 3, "track_id": 2, "classification": "Drone", "confidence": 0.626,
"latitude": 14.304459, "longitude": 101.172516, "altitude_msl": 57.69,
"velocity_mps": null, "direction_deg": null,
"bbox": { "center_x": 650, "center_y": 396, "width": 15, "height": 9 }
}
],
"image_base64": "/9j/4AAQSkZJRgABAQAAAQAB..."
}
ความเร็ว (velocity_mps) และทิศทางการบิน (direction_deg) ยังไม่ได้คำนวณ จึงส่งเป็น null
ข้อจำกัดที่ยังมี
-
ชุดทดสอบเล็ก: การตรวจจับทดสอบบน 15 ภาพ (โดรน 10 ลำ) ผลต่างก่อนและหลังชัดเจนมาก แต่ตัวเลขยังมีความไม่แน่นอนสูง
-
ไม่มีข้อมูลเฉลยสำหรับการติดตาม: จึงยังวัดค่ามาตรฐานอย่าง MOTA หรือจำนวนครั้งที่สลับหมายเลขไม่ได้ ผลการติดตามข้างต้นวัดจากวิดีโอที่รู้จำนวนโดรนแน่นอน และโดรนไม่ได้บินตัดกัน
-
ยังไม่ถึง 25 เฟรมต่อวินาทีบน Raspberry Pi 5
-
ระบุพิกัดได้แย่ลงเมื่อโดรนอยู่ไกลกว่าที่เคยเห็นตอนฝึก
-
ส่วนรายงานผล: คะแนนอย่างเป็นทางการของการแข่งขันใช้ชุดทดสอบลับ จึงไม่ได้รวมไว้ในบทความนี้
สิ่งที่ได้เรียนรู้
-
ตัวเลขที่ดีเกินไปควรถูกตรวจสอบก่อนเชื่อ: ต้องรู้ว่าวัดจากข้อมูลชุดไหน และโมเดลเคยเห็นข้อมูลนั้นตอนฝึกหรือไม่
-
ขั้นตอนเตรียมภาพที่ดูเหมือนช่วย อาจทำให้ AI มองไม่เห็นเป้าหมาย: ควรดูภาพที่ AI ได้รับจริงทุกครั้ง
-
ข้อมูลวิดีโอต้องแบ่งตามช่วงเวลา ไม่ใช่สุ่มทีละภาพ: มิฉะนั้นคะแนนจะสูงเกินจริง
-
ต้องวัดบนฮาร์ดแวร์จริง: บน Raspberry Pi ตัวรันโมเดล (PyTorch หรือ NCNN) ทำให้ความเร็วต่างกันหลายเท่า ทั้งที่โมเดลเป็นตัวเดียวกัน
โค้ดและสคริปต์วัดผลทั้งหมด: github.com/PS-Open-Fruit/AI-Drone-Detection
