portaldacalheta.pt
  • หลัก
  • นักลงทุนและเงินทุน
  • กระบวนการทางการเงิน
  • นวัตกรรม
  • ส่วนหลัง
มือถือ

บทช่วยสอน ARKit สำหรับ iOS: วาดในอากาศด้วย Bare Fingers



เมื่อเร็ว ๆ นี้ Apple ได้เปิดตัวไลบรารี Augmented Reality (AR) ใหม่ที่มีชื่อว่า ARKit . สำหรับหลาย ๆ คนดูเหมือนว่าเป็นเพียงคลัง AR ที่ดีไม่ใช่ตัวขัดขวางเทคโนโลยีที่ต้องใส่ใจ อย่างไรก็ตามหากคุณดูความคืบหน้าของ AR ในช่วงสองสามปีที่ผ่านมาเราไม่ควรด่วนสรุปเช่นนี้

ภาพประกอบบทช่วยสอน ARKit: การโต้ตอบกับวัตถุเสมือนในแอป iOS ARKit



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



การสาธิตการใช้งานแอปความเป็นจริงเสริมตัวอย่าง ARKit สำหรับ iOS ของเรา



วิธีทำเซิร์ฟเวอร์ raspberry pi

ทำไมเราควรสนใจ iOS ARKit ตอนนี้

นักพัฒนาที่มีประสบการณ์ทุกคนคงทราบดีอยู่แล้วว่า AR เป็นแนวคิดเก่า ๆ เราสามารถตรึงการพัฒนาอย่างจริงจังครั้งแรกของ AR จนถึงเวลาที่นักพัฒนาสามารถเข้าถึงแต่ละเฟรมได้จากเว็บแคม แอปในเวลานั้นมักจะใช้เพื่อเปลี่ยนใบหน้าของคุณ อย่างไรก็ตามมนุษยชาติใช้เวลาไม่นานในการตระหนักว่าการเปลี่ยนใบหน้าเป็นกระต่ายไม่ใช่หนึ่งในความต้องการที่ใกล้เข้ามาที่สุดของพวกเขาและในไม่ช้าความโฆษณาก็จางหายไป!

ฉันเชื่อว่า AR ขาดการก้าวกระโดดของเทคโนโลยีหลักสองอย่างที่ทำให้เป็นประโยชน์นั่นคือการใช้งานและการใช้งาน หากคุณตรวจสอบ AR hypes อื่น ๆ คุณจะสังเกตเห็นสิ่งนี้ ตัวอย่างเช่น AR hype เริ่มขึ้นอีกครั้งเมื่อนักพัฒนาสามารถเข้าถึงแต่ละเฟรมจากกล้องมือถือ นอกเหนือจากการกลับมาอีกครั้งอย่างแข็งแกร่งของเครื่องแปลงร่างกระต่ายตัวใหญ่เรายังเห็นแอพจำนวนมากที่วางวัตถุ 3 มิติลงบนโค้ด QR ที่พิมพ์ออกมา แต่พวกเขาไม่เคยถอดออกมาเป็นแนวคิด พวกเขาไม่ใช่ความเป็นจริงที่เพิ่มขึ้น แต่เป็นการเพิ่มรหัส QR



จากนั้น Google ทำให้เราประหลาดใจด้วยนิยายวิทยาศาสตร์ Google Glass สองปีผ่านไปและเมื่อถึงเวลาที่คาดว่าผลิตภัณฑ์ที่น่าทึ่งนี้จะมีชีวิตขึ้นมามันก็ตายไปแล้ว! นักวิจารณ์หลายคนวิเคราะห์สาเหตุของความล้มเหลวของ Google Glass โดยกล่าวโทษในทุกสิ่งตั้งแต่ด้านสังคมไปจนถึงแนวทางที่น่าเบื่อของ Google ในการเปิดตัวผลิตภัณฑ์ อย่างไรก็ตามเราใส่ใจในบทความนี้ด้วยเหตุผลเฉพาะประการหนึ่งนั่นคือการแช่ตัวในสิ่งแวดล้อม ในขณะที่ Google Glass แก้ไขปัญหาการใช้งาน แต่ก็ยังไม่มีอะไรมากไปกว่าภาพ 2 มิติที่พล็อตกลางอากาศ

