Computer >> คอมพิวเตอร์ >  >> สมาร์ทโฟน >> iPhone

วิธีสร้างแอปติดตามรอยยิ้มด่วนสุด ๆ

ARKit อาจดูน่ากลัว แต่ก็ไม่เลวร้ายนักหากคุณมีประสบการณ์พื้นฐานในการสร้างแอป iOS อยู่แล้ว

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

ฉันจะทำสิ่งนี้ใน 3 ส่วน:

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

ในขณะที่เขียนนี้ โปรแกรมจำลอง Xcode ไม่สนับสนุนกล้องหน้า ดังนั้น คุณจะต้องมีอุปกรณ์จริงเพื่อเรียกใช้แอป อุปกรณ์ของคุณจะต้องมีกล้อง TrueDepth ด้วย (iPhone X หรือใหม่กว่าก็ใช้ได้)

สุดท้ายนี้ สำหรับเพื่อนสมาชิก Copy Paste Club โค้ดทั้งหมดมีอยู่ใน Github

การตั้งค่าเริ่มต้น

เริ่มต้นด้วยการเปิด Xcode และสร้างโปรเจ็กต์ใหม่ชื่อ “SmileTracker” (หรือชื่ออะไรก็ได้ที่คุณต้องการ)

ก่อนที่เราจะเข้าสู่การติดตามใบหน้า เราต้องทำสองสิ่ง:

  1. ตรวจสอบให้แน่ใจว่าอุปกรณ์ของคุณรองรับ ARKit
  2. ขออนุญาตเข้าถึงกล้องของอุปกรณ์

ในโครงการใหม่ของคุณ เปิด 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 ที่ฉันโพสต์อัปเดตเกี่ยวกับเรื่องราวที่ฉันกำลังดำเนินการอยู่และสิ่งที่ฉันกำลังทำอยู่