ARKit อาจดูน่ากลัว แต่ก็ไม่เลวร้ายนักหากคุณมีประสบการณ์พื้นฐานในการสร้างแอป iOS อยู่แล้ว
ฉันเป็นคนที่เรียนรู้จากการทำสิ่งต่างๆ ดังนั้นฉันจึงได้ลองใช้ ARKit เพื่อสร้างแอปพื้นฐานเพื่อทำความคุ้นเคย ในโพสต์นี้ ฉันจะทบทวนสิ่งที่ฉันได้เรียนรู้เกี่ยวกับการสร้างแอปติดตามใบหน้าแบบง่ายๆ
ฉันจะทำสิ่งนี้ใน 3 ส่วน:
- การตั้งค่าเริ่มต้น → ก่อนอื่น ให้รับสิทธิ์เข้าถึงกล้องและตรวจสอบว่าอุปกรณ์ใช้ ARKit ได้
- การติดตามรอยยิ้ม → เริ่มติดตามรอยยิ้มด้วย ARKit นี่อาจเป็นสิ่งที่คุณมาที่นี่
- ส่วนต่อประสานผู้ใช้ → เพิ่ม UI สำหรับแอปของเราที่จะตอบสนองต่อรอยยิ้ม
ในขณะที่เขียนนี้ โปรแกรมจำลอง Xcode ไม่สนับสนุนกล้องหน้า ดังนั้น คุณจะต้องมีอุปกรณ์จริงเพื่อเรียกใช้แอป อุปกรณ์ของคุณจะต้องมีกล้อง TrueDepth ด้วย (iPhone X หรือใหม่กว่าก็ใช้ได้)
สุดท้ายนี้ สำหรับเพื่อนสมาชิก Copy Paste Club โค้ดทั้งหมดมีอยู่ใน Github
การตั้งค่าเริ่มต้น
เริ่มต้นด้วยการเปิด Xcode และสร้างโปรเจ็กต์ใหม่ชื่อ “SmileTracker” (หรือชื่ออะไรก็ได้ที่คุณต้องการ)
ก่อนที่เราจะเข้าสู่การติดตามใบหน้า เราต้องทำสองสิ่ง:
- ตรวจสอบให้แน่ใจว่าอุปกรณ์ของคุณรองรับ ARKit
- ขออนุญาตเข้าถึงกล้องของอุปกรณ์
ในโครงการใหม่ของคุณ เปิด ViewController.swift
. ใกล้ด้านบนสุดของไฟล์ ใต้ import UIKit
, เพิ่มบรรทัด:import ARKit
. ซึ่งจะทำให้เราเข้าถึงสิ่งดีๆ ทั้งหมดที่ Apple มอบให้เพื่อให้การติดตามใบหน้าเป็นเรื่องง่าย
ตอนนี้เพิ่มรหัสต่อไปนี้ใน viewDidLoad
:
guard ARFaceTrackingConfiguration.isSupported else {
fatalError("Device does not support face tracking")
}
ARFaceTrackingConfiguration.isSupported
เป็นบูลีนที่จะเป็นจริงหากอุปกรณ์ที่รันแอพรองรับการติดตามใบหน้าและเป็นเท็จหากไม่ ในกรณีนี้ หากอุปกรณ์ไม่รองรับการติดตามใบหน้า เราจะหยุดทำงานแอปด้วยข้อผิดพลาดร้ายแรง
ต่อไปมาขออนุญาตใช้กล้องกันนะครับ เพิ่มสิ่งต่อไปนี้ใน viewDidLoad
ด้านล่าง guard
. ของเรา คำสั่ง:
AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in
if (granted) {
Dispatch.main.sync {
// We're going to implement this function in a minute
self.setupSmileTracker()
}
} else {
fatalError("User did not grant camera permission!")
}
}
ที่นี่เรากำลังขอให้อุปกรณ์ขออนุญาตกล้อง หากผู้ใช้ให้สิทธิ์ เราจะเรียกใช้ฟังก์ชันที่จะตั้งค่าการติดตามรอยยิ้มของเรา (ไม่ต้องกังวลกับข้อผิดพลาด เราจะใช้ฟังก์ชันนี้ในอีกสักครู่)
เราห่อฟังก์ชันใน Dispatch.main.sync
เพราะเราจะเพิ่มองค์ประกอบ UI ในฟังก์ชันนี้ ซึ่งทำได้เฉพาะในเธรดหลักเท่านั้น
เรายังต้องเพิ่มคำอธิบายการใช้กล้องใน Info.plist
. ของเราด้วย . เปิด Info.plist
และเพิ่มแถวใหม่ (ทำได้โดยไฮไลต์แถวสุดท้ายแล้วกด enter
)
ในแถวที่คุณเพิ่งสร้าง ให้เพิ่ม Privacy — Camera Usage Description
ไปที่ Key
และตรวจสอบให้แน่ใจว่า Type
คอลัมน์ถูกตั้งค่าเป็นสตริง สามารถฝาก Value
คอลัมน์ว่างหรือเพิ่มข้อความเพื่ออธิบายว่าคุณจะใช้กล้องกับผู้ใช้อย่างไร
Info.plist
ของคุณ ตอนนี้ควรมีลักษณะดังนี้:
หากคุณต้องการทดสอบแอปของคุณในตอนนี้ คุณสามารถแสดงความคิดเห็นในบรรทัดที่เราเรียกว่า setupSmileTracker()
. อย่าลืมยกเลิกความคิดเห็นในภายหลัง
หากคุณเปิดแอปตอนนี้ คุณจะเห็นป๊อปอัปขอให้คุณเปิดใช้งานการอนุญาตของกล้อง หากคุณปฏิเสธ คุณจะต้องไปที่การตั้งค่าแอปพลิเคชันเพื่อเปิดใช้การอนุญาตเหล่านั้นเพื่อให้แอปทำงาน
หากแอปขัดข้อง ให้ตรวจสอบคอนโซลสำหรับข้อความแสดงข้อผิดพลาดสองข้อความของเราเพื่อดูว่ามีอะไรผิดพลาด
การติดตามรอยยิ้ม
เปิด ViewController.swift
และเพิ่มตัวแปรต่อไปนี้ที่ด้านบนของ ViewController
:
class ViewController: UIViewController {
let sceneView = ARSCNView()
override func viewDidLoad() {...}
}
ARSCNView
มาพร้อมกับ ARSession
ที่ iPhone ของคุณใช้เพื่อประสานประสบการณ์ AR เราจะใช้ sceneView
ของ ARSession
เพื่อวิเคราะห์ใบหน้าผู้ใช้ของเราผ่านกล้องหน้า
เพิ่มฟังก์ชันนี้ลงในไฟล์ของคุณภายใต้ viewDidLoad
:
func setupSmileTracker() {
let configuration = ARFaceTrackingConfiguration()
sceneView.session.run(configuration)
sceneView.delegate = self
view.addSubview(sceneView)
}
ที่นี่ เราได้สร้างการกำหนดค่าเพื่อจัดการการติดตามใบหน้าและใช้เพื่อเรียกใช้ sceneView
. ของเรา ของ ARSession
.
จากนั้นเราก็ตั้งค่า sceneView
มอบให้แก่ตนเองและเพิ่มลงในมุมมองของเรา
Xcode จะบอกคุณว่ามีปัญหาตั้งแต่ ViewController
ไม่เป็นไปตาม ARSCNViewDelegate
. ไปที่ ViewController
ถูกประกาศใกล้กับด้านบนของไฟล์และเปลี่ยนบรรทัดดังต่อไปนี้:
class ViewController: ViewController, ARSCNViewDelegate {
...
}
ตอนนี้เพิ่ม ARSCNViewDelegate
. นี้ ทำงานใน ViewController
. ของคุณ คลาส setupSmileTracker
:
func renderer(_renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
...
}
renderer
จะทำงานทุกครั้งที่ฉากของเราอัปเดตและให้ ARAnchor
. แก่เรา ที่เข้ากับใบหน้าของผู้ใช้
เพื่อให้ง่ายต่อการสร้างประสบการณ์การติดตามใบหน้า Apple จะสร้าง . โดยอัตโนมัติ ARFaceAnchor
และเพิ่มลงในเซสชันของเราเมื่อเราใช้ ARFacetrackingConfiguration
เพื่อเรียกใช้ ARFaceAnchor นี้จะถูกส่งต่อไปยัง renderer
เป็น ARAnchor
.
เพิ่มรหัสต่อไปนี้เพื่อแสดงผล:
func renderer(_renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
// 1
guard let faceAnchor = anchor as? ARFaceAnchor else { return }
// 2
let leftSmileValue = faceAnchor.blendshapes[.mouthSmileLeft] as! CGFloat
let rightSmileValue = faceAnchor.blendShapes[.mouthSmileRight] as! CGFloat
// 3
print(leftSmileValue, rightSmileValue)
}
มีหลายสิ่งที่เกิดขึ้นภายในฟังก์ชันนี้ ฉันจึงนับขั้นตอน (สไตล์ Ray Wenderlich)
ใน ขั้นตอนที่ 1 เราแปลง ARAnchor
เป็น ARFaceAnchor
และกำหนดให้กับ faceAnchor
ตัวแปร
ARFaceAnchor
มีข้อมูลเกี่ยวกับตำแหน่งและทิศทางปัจจุบัน โทโพโลยี และการแสดงออกทางสีหน้า ของใบหน้าที่เรากำลังติดตาม
ARFaceAnchor
เก็บข้อมูลเกี่ยวกับการแสดงออกทางสีหน้าในตัวแปร blendShapes
. blendShapes
เป็นพจนานุกรมที่เก็บค่าสัมประสิทธิ์ที่สอดคล้องกับลักษณะใบหน้าต่างๆ หากคุณสนใจ เราขอแนะนำให้คุณตรวจสอบรายการคุณสมบัติใบหน้าทั้งหมดในเอกสารประกอบของ Apple (คำแนะนำ :หากคุณต้องการเพิ่มการติดตามการขมวดคิ้ว คุณจะพบวิธีทำได้ที่นี่)
ใน ขั้นตอนที่ 2 , เราใช้ faceAnchor.blendShapes
เพื่อให้ได้ CGFloat ที่ตรงกับจำนวนปากของผู้ใช้ที่ยิ้มโดยใช้ปุ่ม mouthSmileLeft
และ mouthSmileRight
.
สุดท้าย ขั้นตอนที่ 3 เพียงพิมพ์ค่าทั้งสองออกมาเพื่อให้มั่นใจว่าทำงานได้อย่างถูกต้อง ?.
ณ จุดนี้คุณควรมีแอปที่:
- รับสิทธิ์การติดตามกล้องและใบหน้าจากผู้ใช้
- ใช้ ARKit เพื่อติดตามการแสดงออกทางสีหน้าของผู้ใช้
- พิมพ์ว่าผู้ใช้กำลังยิ้มทางด้านซ้ายและด้านขวาของปากไปที่คอนโซลมากแค่ไหน
เรามีความคืบหน้าอย่างมาก ดังนั้นโปรดใช้เวลาสักครู่เพื่อให้แน่ใจว่าทุกอย่างทำงานอย่างถูกต้อง
เมื่อคุณเปิดแอปเป็นครั้งแรก ระบบจะถามคุณว่าคุณจะอนุญาตให้ใช้กล้องหรือไม่ อย่าลืมตอบตกลง
จากนั้น คุณจะถูกส่งไปยังหน้าจอว่าง แต่คุณควรเริ่มเห็นค่า CGFloat ถูกพิมพ์ไปยังคอนโซล (อาจมีความล่าช้าเล็กน้อยก่อนที่คุณจะเห็น)
เมื่อคุณยิ้มให้โทรศัพท์ คุณควรสังเกตว่าค่าที่พิมพ์ออกมานั้นเพิ่มขึ้น ยิ่งยิ้ม ตัวเลขยิ่งสูงขึ้น
ถ้ามันทำงานอย่างถูกต้อง ขอแสดงความยินดี ?! หากคุณพบข้อผิดพลาด ให้ตรวจสอบอีกครั้งเพื่อให้แน่ใจว่าอุปกรณ์ของคุณรองรับการติดตามใบหน้า และคุณได้เปิดการอนุญาตของกล้องไว้ หากคุณได้ติดตามบทความนี้ตั้งแต่ต้น คอนโซลจะพิมพ์ข้อผิดพลาดทั้งสองกรณี
อินเทอร์เฟซผู้ใช้
ตอนนี้เรากำลังติดตามใบหน้า มาสร้าง UI เพื่อตอบสนองต่อรอยยิ้มกัน
ขั้นแรกให้เพิ่ม UILabel
. ใหม่ เรียกว่า smileLabel
ที่ด้านบนสุดของไฟล์ ด้านล่าง sceneView
.
class ViewController: UIViewController {
let sceneView = ARSCNView()
let smileLabel = UILabel()
...
}
นี่จะเป็นมุมมองที่ตอบสนองต่อการแสดงออกทางสีหน้าของผู้ใช้
เพิ่มรหัสต่อไปนี้ที่ด้านล่างของ setupSmileTracker
. ของคุณ ฟังก์ชัน:
smileLabel.text = "?"smileLabel.font = UIFont.systemFont(ofSize: 150)
view.addSubview(smileLabel)
// Set constraints
smileLabel.translatesAutoresizingMaskIntoConstraints = false
smileLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
smileLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
ในที่นี้ เรากำลังเพิ่มคุณสมบัติ UI พื้นฐานให้กับ smileLabel
. ของเรา และตั้งค่าข้อจำกัดให้อยู่ตรงกลางหน้าจอ ตอนนี้เมื่อคุณเปิดแอป คุณจะเห็นยักษ์ ? อิโมจิตรงกลาง
เมื่อคุณเห็นอิโมจิปรากฏขึ้น ให้เพิ่มฟังก์ชันต่อไปนี้ใน ViewController
. ของคุณ :
func handleSmile(leftValue: CGFloat, rightValue: CGFloat) {
let smileValue = (leftValue + rightValue)/2.0
switch smileValue {
case _ where smileValue > 0.5:
smileLabel.text = "?"
case _ where smileValue > 0.2:
smileLabel.text = "?"
default:
smileLabel.text = "?"
}
}
ฟังก์ชันนี้จะเปลี่ยนอีโมจิใน smileLabel
. ของเรา ขึ้นอยู่กับว่าผู้ใช้ยิ้มใส่กล้องมากแค่ไหน เราคำนวณ smileValue
โดยนำค่าเฉลี่ยของค่ารอยยิ้มซ้ายและขวาที่ ARFaceAnchor
. มอบให้เรา (เป็นวิทยาศาสตร์มากนะรู้ยัง)
ใส่ค่านั้นลงในคำสั่ง switch ยิ่งผู้ใช้ยิ้มมากเท่าไหร่ อีโมจิของเราก็ยิ่งมีความสุขมากขึ้นเท่านั้น
สุดท้าย กลับไปที่ renderer
. ของเรา และเพิ่มสิ่งนี้ที่ด้านล่างเพื่อเสียบค่ารอยยิ้มซ้ายและขวาของเราลงใน handleSmile
:
DispatchQueue.main.async {
self.handleSmile(leftValue: leftSmileValue, rightValue: rightSmileValue)
}
อีกครั้งที่เราใช้ DispatchQueue
เนื่องจากเรากำลังทำการเปลี่ยนแปลง UI ซึ่งต้องทำในเธรดหลัก
เมื่อคุณเปิดแอป คุณจะเห็นอีโมจิเปลี่ยนไปขึ้นอยู่กับว่าคุณยิ้มให้กับมันมากแค่ไหน
ใน gif ด้านล่าง ฉันได้เพิ่มใบหน้าของฉันเพื่อให้คุณเห็นการทำงานกับเอาต์พุตของกล้องพร้อมกับอีโมจิ
แอปของคุณจะไม่มีเอาต์พุตของกล้อง แต่คุณสามารถเพิ่มได้โดยเพิ่ม ARSCNView
. ของเรา , sceneView
ให้ผู้ควบคุมดูแลและกำหนดมิติ
สรุปผล
ฉันหวังว่าโพสต์นี้จะเป็นประโยชน์สำหรับคุณในการเริ่มต้นสร้างแอปด้วย ARKit
หากคุณต้องการขยายแอปนี้ให้มากขึ้น โปรดดูรายการที่ฉันกล่าวถึงข้างต้นพร้อมคุณสมบัติใบหน้าอื่นๆ ทั้งหมดที่คุณสามารถติดตามได้ ฉันทิ้งคำแนะนำไว้ว่าจะขยายเวลานี้อย่างไรเพื่อตรวจหาการขมวดคิ้วด้วย
กลับมาแสดงความคิดเห็นเกี่ยวกับโปรเจ็กต์เจ๋งๆ ที่คุณสร้างขึ้นด้วยตัวเอง ฉันยังคงรู้สึกไม่สบายใจกับสิ่งนี้ ดังนั้นฉันตื่นเต้นที่จะได้เห็นแอปที่ซับซ้อนกว่านี้
ฉันได้โพสต์รหัสทั้งหมดสำหรับแอปนี้บน Github สำหรับข้อเสนอแนะและคำถาม ขอบคุณสำหรับการอ่านและขอให้โชคดี!
ขอบคุณมากสำหรับการอ่าน! หากคุณชอบเรื่องนี้ ติดตามฉันบน Twitter ที่ฉันโพสต์อัปเดตเกี่ยวกับเรื่องราวที่ฉันกำลังดำเนินการอยู่และสิ่งที่ฉันกำลังทำอยู่