ไททันเทคโนโลยีเช่น Microsoft, Facebook และ Apple ได้เรียนรู้บทเรียนอันโหดร้ายนี้ด้วยใจจริง ในเดือนมิถุนายน 2017 Apple ได้ประกาศไลบรารี iOS ARKit ที่สวยงามโดยให้ความสำคัญสูงสุด การถือโทรศัพท์ยังคงเป็นตัวปิดกั้นประสบการณ์การใช้งานที่สำคัญ แต่บทเรียนของ Google Glass สอนเราว่าฮาร์ดแวร์ไม่ใช่ปัญหา



ฉันเชื่อว่าเรากำลังมุ่งหน้าสู่จุดสูงสุดของ AR ใหม่ในไม่ช้าและด้วยจุดสำคัญใหม่นี้ในที่สุดก็สามารถหาตลาดในบ้านได้ทำให้การพัฒนาแอป AR กลายเป็นกระแสหลักมากขึ้น นอกจากนี้ยังหมายความว่า บริษัท พัฒนาแอป Augmented Reality ทุกแห่งจะสามารถเข้าถึงระบบนิเวศและฐานผู้ใช้ของ Apple ได้

แต่พอมีประวัติมาแล้วขอให้มือของเราสกปรกด้วยรหัสและดูการใช้งานจริงของ Apple!



คุณสมบัติ ARKit Immersion

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

ARKit บรรลุเป้าหมายนี้ได้อย่างไร? ซึ่งทำได้โดยใช้เทคนิคที่เรียกว่า Visual Inertial Odometry (VIO) ไม่ต้องกังวลเช่นเดียวกับที่ผู้ประกอบการพบว่าพวกเขามีความสุขกับจำนวนการหัวเราะคิกคักที่คุณหัวเราะคิกคักเมื่อคุณหาแหล่งที่มาที่อยู่เบื้องหลังชื่อเริ่มต้นของพวกเขานักวิจัยพบว่าพวกเขามีรอยขีดข่วนบนศีรษะจำนวนมากที่คุณพยายามถอดรหัสคำศัพท์ใด ๆ ที่เกิดขึ้นเมื่อ ตั้งชื่อสิ่งประดิษฐ์ของพวกเขา - ดังนั้นปล่อยให้พวกเขามีความสนุกสนานและดำเนินการต่อไป



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

เริ่มต้นใช้งาน ARKit ใน iOS

ในขณะที่เขียนบทความนี้ ARKit เป็นส่วนหนึ่งของ iOS 11 ซึ่งยังอยู่ในรุ่นเบต้า ดังนั้นในการเริ่มต้นคุณต้องดาวน์โหลด iOS 11 Beta บน iPhone 6s ขึ้นไปและ Xcode Beta ใหม่ เราสามารถเริ่มโครงการ ARKit ใหม่ได้จาก ใหม่> โครงการ> แอป Augmented Reality . อย่างไรก็ตามฉันพบว่าสะดวกกว่าที่จะเริ่มบทช่วยสอนความเป็นจริงยิ่งขึ้นนี้กับทางการ ตัวอย่าง Apple ARKit ซึ่งมีบล็อกรหัสที่จำเป็นบางส่วนและเป็นประโยชน์อย่างยิ่งสำหรับการตรวจจับเครื่องบิน ดังนั้นให้เราเริ่มต้นด้วยโค้ดตัวอย่างนี้อธิบายประเด็นหลักในนั้นก่อนจากนั้นแก้ไขสำหรับโครงการของเรา



อันดับแรกเราควรพิจารณาว่าเราจะใช้เครื่องยนต์ใด ARKit สามารถใช้ได้กับ Sprite SceneKit หรือ Metal ในตัวอย่าง Apple ARKit เราใช้ iOS SceneKit ซึ่งเป็นเอนจิ้น 3 มิติที่ Apple จัดหาให้ ต่อไปเราต้องตั้งค่ามุมมองที่จะแสดงวัตถุ 3 มิติของเรา ซึ่งทำได้โดยการเพิ่มมุมมองประเภท ARSCNView

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

