# ทดลองจริง: ประเมิน trajectory และสอบเทียบกล้อง

ผลวันที่ 28 กันยายน 2026 ใช้ **trajectory ที่มีอยู่แล้วในตัวอย่างของ evo** และภาพกระดานหมากรุกจริงจาก OpenCV ไม่ใช่ผลจากการรัน OpenVINS ใหม่ และยังไม่ใช่การสอบเทียบกล้องกับ IMU

## ผลที่วัดได้

| รายการ | ผล | เงื่อนไข |
|---|---:|---|
| APE translation RMSE | 0.091727 เมตร | จับคู่ 798 poses, จัดแนว SE(3), ไม่ปรับ scale |
| RPE translation RMSE | 0.057522 เมตร | 79 คู่แบบ consecutive ระยะห่าง 10 frames ที่จับคู่แล้ว |
| Reprojection RMS ชุด fit | 0.451398 พิกเซล | 10 ภาพ รวม 540 จุด |
| Reprojection RMS ชุด holdout | 0.217797 พิกเซล | 3 ภาพ รวม 162 จุด; fit pose ของแต่ละภาพใหม่ |

![Trajectory และ APE จากข้อมูลจริง](vio-evo-trajectory.png)

Tolerance สำหรับจับคู่เวลาเท่ากับ 0.010 วินาที ได้ 798 poses จาก estimate 807 poses และ reference 16,702 poses ครอบคลุม 79.3 วินาที ความต่างเวลาสูงสุดของคู่ที่ใช้ประมาณ 0.000000954 วินาที การจัดแนวใช้ข้อมูลอ้างอิงทั้งช่วง จึงเป็นการวิเคราะห์ย้อนหลัง ไม่ใช่ความแม่นยำของการนำทางออนไลน์

**10 frames ไม่เท่ากับ 1 วินาทีเสมอไป** คู่ RPE ในการทดลองนี้ห่างกันจริงประมาณ 0.900–1.000 วินาที evo 1.37.1 ไม่รองรับ `--delta_unit s` จึงรายงานหน่วย frames ตามคำสั่งจริง

## สอบเทียบกล้องและตีความ holdout

ตรวจพบ internal corners 9 × 6 จุดในภาพ 640 × 480 ทั้ง 13 ภาพ กำหนด `left03.jpg`, `left07.jpg`, `left12.jpg` เป็น holdout **ก่อนตรวจจุดหรือ fit** อีก 10 ภาพใช้หา intrinsics และ distortion แบบ pinhole 5 coefficients ด้วย `calibrateCamera` ส่วน `left10.jpg` ไม่มีในต้นทาง (404) ไม่ได้ถูกตัดออกเพราะผลไม่ดี

ได้ fx = 536.527775, fy = 536.440557, cx = 342.307650 และ cy = 235.960790 **พิกเซล** ขนาดช่องกระดานกำหนดเป็น 1 หน่วยสมมติ เพราะยังไม่ทราบขนาดจริง จึงไม่อ้างระยะกล้องถึงกระดานเป็นเมตร

![Residual แยกตามภาพ; สีส้มคือ holdout](vio-calibration-reprojection.png)

เมื่อประเมิน holdout จะตรึง intrinsics/distortion แต่ใช้ `solvePnP` หา pose จาก **ทุกจุดในภาพ holdout นั้น** จึงเป็น residual ของภาพที่ไม่ได้ใช้ fit intrinsics ไม่ใช่การทำนายจุดใหม่ที่ไม่เคยใช้ fit pose ค่า holdout ต่ำกว่าชุด fit ไม่ได้พิสูจน์ว่าโมเดลจะใช้ได้ดีกับภาพใหม่ทั่วไป

ภาพ `left02.jpg` มี RMS สูงสุด 1.212296 พิกเซล และ residual จุดสูงสุด 4.789951 พิกเซล ยังคงรวมไว้ในผล ไม่มีการเลือกตัดภาพหลังเห็นค่าผิดพลาด

## เตรียมข้อมูลและรันซ้ำ

ดาวน์โหลด [สคริปต์](vio-calibration-check.py) และ [หลักฐาน JSON](vio-calibration-evidence.json) แล้วใช้ Python 3.12 ใน virtual environment แยก รุ่นที่รันจริงคือ evo 1.37.1, OpenCV 5.0.0, NumPy 2.5.2 และ Matplotlib 3.11.1 ภาพต้นทางมาจาก tag OpenCV **4.12.0** ซึ่งต่างจากรุ่น runtime

