5.22. การแก้ไขเลนส์และมุมมอง

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

5.22.1. ความผิดเพี้ยนของเลนส์แบบรัศมี

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

lens_corr() จะยกเลิกความผิดเพี้ยนนั้น เมธอดจะรันการแมปผกผัน: พิกเซลเอาต์พุตแต่ละตัวจะถูกสุ่มตัวอย่างจากตำแหน่งในอินพุตที่เลนส์จะโค้ง ออกมาจาก ตำแหน่งนั้น และผลลัพธ์คือภาพที่เส้นตรงถูกต้องตามหลักเรขาคณิต

img.lens_corr(strength=1.8)

พารามิเตอร์ strength คือหัวใจของการแก้ไข เป็นตัวเลขเดียวที่อธิบายว่าเลนส์โค้งงอมากแค่ไหน ค่าใกล้ 1.0 คือการแก้ไขเล็กน้อยสำหรับเลนส์มุมกว้างปานกลาง และค่าสูงถึงประมาณ 2.0 เหมาะสมสำหรับ fisheye แบบเข้มข้น ค่าเริ่มต้น 1.8 เป็นจุดเริ่มต้นที่เหมาะสมสำหรับเลนส์ OpenMV Cam มาตรฐาน ค่าที่เหมาะสมสำหรับเลนส์เฉพาะแต่ละตัวต้องลองค่าต่างๆ และสังเกตภาพ

พารามิเตอร์ด้านข้างสองตัวมักจะใช้ค่าเริ่มต้นได้ดี zoom (ค่าเริ่มต้น 1.0) ปรับขนาดเอาต์พุต ค่ามากกว่าหนึ่งจะครอปออกด้านนอกเพื่อชดเชยการที่การแก้ไขเลนส์ผลักมุมออกไปมากขึ้น ค่าน้อยกว่าจะแสดงฉากที่แก้ไขแล้วมากขึ้นโดยแลกกับการรวมพิกเซลว่างที่ขอบภาพ x_corr และ y_corr จะเลื่อนศูนย์กลางของการแก้ไขออกจากศูนย์กลางเรขาคณิตของภาพ ซึ่งมีประโยชน์เมื่อเลนส์ไม่ได้อยู่ตรงกลางแนวแสงเหนือเซนเซอร์ (กรณีที่ผิดปกติแต่ควรทราบ)

ไปป์ไลน์ทั่วไป: ถ่ายภาพ รัน lens_corr() หนึ่งครั้งเพื่อทำให้เรขาคณิตตรง จากนั้นรันสิ่งที่แอปพลิเคชันต้องการทำกับผลลัพธ์

5.22.2. การแก้ไขการหมุน 3 มิติ

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

วิธีแก้ไขคือการใช้ การหมุน 3 มิติ กับเฟรมที่ถ่ายมาเพื่อเสมือนกับการปรับทิศทางระนาบเซนเซอร์ให้ขนานกับระนาบฉาก คณิตศาสตร์เป็นการแมปมุมมองเดียวกับที่การตรวจจับ AprilTag ใช้เพื่อกู้คืน pose ของแท็กจากสี่มุม แต่รันในทิศทางย้อนกลับ: เมื่อกำหนดการหมุน การดำเนินการจะแมปพิกเซลเอาต์พุตแต่ละตัวกลับไปยังตำแหน่งอินพุตที่การหมุนนั้นจะมาจาก

rotation_corr() รันการแก้ไขนั้น:

img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)

พารามิเตอร์การหมุนสามตัวมีหน่วยเป็นองศาและอธิบายการหมุนรอบแกน x, y และ z ของกล้องเสมือนที่อยู่ตรงกลางภาพ x_rotation เอียงกล้องขึ้นหรือลง (การแก้ไขที่เป็นธรรมชาติสำหรับการถ่ายภาพผนังในระดับพื้นดิน) y_rotation หมุนกล้องซ้ายหรือขวา z_rotation หมุนกล้องรอบแกนแสง (การแก้ไขที่เป็นธรรมชาติสำหรับการติดตั้งที่ไม่ได้ระดับ)

x_translation และ y_translation เลื่อนกล้องเสมือนไปด้านข้างโดยไม่หมุน zoom (ค่าเริ่มต้น 1.0) ปรับขนาดเอาต์พุต fov (ค่าเริ่มต้น 60.0) อธิบายมุมมองแนวตั้งของกล้อง ซึ่งใช้ในการคำนวณการฉายภาพ ค่าควรตรงกับเลนส์จริงเพื่อให้เรขาคณิตสอดคล้องกัน

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

5.22.3. การแก้ไขสี่เหลี่ยมผืนผ้าที่ทราบ

รูปแบบที่มีประโยชน์มากที่สุดของ rotation_corr() คือคีย์เวิร์ด corners= ซึ่งรับรายการทูเพิล (x, y) สี่ตัวที่อธิบายมุมของสี่เหลี่ยมผืนผ้าที่ทราบในภาพอินพุต เมธอดจะคำนวณการหมุน 3 มิติที่จะแมปสี่เหลี่ยมผืนผ้าจริงไปยังสี่จุดเฉพาะเหล่านั้น ใช้ ผกผัน ของการหมุนนั้นกับภาพทั้งหมด และคืนผลลัพธ์ที่สี่เหลี่ยมผืนผ้าที่ทราบเป็นสี่เหลี่ยมผืนผ้าอีกครั้ง:

plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)

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

เมื่อรูปแบบสี่มุมแก้ปัญหาที่แอปพลิเคชันพยายามแก้ มันมีประโยชน์มากกว่ารูปแบบหกพารามิเตอร์อย่างมาก แอปพลิเคชันไม่ต้องประมาณมุมการหมุนใดๆ เพียงแค่ส่งสี่จุดให้เมธอดและปล่อยให้เมธอดหาส่วนที่เหลือ รูปแบบหกพารามิเตอร์มีประโยชน์เมื่อไม่มีสี่เหลี่ยมผืนผ้าที่ระบุได้ในฉากและต้องปรับการหมุนด้วยตนเองจากความรู้ภายนอก (เช่น มุมการติดตั้งที่ได้รับการสอบเทียบแล้ว)