ARSCNView ไม่ได้ทำการประมวลผล AR ด้วยตัวเอง แต่ต้องใช้วัตถุเซสชัน AR ที่จัดการกล้องของอุปกรณ์และการประมวลผลการเคลื่อนไหว ดังนั้นในการเริ่มต้นเราต้องกำหนดเซสชันใหม่:

self.session = ARSession() sceneView.session = session sceneView.delegate = self setupFocusSquare()

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

ตารางโฟกัสที่ฉายบนโต๊ะโดยใช้ Apple ARKit

วิธีรับทวีตจาก twitter api ใน python

ขั้นตอนต่อไปคือการเริ่มเซสชัน ARKit ควรรีสตาร์ทเซสชันทุกครั้งที่มุมมองปรากฏขึ้นเนื่องจากเราไม่สามารถใช้ประโยชน์จากข้อมูลเซสชันก่อนหน้านี้ได้หากเราไม่ได้ติดตามผู้ใช้อีกต่อไป ดังนั้นเราจะเริ่มเซสชันใน viewDidAppear:

override func viewDidAppear(_ animated: Bool) { let configuration = ARWorldTrackingSessionConfiguration() configuration.planeDetection = .horizontal session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) }

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

สุดท้ายเราต้องอัปเดต Focus Square ทุกครั้งที่ตำแหน่งกล้องเช่นการวางแนวหรือตำแหน่งอุปกรณ์จริงเปลี่ยนไป สิ่งนี้สามารถทำได้ในฟังก์ชัน renderer delegate ของ SCNView ซึ่งจะถูกเรียกทุกครั้งที่กำลังจะแสดงเฟรมใหม่ของเอ็นจิ้น 3D:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { updateFocusSquare() }

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

การตรวจจับเครื่องบินใน ARKit

ARKit สามารถตรวจจับเครื่องบินใหม่อัปเดตเครื่องบินที่มีอยู่หรือลบออก ในการจัดการกับเครื่องบินอย่างสะดวกเราจะสร้างโหนด SceneKit จำลองที่เก็บข้อมูลตำแหน่งเครื่องบินและอ้างอิงไปยังตารางโฟกัส ระนาบถูกกำหนดในทิศทาง X และ Z โดยที่ Y เป็นพื้นผิวปกติกล่าวคือเราควรรักษาตำแหน่งโหนดการวาดของเราให้อยู่ในค่า Y ของระนาบเดียวกันเสมอหากเราต้องการทำให้ดูเหมือนว่าพิมพ์บนระนาบ .

การตรวจจับเครื่องบินทำได้โดยใช้ฟังก์ชันการโทรกลับที่ ARKit จัดเตรียมไว้ให้ ตัวอย่างเช่นฟังก์ชันเรียกกลับต่อไปนี้จะถูกเรียกใช้ทุกครั้งที่ตรวจพบเครื่องบินใหม่:

var planes = [ARPlaneAnchor: Plane]() func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { if let planeAnchor = anchor as? ARPlaneAnchor { serialQueue.async { self.addPlane(node: node, anchor: planeAnchor) self.virtualObjectManager.checkIfObjectShouldMoveOntoPlane(anchor: planeAnchor, planeAnchorNode: node) } } } func addPlane(node: SCNNode, anchor: ARPlaneAnchor) { let plane = Plane(anchor) planes[anchor] = plane node.addChildNode(plane) } ... class Plane: SCNNode { var anchor: ARPlaneAnchor var focusSquare: FocusSquare? init(_ anchor: ARPlaneAnchor) { self.anchor = anchor super.init() } ... }