1. ใน JSON ให้นำ `sources.trajectory` บันทึกเป็น `trajectory/manifest.json` และ `sources.images` เป็น `images/manifest.json`
2. ดาวน์โหลดแต่ละไฟล์จาก `url` ใน manifest ลงโฟลเดอร์นั้น โดยใช้ชื่อ `name` ตรวจ `sha256` ให้ตรง ข้ามรายการ 404 ของ `left10.jpg` ข้อมูลทั้งหมดประมาณ 3.36 MB สคริปต์ตรวจ hash ซ้ำก่อนและหลังประมวลผล
3. รันแบบ offline ในสภาพแวดล้อมจำกัดทรัพยากร ให้ข้อมูลและเครื่องมือเป็น read-only และให้เขียนได้เฉพาะ scratch/output:

```sh
python vio-calibration-check.py --trajectory-dir trajectory --images-dir images --out results
```

คำสั่ง evo ที่ใช้จริงเทียบเท่ากับ:

```sh
evo_ape euroc trajectory/V102_groundtruth.csv trajectory/V102.txt --align --pose_relation trans_part --t_max_diff 0.01 --save_results ape.zip
evo_rpe euroc trajectory/V102_groundtruth.csv trajectory/V102.txt --align --pose_relation trans_part --t_max_diff 0.01 --delta 10 --delta_unit f --save_results rpe.zip
```

สคริปต์เปรียบเทียบผล CLI กับ Python API ของ evo และคำนวณ reprojection RMS กลับจากจุดที่ฉายใหม่ ผลตรงกันตาม tolerance ที่กำหนด การตรวจ CLI/API เป็นการตรวจความสอดคล้องของการเรียกใช้ ไม่ใช่การตรวจอัลกอริทึมด้วย implementation อิสระ `passed: true` หมายถึงการตรวจซอฟต์แวร์เหล่านี้ผ่าน ไม่ใช่ใบรับรองความพร้อมบิน

การรันที่บันทึกใช้ WSL Ubuntu จำกัด CPU 2 cores, virtual memory 6 GiB, CPU time 280 วินาที, wall timeout 300 วินาที, 128 processes, 256 open files, ขนาดไฟล์ 32 MiB และ scratch 256 MiB ไม่มี external network หรืออุปกรณ์บิน ข้อมูลและ toolchain เป็น read-only

## แหล่งที่มาและงานที่ยังไม่ผ่านการตรวจ

- [ข้อมูลตัวอย่าง evo แบบตรึง commit](https://github.com/MichaelGrupp/evo/tree/bc52497d7f403bf2afb25be3f760f3d6be1432c1/test/data) และ [คำอธิบาย metrics](https://github.com/MichaelGrupp/evo/wiki/Metrics)
- [ภาพตัวอย่าง OpenCV 4.12.0](https://github.com/opencv/opencv/tree/4.12.0/samples/data) และ [คู่มือ camera calibration](https://docs.opencv.org/4.12.0/dc/dbb/tutorial_py_calibration.html)
- [รายละเอียดภาษาอังกฤษและข้อจำกัดทั้งหมด](vio-calibration-guide.md)

ชุดบทเรียนเผยแพร่สคริปต์ที่เขียนขึ้น กราฟผล และหลักฐานตัวเลข ไม่แจกภาพหรือ trajectory ดิบของบุคคลที่สามซ้ำ ให้รับข้อมูลจากเจ้าของต้นทางและตรวจสิทธิ์ก่อนนำไปแจกต่อ URL และ hash ของแต่ละไฟล์อยู่ใน JSON

ยังไม่ได้รัน OpenVINS ใหม่หรือ EuRoC เต็มชุด ไม่ได้ตรวจ ROS, Kalibr, camera–IMU extrinsics, time offset, stereo calibration, ขนาดกระดานจริง หรือฮาร์ดแวร์/การบิน ผลนี้ยืนยันเส้นทางการประเมิน trajectory และการสอบเทียบ **กล้องอย่างเดียวด้วยภาพตัวอย่าง** เท่านั้น
