โมดูล 4/5 · สัปดาห์ 10–12 · 27 ชม.

กล้องและการสอบเทียบ

UAT 205 เซนเซอร์และระบบเครื่องมือวัด

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

บทเรียน

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

  1. อธิบายโมเดลกล้อง pinhole และค่าภายใน (intrinsics) เช่น ความยาวโฟกัสเป็นพิกเซลและจุดศูนย์กลางภาพ
  2. คำนวณผลของความบิดเบี้ยวของเลนส์แนวรัศมีต่อตำแหน่งพิกเซลและระยะบนพื้น
  3. อธิบายการสอบเทียบกล้องด้วยแผ่นลายหมากรุกตามวิธีของ Zhang
  4. ประเมินผลสอบเทียบด้วย reprojection error และระบุนิยามที่ใช้

ความรู้พื้นฐานที่ควรมี: UAT 205 โมดูล 1 · UAT 315 โมดูล 1 (ภาพคืออาร์เรย์ของตัวเลข)

ทำไมต้องรู้

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

โมเดลกล้อง pinhole

โมเดล pinhole ถือว่าแสงทุกเส้นผ่านจุดเดียว เรียกว่า จุดศูนย์กลางการฉาย จุดในโลกที่ ไปตกบนระนาบภาพที่ (พิกัดปกติ) แล้วแปลงเป็นพิกเซลด้วย ความยาวโฟกัสเป็นพิกเซล โดย คือขนาดพิกเซล และ จุดศูนย์กลางภาพ ค่าเหล่านี้เรียกรวมว่า ค่าภายใน (intrinsics) เขียนเป็นเมทริกซ์ (Hartley และ Zisserman, 2004; Szeliski, 2022)

มุมมองด้านข้าง จุดศูนย์กลางการฉายทางซ้าย ระนาบภาพเป็นเส้นแนวตั้งสีฟ้าห่างออกไประยะ f จุดสีชมพูในโลกที่ X, Z ทางขวาบน เส้นสีชมพูจากจุดในโลกผ่านระนาบภาพที่ตำแหน่ง x ไปยังจุดศูนย์กลางการฉาย เส้นประแนวนอนคือแกนแสงระยะ Z
ภาพที่ 1 โมเดลกล้อง pinhole

ความบิดเบี้ยวของเลนส์

เลนส์จริงงอแสงไม่เท่ากันทั่วภาพ โมเดลของ Brown (1966) ที่ OpenCV ใช้มี ความบิดเบี้ยวแนวรัศมี และ แนวสัมผัส เลนส์มุมกว้างบนโดรนมักมี ติดลบ เรียกว่า barrel distortion ภาพยิ่งห่างศูนย์กลางยิ่งถูกดึงเข้า เส้นตรงที่ขอบภาพจึงโค้ง

ตารางเส้นประสีเทาคือตารางที่ไม่บิดเบี้ยว ตารางเส้นทึบสีฟ้าซ้อนอยู่ ตรงกลางเกือบทับกัน แต่ยิ่งออกไปทางขอบและมุมเส้นสีฟ้ายิ่งโค้งเข้าหาศูนย์กลางเป็นรูปถัง ค่า k1 ลบ 0.12 และ k2 0.03
ภาพที่ 2 ความบิดเบี้ยวแบบถังของเลนส์

ตัวอย่างที่ 1 ความบิดเบี้ยวทำให้ระยะบนพื้นผิดเท่าใด

กล้องความยาวโฟกัส 8.8 mm พิกเซล 3.3 µm ภาพกว้าง 4,000 พิกเซล มองตรงลงจากความสูง 100 m เลนส์มี , (ค่าสมมติ)

FX = 8.8e-3 / 3.3e-6          # ความยาวโฟกัสเป็นพิกเซล
CX = 2000.0
K1, K2 = -0.12, 0.03
Z = 100.0                     # m ความสูง
GSD = Z / FX                  # m ต่อพิกเซลที่ศูนย์กลางภาพ