ฟังก์ชันเรียกกลับมีพารามิเตอร์สองตัวคือ anchor และ node. node เป็นโหนด SceneKit ปกติที่วางไว้ในตำแหน่งที่แน่นอนและการวางแนวของเครื่องบิน มันไม่มีรูปทรงเรขาคณิตจึงมองไม่เห็น เราใช้มันเพื่อเพิ่มโหนดระนาบของเราซึ่งมองไม่เห็น แต่เก็บข้อมูลเกี่ยวกับการวางแนวระนาบและตำแหน่งใน anchor

ดังนั้นตำแหน่งและการวางแนวถูกบันทึกไว้ใน ARPlaneAnchor ได้อย่างไร? ตำแหน่งการวางแนวและมาตราส่วนทั้งหมดถูกเข้ารหัสในเมทริกซ์ 4x4 ถ้าฉันมีโอกาสเลือกแนวคิดทางคณิตศาสตร์หนึ่งข้อเพื่อให้คุณเรียนรู้มันจะเป็นเมทริกซ์อย่างไม่ต้องสงสัย อย่างไรก็ตามเราสามารถหลีกเลี่ยงสิ่งนี้ได้โดยการอธิบายเมทริกซ์ 4x4 นี้ดังนี้อาร์เรย์ 2 มิติที่ยอดเยี่ยมที่มีตัวเลขทศนิยม 4x4 การคูณตัวเลขเหล่านี้ด้วยวิธีใดวิธีหนึ่งด้วยจุดยอด 3 มิติ v1 ในพื้นที่ท้องถิ่นจะทำให้เกิดจุดยอด 3 มิติใหม่ v2 ซึ่งแสดงถึง v1 ในอวกาศโลก ดังนั้นถ้า v1 = (1, 0, 0) ในพื้นที่ท้องถิ่นและเราต้องการวางไว้ที่ x = 100 ในอวกาศโลก v2 จะเท่ากับ (101, 0, 0) เมื่อเทียบกับพื้นที่โลก แน่นอนว่าคณิตศาสตร์ที่อยู่เบื้องหลังสิ่งนี้จะซับซ้อนมากขึ้นเมื่อเราเพิ่มการหมุนเกี่ยวกับแกน แต่ข่าวดีก็คือเราสามารถทำได้โดยไม่ต้องทำความเข้าใจ (ขอแนะนำให้ตรวจสอบส่วนที่เกี่ยวข้องจาก บทความที่ยอดเยี่ยมนี้ สำหรับคำอธิบายเชิงลึกของแนวคิดนี้)

checkIfObjectShouldMoveOntoPlane ตรวจสอบว่าเรามีวัตถุที่วาดอยู่แล้วหรือไม่และตรวจสอบว่าแกน y ของวัตถุทั้งหมดเหล่านี้ตรงกับเครื่องบินที่ตรวจพบใหม่หรือไม่

ตอนนี้กลับไปที่ updateFocusSquare() อธิบายไว้ในส่วนก่อนหน้า เราต้องการให้จุดโฟกัสอยู่ตรงกลางหน้าจอ แต่ฉายบนระนาบที่ตรวจจับได้ใกล้ที่สุด รหัสด้านล่างแสดงให้เห็นถึงสิ่งนี้:

func updateFocusSquare() { let worldPos = worldPositionFromScreenPosition(screenCenter, self.sceneView) self.focusSquare?.simdPosition = worldPos } func worldPositionFromScreenPosition(_ position: CGPoint, in sceneView: ARSCNView) -> float3? { let planeHitTestResults = sceneView.hitTest(position, types: .existingPlaneUsingExtent) if let result = planeHitTestResults.first { return result.worldTransform.translation } return nil }

sceneView.hitTest ค้นหาเครื่องบินในโลกแห่งความเป็นจริงที่ตรงกับจุด 2 มิติในมุมมองหน้าจอโดยการฉายจุด 2 มิตินี้ไปยังระนาบที่อยู่ใกล้ที่สุด result.worldTransform เป็นเมทริกซ์ 4x4 ที่เก็บข้อมูลการแปลงทั้งหมดของระนาบที่ตรวจพบในขณะที่ result.worldTransform.translation เป็นฟังก์ชันที่มีประโยชน์ซึ่งส่งกลับตำแหน่งเท่านั้น