print(f"fx {FX:.1f} px, GSD {GSD * 100:.2f} cm/px")
for X in (0, 10, 30, 50, 70):
    x = X / Z
    r2 = x * x
    xd = x * (1 + K1 * r2 + K2 * r2 * r2)
    u_ideal, u_real = FX * x + CX, FX * xd + CX
    shift = u_ideal - u_real
    print(f"X {X:>2} m: ideal u {u_ideal:7.1f}, distorted u {u_real:7.1f}, "
          f"shift {shift:5.1f} px = {shift * GSD:.2f} m on the ground")
fx 2666.7 px, GSD 3.75 cm/px
X  0 m: ideal u  2000.0, distorted u  2000.0, shift   0.0 px = 0.00 m on the ground
X 10 m: ideal u  2266.7, distorted u  2266.3, shift   0.3 px = 0.01 m on the ground
X 30 m: ideal u  2800.0, distorted u  2791.6, shift   8.4 px = 0.32 m on the ground
X 50 m: ideal u  3333.3, distorted u  3295.8, shift  37.5 px = 1.41 m on the ground
X 70 m: ideal u  3866.7, distorted u  3770.4, shift  96.3 px = 3.61 m on the ground

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

สอบเทียบกล้องด้วยวิธีของ Zhang

Zhang (2000) เสนอวิธีที่ใช้แผ่นลวดลายระนาบ เช่น ลายหมากรุก ถ่ายหลายภาพหลายมุม ซอฟต์แวร์หามุมของช่องในทุกภาพ แล้วหาค่า ค่าความบิดเบี้ยว และท่าของแผ่นในแต่ละภาพที่ทำให้มุมที่ฉายกลับตรงกับมุมที่ตรวจพบมากที่สุด บทเรียนการสอบเทียบของ OpenCV ใช้วิธีนี้ ประเด็นสำคัญคือ

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

ตัววัดคุณภาพคือ reprojection error ผลต่างระหว่างมุมที่ตรวจพบกับมุมที่ฉายกลับด้วยค่าที่หาได้ หน่วยความรู้ F16 ของคลังความรู้โดรนเตือนว่ามีสองนิยาม คือ RMS ต่อจุด (หารด้วย ) กับ RMS ต่อแกน (หารด้วย ) ซึ่งต่างกัน √2 เท่า รายงานจึงต้องบอกนิยามเสมอ

ตัวอย่างที่ 2 reprojection error รายภาพ

ค่าคลาด (dx, dy) เป็นพิกเซลของสี่มุมในห้าภาพ (ข้อมูลสมมติ ย่อจากชุดจริงที่มีหลายสิบมุมต่อภาพ)

import math
import statistics as st

residuals = {
    "img01": [(0.2, -0.1), (-0.3, 0.2), (0.1, 0.1), (0.0, -0.2)],
    "img02": [(0.1, 0.3), (-0.2, -0.1), (0.2, 0.0), (-0.1, 0.2)],
    "img03": [(1.8, -1.2), (2.1, 0.9), (-1.6, 1.5), (1.9, -1.4)],
    "img04": [(-0.2, 0.1), (0.3, -0.2), (0.1, 0.2), (-0.1, -0.1)],
    "img05": [(0.2, 0.2), (-0.1, 0.1), (0.0, -0.3), (0.2, -0.1)],
}

def rmse(pts, per_axis=False):
    total = sum(dx * dx + dy * dy for dx, dy in pts)
    return math.sqrt(total / (len(pts) * (2 if per_axis else 1)))

every = [p for pts in residuals.values() for p in pts]
print(f"all images: {rmse(every):.3f} px per point, {rmse(every, True):.3f} px per axis")
per_image = {k: rmse(v) for k, v in residuals.items()}
limit = 2 * st.median(per_image.values())
for k, v in per_image.items():
    print(f"{k}: {v:.3f} px {'<- check this image' if v > limit else ''}")
kept = [p for k, pts in residuals.items() if per_image[k] <= limit for p in pts]
print(f"without flagged images: {rmse(kept):.3f} px per point")
all images: 1.031 px per point, 0.729 px per axis
img01: 0.245 px
img02: 0.245 px
img03: 2.252 px <- check this image
img04: 0.250 px
img05: 0.245 px
without flagged images: 0.246 px per point

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

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

ปฏิบัติการ: สอบเทียบกล้องด้วย OpenCV

  1. พิมพ์แผ่นลายหมากรุก วัดขนาดช่องจริงด้วยเวอร์เนียร์ ติดบนแผ่นแข็งที่เรียบ
  2. ถ่ายอย่างน้อย 20 ภาพหลายมุม ให้แผ่นอยู่ทั่วภาพและที่ขอบ ล็อกโฟกัส
  3. ทำตามบทเรียนการสอบเทียบของ OpenCV (หรือปฏิบัติการ L11 ในคลังความรู้โดรน) บันทึก ค่าความบิดเบี้ยว และ reprojection error พร้อมนิยาม
  4. ใช้โค้ดตัวอย่างที่ 2 หาภาพที่ผิดปกติ เปิดดูสาเหตุ แล้วสอบเทียบใหม่
  5. แก้ความบิดเบี้ยวของภาพถ่ายทางอากาศหนึ่งภาพ เทียบเส้นตรงที่ขอบภาพก่อนและหลัง

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

ระวัง

  • ใส่ขนาดช่องผิดหน่วย
  • ถ่ายแผ่นเฉพาะกลางภาพ
  • เปลี่ยนความละเอียดหรือซูม หลังสอบเทียบ
  • รายงาน reprojection error โดยไม่บอกนิยาม
  • ตัดภาพที่ค่าคลาดสูงทิ้งโดยไม่ดูสาเหตุ

สรุป

  • โมเดล pinhole ฉายจุดด้วย และ ซึ่งเป็นค่าภายในของกล้อง
  • เลนส์จริงมีความบิดเบี้ยวแนวรัศมีและแนวสัมผัส ผลมากที่สุดที่ขอบภาพ
  • วิธีของ Zhang ใช้ภาพแผ่นระนาบหลายมุมหาค่าภายในและความบิดเบี้ยว
  • reprojection error ต้องบอกนิยาม ตรวจรายภาพ และตรวจด้วยชุดภาพอิสระ

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

  1. ความยาวโฟกัส 4.5 mm พิกเซล 1.5 µm ได้ เท่าใด
  2. จุดที่ m, m, , ตกที่พิกเซล เท่าใด (ไม่คิดความบิดเบี้ยว)
  3. barrel distortion มีเครื่องหมาย อย่างไร
  4. RMS ต่อจุด 0.5 px เท่ากับ RMS ต่อแกนเท่าใด
  5. ทำไมต้องถ่ายแผ่นลายหมากรุกให้อยู่ที่ขอบภาพด้วย
เฉลย
  1. px
  2. ติดลบ
  3. px
  4. ความบิดเบี้ยวมากที่สุดที่ขอบ ถ้าไม่มีข้อมูลที่ขอบ ค่าที่ได้จะไม่แม่นในบริเวณนั้น

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

การฉายภาพแบบ pinhole
ความบิดเบี้ยวแนวรัศมี
reprojection RMSE ต่อจุด

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

  1. Zhang, Z. (2000). A flexible new technique for camera calibration. IEEE Transactions on Pattern Analysis and Machine Intelligence, 22(11), 1330–1334. link
  2. Brown, D. C. (1966). Decentering distortion of lenses. Photogrammetric Engineering, 32(3), 444–462.
  3. OpenCV. Camera calibration (Python tutorial). OpenCV 4.x documentation. link
  4. Hartley, R., & Zisserman, A. (2004). Multiple view geometry in computer vision (2nd ed.). Cambridge University Press. link
  5. Szeliski, R. (2022). Computer vision: Algorithms and applications (2nd ed.). Springer. link

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

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

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

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

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

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

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

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