ตอนนี้เรามีข้อมูลทั้งหมดที่จำเป็นในการวางวัตถุ 3 มิติบนพื้นผิวที่ตรวจพบโดยให้จุด 2D บนหน้าจอ มาเริ่มวาดกันเลย

การวาดภาพ

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

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

ตัวอย่างส่วนหัว c++ และไฟล์ cpp

รหัสต่อไปนี้แสดง PointNode คลาสที่แสดงถึงจุด:

let POINT_SIZE = CGFloat(0.003) let POINT_HEIGHT = CGFloat(0.00001) class PointNode: SCNNode { static var boxGeo: SCNBox? override init() { super.init() if PointNode.boxGeo == nil { PointNode.boxGeo = SCNBox(width: POINT_SIZE, height: POINT_HEIGHT, length: POINT_SIZE, chamferRadius: 0.001) // Setup the material of the point let material = PointNode.boxGeo!.firstMaterial material?.lightingModel = SCNMaterial.LightingModel.blinn material?.diffuse.contents = UIImage(named: 'wood-diffuse.jpg') material?.normal.contents = UIImage(named: 'wood-normal.png') material?.specular.contents = UIImage(named: 'wood-specular.jpg') } let object = SCNNode(geometry: PointNode.boxGeo!) object.transform = SCNMatrix4MakeTranslation(0.0, Float(POINT_HEIGHT) / 2.0, 0.0) self.addChildNode(object) } . . . }

คุณจะสังเกตเห็นในโค้ดด้านบนว่าเราแปลรูปทรงเรขาคณิตตามแกน y ด้วยความสูงครึ่งหนึ่ง เหตุผลนี้คือเพื่อให้แน่ใจว่าด้านล่างของวัตถุอยู่ที่เสมอ y = 0 เพื่อให้ปรากฏเหนือเครื่องบิน

ต่อไปในฟังก์ชั่นเรียกกลับตัวแสดงผลของ SceneKit เราจะวาดตัวบ่งชี้บางอย่างที่ทำหน้าที่เหมือนจุดปลายปากกาโดยใช้ PointNode ชั้นเรียน เราจะวางจุดที่ตำแหน่งนั้นหากเปิดใช้งานการวาดภาพหรือยกภาพวาดเป็นโครงสร้าง 3 มิติหากเปิดใช้งานโหมด 3 มิติ:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { updateFocusSquare() // Setup a dot that represents the virtual pen's tippoint if (self.virtualPenTip == nil) { self.virtualPenTip = PointNode(color: UIColor.red) self.sceneView.scene.rootNode.addChildNode(self.virtualPenTip!) } // Draw if let screenCenterInWorld = worldPositionFromScreenPosition(self.screenCenter, self.sceneView) { // Update virtual pen position self.virtualPenTip?.isHidden = false self.virtualPenTip?.simdPosition = screenCenterInWorld // Draw new point if (self.inDrawMode && !self.virtualObjectManager.pointNodeExistAt(pos: screenCenterInWorld)){ let newPoint = PointNode() self.sceneView.scene.rootNode.addChildNode(newPoint) self.virtualObjectManager.loadVirtualObject(newPoint, to: screenCenterInWorld) } // Convert drawing to 3D if (self.in3DMode ) { if self.trackImageInitialOrigin != nil { DispatchQueue.main.async { let newH = 0.4 * (self.trackImageInitialOrigin!.y - screenCenterInWorld.y) / self.sceneView.frame.height self.virtualObjectManager.setNewHeight(newHeight: newH) } } else { self.trackImageInitialOrigin = screenCenterInWorld } } }

virtualObjectManager เป็นคลาสที่จัดการจุดที่วาด ในโหมด 3 มิติเราจะประมาณความแตกต่างจากตำแหน่งสุดท้ายและเพิ่ม / ลดความสูงของทุกจุดด้วยค่านั้น

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

การตรวจจับปลายนิ้วของผู้ใช้

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

เราจะใช้เคล็ดลับเล็ก ๆ เราจะขอให้ผู้ใช้วางมือบนโต๊ะราวกับว่าพวกเขากำลังถือปากกาและเพื่อให้แน่ใจว่าภาพขนาดย่อของพวกเขาหันเข้าหากล้องหลังจากนั้นพวกเขาควรแตะที่ภาพขนาดย่อบนหน้าจอ มีสองจุดที่ต้องอธิบายที่นี่ ขั้นแรกภาพขนาดย่อควรมีคุณลักษณะเฉพาะมากพอที่จะตรวจสอบได้ผ่านความเปรียบต่างระหว่างภาพขนาดย่อสีขาวผิวและตาราง นั่นหมายความว่าเม็ดสีผิวที่เข้มขึ้นจะทำให้การติดตามมีความน่าเชื่อถือมากขึ้น ประการที่สองเนื่องจากผู้ใช้วางมือบนโต๊ะและเนื่องจากเราตรวจพบว่าตารางเป็นระนาบอยู่แล้วการฉายตำแหน่งของภาพขนาดย่อจากมุมมอง 2 มิติไปยังสภาพแวดล้อม 3 มิติจะส่งผลให้ตำแหน่งของนิ้วบน โต๊ะ.

ภาพต่อไปนี้แสดงจุดคุณสมบัติที่สามารถตรวจพบได้โดยไลบรารี Vision:

จุดคุณลักษณะ ARKit ของ iOS ที่ตรวจพบโดยไลบรารี Vision

เราจะเริ่มต้นการติดตามภาพขนาดย่อด้วยท่าทางการแตะดังนี้:

// MARK: Object tracking fileprivate var lastObservation: VNDetectedObjectObservation? var trackImageBoundingBox: CGRect? let trackImageSize = CGFloat(20) @objc private func tapAction(recognizer: UITapGestureRecognizer) { lastObservation = nil let tapLocation = recognizer.location(in: view) // Set up the rect in the image in view coordinate space that we will track let trackImageBoundingBoxOrigin = CGPoint(x: tapLocation.x - trackImageSize / 2, y: tapLocation.y - trackImageSize / 2) trackImageBoundingBox = CGRect(origin: trackImageBoundingBoxOrigin, size: CGSize(width: trackImageSize, height: trackImageSize)) let t = CGAffineTransform(scaleX: 1.0 / self.view.frame.size.width, y: 1.0 / self.view.frame.size.height) let normalizedTrackImageBoundingBox = trackImageBoundingBox!.applying(t) // Transfrom the rect from view space to image space guard let fromViewToCameraImageTransform = self.sceneView.session.currentFrame?.displayTransform(withViewportSize: self.sceneView.frame.size, orientation: UIInterfaceOrientation.portrait).inverted() else { return } var trackImageBoundingBoxInImage = normalizedTrackImageBoundingBox.applying(fromViewToCameraImageTransform) trackImageBoundingBoxInImage.origin.y = 1 - trackImageBoundingBoxInImage.origin.y // Image space uses bottom left as origin while view space uses top left lastObservation = VNDetectedObjectObservation(boundingBox: trackImageBoundingBoxInImage) }

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

ต่อไปในตัวแสดงผลเราจะป้อนรูปภาพใหม่เพื่อติดตามตำแหน่งใหม่ของนิ้ว:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { // Track the thumbnail guard let pixelBuffer = self.sceneView.session.currentFrame?.capturedImage, let observation = self.lastObservation else { return } let request = VNTrackObjectRequest(detectedObjectObservation: observation) { [unowned self] request, error in self.handle(request, error: error) } request.trackingLevel = .accurate do { try self.handler.perform([request], on: pixelBuffer) } catch { print(error) } . . . }

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

fileprivate func handle(_ request: VNRequest, error: Error?) { DispatchQueue.main.async { guard let newObservation = request.results?.first as? VNDetectedObjectObservation else { return } self.lastObservation = newObservation var trackImageBoundingBoxInImage = newObservation.boundingBox // Transfrom the rect from image space to view space trackImageBoundingBoxInImage.origin.y = 1 - trackImageBoundingBoxInImage.origin.y guard let fromCameraImageToViewTransform = self.sceneView.session.currentFrame?.displayTransform(withViewportSize: self.sceneView.frame.size, orientation: UIInterfaceOrientation.portrait) else { return } let normalizedTrackImageBoundingBox = trackImageBoundingBoxInImage.applying(fromCameraImageToViewTransform) let t = CGAffineTransform(scaleX: self.view.frame.size.width, y: self.view.frame.size.height) let unnormalizedTrackImageBoundingBox = normalizedTrackImageBoundingBox.applying(t) self.trackImageBoundingBox = unnormalizedTrackImageBoundingBox // Get the projection if the location of the tracked image from image space to the nearest detected plane if let trackImageOrigin = self.trackImageBoundingBox?.origin { self.lastFingerWorldPos = self.virtualObjectManager.worldPositionFromScreenPosition(CGPoint(x: trackImageOrigin.x - 20.0, y: trackImageOrigin.y + 40.0), in: self.sceneView) } } }

สุดท้ายเราจะใช้ self.lastFingerWorldPos แทนที่จะเป็นศูนย์กลางหน้าจอเมื่อวาดภาพและเราก็ทำเสร็จแล้ว

ARKit และอนาคต

ในโพสต์นี้เราได้แสดงให้เห็นว่า AR สามารถดื่มด่ำได้อย่างไรผ่านการโต้ตอบกับนิ้วของผู้ใช้และตารางในชีวิตจริง ด้วยความก้าวหน้าที่มากขึ้นในการมองเห็นของคอมพิวเตอร์และการเพิ่มฮาร์ดแวร์ที่เป็นมิตรกับ AR ให้กับแกดเจ็ตมากขึ้น (เช่นกล้องความลึก) เราสามารถเข้าถึงโครงสร้าง 3 มิติของวัตถุรอบตัวเราได้มากขึ้นเรื่อย ๆ

แม้ว่าจะยังไม่ได้เปิดตัวสู่สาธารณชน แต่ก็ควรค่าแก่การกล่าวถึงว่า Microsoft จริงจังมากแค่ไหนที่จะชนะการแข่งขัน AR ผ่านมัน อุปกรณ์ Hololens ซึ่งรวมฮาร์ดแวร์ที่ปรับแต่ง AR เข้ากับเทคนิคการจดจำสภาพแวดล้อม 3 มิติขั้นสูง คุณสามารถรอดูว่าใครจะเป็นผู้ชนะการแข่งขันครั้งนี้หรือคุณสามารถเป็นส่วนหนึ่งของการแข่งขันนี้ได้โดยการพัฒนาตัวจริง แอปความเป็นจริงยิ่งตอนนี้ ! แต่ได้โปรดโปรดช่วยเหลือมวลมนุษยชาติและอย่าเปลี่ยนสิ่งของที่มีชีวิตเป็นกระต่าย

โอเพ่นซอร์สซอฟต์แวร์สร้างภาพ 3 มิติ

ทำความเข้าใจพื้นฐาน

Apple ARKit มีฟีเจอร์อะไรให้นักพัฒนาบ้าง?

ARKit ช่วยให้นักพัฒนาสร้างแอพ Augmented Reality บน iPhone และ iPad โดยวิเคราะห์ฉากที่นำเสนอโดยมุมมองกล้องและค้นหาระนาบแนวนอนในห้อง

เราจะติดตามวัตถุด้วยห้องสมุด Apple Vision ได้อย่างไร

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

เราจะเริ่มต้นกับ Apple ARKit ได้อย่างไร

ในการเริ่มต้นใช้งาน Apple ARKit ให้ดาวน์โหลด iOS 11 บน iPhone 6s ขึ้นไปและสร้างโปรเจ็กต์ ARKit ใหม่จากใหม่> โปรเจ็กต์> แอพ Augmented Reality คุณสามารถตรวจสอบโค้ดตัวอย่าง AR ที่ Apple ให้มาได้ที่นี่: https://developer.apple.com/arkit/

Augmented Reality ทำงานอย่างไร?

Augmented Reality คือกระบวนการซ้อนทับวิดีโอดิจิทัลและองค์ประกอบ CGI อื่น ๆ บนวิดีโอในโลกแห่งความจริง การสร้างภาพซ้อนทับ CGI ที่มีคุณภาพบนวิดีโอที่ถ่ายด้วยกล้องจำเป็นต้องใช้เซ็นเซอร์และซอฟต์แวร์มากมาย

การใช้ Augmented Reality คืออะไร?

Augmented Reality มีการใช้งานที่มีศักยภาพมากมายในอุตสาหกรรมต่างๆ AR สามารถใช้เพื่อให้การฝึกอบรมในการตั้งค่าเสมือนจริงที่ยากที่จะสร้างขึ้นใหม่เพื่อวัตถุประสงค์ในการฝึกอบรมเช่น spaceflight อุตสาหกรรมการแพทย์โครงการวิศวกรรมบางอย่าง

VR และ AR ต่างกันอย่างไร

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

Inside Sales Executive - ภาคตะวันออก

อื่น ๆ

Inside Sales Executive - ภาคตะวันออก
หลักการออกแบบและความสำคัญ

หลักการออกแบบและความสำคัญ

การออกแบบตราสินค้า

โพสต์ยอดนิยม
การรวม YouTube API: การอัปโหลดวิดีโอด้วย Django
การรวม YouTube API: การอัปโหลดวิดีโอด้วย Django
สำรวจ Bear Case ของ Cryptocurrency Bubble
สำรวจ Bear Case ของ Cryptocurrency Bubble
บทช่วยสอน ARKit สำหรับ iOS: วาดในอากาศด้วย Bare Fingers
บทช่วยสอน ARKit สำหรับ iOS: วาดในอากาศด้วย Bare Fingers
ความรู้เบื้องต้นเกี่ยวกับทฤษฎีการคำนวณและความซับซ้อน
ความรู้เบื้องต้นเกี่ยวกับทฤษฎีการคำนวณและความซับซ้อน
เข้าใกล้กระบวนการออกแบบเว็บไซต์จากเบราว์เซอร์
เข้าใกล้กระบวนการออกแบบเว็บไซต์จากเบราว์เซอร์
 
วิธีอำนวยความสะดวกในการเปลี่ยนแปลงผ่านการเป็นผู้นำผู้รับใช้ที่คล่องตัว
วิธีอำนวยความสะดวกในการเปลี่ยนแปลงผ่านการเป็นผู้นำผู้รับใช้ที่คล่องตัว
Terraform AWS Cloud: การจัดการโครงสร้างพื้นฐานที่ดี
Terraform AWS Cloud: การจัดการโครงสร้างพื้นฐานที่ดี
GWT Toolkit: สร้างส่วนหน้า JavaScript ที่มีประสิทธิภาพโดยใช้ Java
GWT Toolkit: สร้างส่วนหน้า JavaScript ที่มีประสิทธิภาพโดยใช้ Java
การผสานรวมวิธีการชำระเงิน Stripe และ PayPal ใน Ruby on Rails
การผสานรวมวิธีการชำระเงิน Stripe และ PayPal ใน Ruby on Rails
แนวทางที่ดีกว่าในการปรับใช้ Google Cloud อย่างต่อเนื่อง
แนวทางที่ดีกว่าในการปรับใช้ Google Cloud อย่างต่อเนื่อง
โพสต์ยอดนิยม
  • วิธีการออกแบบโครงการซอฟต์แวร์
  • llc vs c corp vs s corp
  • คู่มือการศึกษาสถาปนิกโซลูชั่น aws ที่ผ่านการรับรอง
  • จุดประสงค์หลักของการตกแต่งคืออะไร
  • กลยุทธ์การกำหนดราคาทำหน้าที่เป็นแนวทางในการบรรลุวัตถุประสงค์ด้านราคา
หมวดหมู่
  • นักลงทุนและเงินทุน
  • กระบวนการทางการเงิน
  • นวัตกรรม
  • ส่วนหลัง
  • © 2022 | สงวนลิขสิทธิ์

    portaldacalheta.pt