ARKit có vẻ đáng sợ nhưng sẽ không quá tệ nếu bạn đã có một số kinh nghiệm cơ bản về xây dựng ứng dụng iOS.
Tôi thuộc tuýp người vừa học vừa làm, vì vậy tôi đã chơi với ARKit, xây dựng các ứng dụng cơ bản để làm quen với nó. Trong bài đăng này, tôi sẽ xem lại những gì tôi đã học được để tạo một ứng dụng theo dõi khuôn mặt đơn giản.
Tôi sẽ làm điều này thành 3 phần:
- Thiết lập ban đầu → Trước hết, hãy nhận quyền đối với Máy ảnh và đảm bảo thiết bị có thể sử dụng ARKit.
- Theo dõi nụ cười → Bắt đầu theo dõi nụ cười với ARKit. Đây có thể là lý do bạn ở đây.
- Giao diện Người dùng → Thêm giao diện người dùng cho ứng dụng của chúng tôi, giao diện người dùng sẽ phản ứng với nụ cười.
Theo văn bản này, trình mô phỏng Xcode không hỗ trợ máy ảnh mặt trước vì vậy bạn sẽ cần một thiết bị thực để chạy ứng dụng. Thiết bị của bạn cũng sẽ cần có camera TrueDepth (iPhone X trở lên sẽ ổn).
Cuối cùng, đối với các thành viên khác của tôi trong Câu lạc bộ Copy Paste, tất cả mã đều có sẵn trên Github.
Thiết lập ban đầu
Bắt đầu bằng cách mở Xcode và tạo một dự án mới có tên “SmileTracker” (hoặc bất kỳ tên nào bạn thích).
Trước khi có thể bắt đầu theo dõi khuôn mặt, chúng ta cần thực hiện hai việc:
- Đảm bảo thiết bị của bạn hỗ trợ ARKit
- Nhận quyền truy cập máy ảnh trên thiết bị của bạn
Trong dự án mới của bạn, hãy mở ViewController.swift
. Gần đầu tệp, bên dưới import UIKit
, thêm dòng:import ARKit
. Điều này sẽ cho phép chúng tôi truy cập tất cả các tiện ích mà Apple đã cung cấp cho chúng tôi để giúp theo dõi khuôn mặt trở nên cực kỳ dễ dàng.
Bây giờ hãy thêm mã sau vào bên trong viewDidLoad
:
guard ARFaceTrackingConfiguration.isSupported else {
fatalError("Device does not support face tracking")
}
ARFaceTrackingConfiguration.isSupported
là boolean sẽ đúng nếu thiết bị chạy ứng dụng có thể hỗ trợ theo dõi khuôn mặt và false nếu không. Trong trường hợp này, nếu thiết bị không thể hỗ trợ tính năng theo dõi khuôn mặt, chúng tôi sẽ khiến ứng dụng gặp lỗi nghiêm trọng.
Tiếp theo, hãy xin phép sử dụng máy ảnh. Thêm phần sau vào viewDidLoad
dưới guard
của chúng tôi tuyên bố:
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!")
}
}
Ở đây, chúng tôi đang yêu cầu thiết bị yêu cầu quyền đối với máy ảnh. Nếu người dùng cấp quyền, chúng tôi sẽ chạy chức năng sẽ thiết lập tính năng theo dõi nụ cười của chúng tôi (đừng lo lắng về lỗi, chúng tôi sẽ triển khai chức năng này trong giây lát).
Chúng tôi bọc hàm trong Dispatch.main.sync
bởi vì chúng tôi sẽ thêm các phần tử giao diện người dùng trong chức năng này, điều này chỉ có thể được thực hiện trên chuỗi chính.
Chúng tôi cũng sẽ cần thêm Mô tả sử dụng máy ảnh vào Info.plist
của chúng tôi . Mở Info.plist
và thêm một hàng mới (bạn có thể làm điều này bằng cách đánh dấu hàng cuối cùng và nhấn enter
).
Trong hàng bạn vừa tạo, hãy thêm Privacy — Camera Usage Description
đến Key
và đảm bảo rằng Type
cột được đặt thành chuỗi. Bạn có thể để lại Value
cột trống hoặc thêm thông báo để giải thích cách bạn sẽ sử dụng máy ảnh cho người dùng.
Info.plist
của bạn bây giờ sẽ trông giống như sau:
Nếu bạn muốn thử nghiệm ứng dụng của mình cho đến nay, bạn có thể nhận xét về dòng mà chúng tôi gọi là setupSmileTracker()
. Chỉ cần nhớ bỏ ghi chú nó sau.
Nếu bạn chạy ứng dụng của mình ngay bây giờ, bạn sẽ thấy một cửa sổ bật lên yêu cầu bạn bật quyền đối với máy ảnh. Nếu bạn nói không, bạn sẽ phải đi tới cài đặt ứng dụng để bật các quyền đó nhằm chạy ứng dụng.
Nếu ứng dụng gặp sự cố, hãy kiểm tra bảng điều khiển để tìm một trong hai thông báo lỗi của chúng tôi để xem điều gì đã xảy ra.
Theo dõi nụ cười
Mở ViewController.swift
và thêm biến sau vào đầu ViewController
:
class ViewController: UIViewController {
let sceneView = ARSCNView()
override func viewDidLoad() {...}
}
ARSCNView
được trang bị một ARSession
mà iPhone của bạn sử dụng để điều phối trải nghiệm AR. Chúng tôi sẽ sử dụng sceneView
Của ARSession
để phân tích khuôn mặt của người dùng của chúng tôi thông qua camera phía trước.
Thêm chức năng này vào tệp của bạn bên dưới viewDidLoad
:
func setupSmileTracker() {
let configuration = ARFaceTrackingConfiguration()
sceneView.session.run(configuration)
sceneView.delegate = self
view.addSubview(sceneView)
}
Tại đây, chúng tôi đã tạo một cấu hình để xử lý theo dõi khuôn mặt và sử dụng cấu hình đó để chạy sceneView
của chúng tôi Của ARSession
.
Sau đó, chúng tôi đặt sceneView
được ủy quyền cho chính mình và thêm nó vào chế độ xem của chúng tôi.
Xcode sẽ cho bạn biết rằng có sự cố kể từ ViewController
không phù hợp với ARSCNViewDelegate
. Chuyển đến nơi ViewController
được khai báo ở gần đầu tệp và thay đổi dòng thành sau:
class ViewController: ViewController, ARSCNViewDelegate {
...
}
Bây giờ hãy thêm ARSCNViewDelegate
này chức năng trong ViewController
của bạn lớp setupSmileTracker
:
func renderer(_renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
...
}
renderer
sẽ chạy mỗi khi cảnh của chúng tôi cập nhật và cung cấp cho chúng tôi ARAnchor
tương ứng với khuôn mặt của người dùng.
Để tạo trải nghiệm theo dõi khuôn mặt dễ dàng hơn, Apple tự động tạo ARFaceAnchor
và thêm nó vào phiên của chúng tôi khi chúng tôi sử dụng ARFacetrackingConfiguration
để chạy nó. ARFaceAnchor này sau đó được chuyển vào renderer
dưới dạng ARAnchor
.
Thêm mã sau vào trình kết xuất:
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)
}
Có rất nhiều thứ đang diễn ra bên trong chức năng này nên tôi đã đánh số các bước (kiểu Ray Wenderlich).
Trong bước 1 chúng tôi chuyển đổi ARAnchor
thành một ARFaceAnchor
và gán nó cho faceAnchor
biến.
ARFaceAnchor
chứa thông tin về vị trí và hướng hiện tại, cấu trúc liên kết và nét mặt của khuôn mặt mà chúng tôi đang theo dõi.
ARFaceAnchor
lưu trữ thông tin về nét mặt trong biến blendShapes
của nó . blendShapes
là một từ điển lưu trữ các hệ số tương ứng với các đặc điểm khác nhau trên khuôn mặt. Nếu bạn quan tâm, tôi khuyên bạn nên xem danh sách đầy đủ các đặc điểm trên khuôn mặt trong tài liệu của Apple. ( Gợi ý :nếu bạn muốn thêm theo dõi cau mày, bạn sẽ tìm cách thực hiện việc đó tại đây.)
Trong bước 2 , chúng tôi sử dụng faceAnchor.blendShapes
để có được CGFloat tương ứng với mức độ mà bên trái và bên phải của miệng người dùng đang cười bằng cách sử dụng các phím mouthSmileLeft
và mouthSmileRight
.
Cuối cùng, bước 3 chỉ in ra hai giá trị để bạn có thể đảm bảo rằng nó đang hoạt động bình thường?.
Tại thời điểm này, bạn sẽ có một ứng dụng:
- Nhận quyền theo dõi khuôn mặt và camera từ người dùng
- Sử dụng ARKit để theo dõi nét mặt của người dùng
- In mức độ mà người dùng đang cười ở bên trái và bên phải của họ vào bảng điều khiển
Chúng tôi đã đạt được rất nhiều tiến bộ, vì vậy hãy dành một chút thời gian để đảm bảo mọi thứ hoạt động bình thường.
Khi bạn chạy ứng dụng lần đầu tiên, bạn sẽ được hỏi liệu bạn có cấp quyền cho máy ảnh hay không. Đảm bảo nói có.
Sau đó, bạn sẽ được đưa đến một màn hình trống, nhưng bạn sẽ bắt đầu thấy các giá trị CGFloat được in ra bảng điều khiển (có thể có một khoảng thời gian ngắn trước khi bạn nhìn thấy chúng).
Khi bạn mỉm cười với điện thoại của mình, bạn sẽ nhận thấy các giá trị được in tăng lên. Bạn cười càng nhiều thì con số càng cao.
Nếu nó hoạt động bình thường, xin chúc mừng ?! Nếu bạn đang gặp lỗi, hãy kiểm tra kỹ để đảm bảo thiết bị của bạn hỗ trợ tính năng theo dõi khuôn mặt và bạn đã bật quyền đối với máy ảnh. Nếu bạn đã theo dõi quá trình ghi này ngay từ đầu, bảng điều khiển sẽ in lỗi trong cả hai trường hợp đó.
Giao diện người dùng
Vì vậy, chúng tôi đang theo dõi khuôn mặt, bây giờ hãy xây dựng giao diện người dùng để phản ứng với nụ cười.
Đầu tiên hãy thêm một UILabel
mới được gọi là smileLabel
ở đầu tệp, ngay bên dưới sceneView
.
class ViewController: UIViewController {
let sceneView = ARSCNView()
let smileLabel = UILabel()
...
}
Đây sẽ là chế độ xem phản ứng với nét mặt của người dùng.
Thêm mã sau vào cuối setupSmileTracker
của bạn chức năng:
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
Tại đây, chúng tôi đang thêm các thuộc tính giao diện người dùng cơ bản vào smileLabel
của chúng tôi và thiết lập các ràng buộc của nó để nó ở giữa màn hình. Bây giờ khi bạn chạy ứng dụng, bạn sẽ thấy một người khổng lồ? biểu tượng cảm xúc ở giữa.
Khi bạn thấy biểu tượng cảm xúc xuất hiện, hãy thêm chức năng sau vào ViewController
của bạn :
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 = "?"
}
}
Chức năng này sẽ thay đổi biểu tượng cảm xúc trong smileLabel
của chúng tôi tùy thuộc vào mức độ mà người dùng đang mỉm cười với máy ảnh. Chúng tôi tính toán smileValue
bằng cách lấy giá trị trung bình của nụ cười trái và phải mà ARFaceAnchor
của chúng tôi cung cấp cho chúng tôi (rất khoa học, tôi biết).
Cắm giá trị đó vào câu lệnh chuyển đổi và người dùng cười càng nhiều thì biểu tượng cảm xúc của chúng ta càng hạnh phúc.
Cuối cùng, quay lại renderer
của chúng tôi chức năng và thêm cái này vào dưới cùng để cắm các giá trị nụ cười trái và phải của chúng ta vào handleSmile
:
DispatchQueue.main.async {
self.handleSmile(leftValue: leftSmileValue, rightValue: rightSmileValue)
}
Một lần nữa, chúng tôi sử dụng DispatchQueue
bởi vì chúng tôi đang thực hiện các thay đổi đối với giao diện người dùng, điều này phải được thực hiện trên chuỗi chính.
Khi chạy ứng dụng, bạn sẽ thấy biểu tượng cảm xúc thay đổi tùy thuộc vào mức độ bạn cười với nó.
Trong ảnh gif bên dưới, tôi đã thêm khuôn mặt của mình để bạn có thể thấy khuôn mặt hoạt động với đầu ra máy ảnh cùng với biểu tượng cảm xúc.
Ứng dụng của bạn sẽ không có đầu ra máy ảnh, nhưng bạn có thể thêm nó bằng cách thêm ARSCNView
của chúng tôi , sceneView
, vào superview và cung cấp các kích thước cho nó.
Kết thúc
Tôi hy vọng bài đăng này hữu ích để bạn bắt đầu tạo ứng dụng với ARKit.
Nếu bạn muốn mở rộng ứng dụng này hơn nữa, hãy xem danh sách tôi đã đề cập ở trên với tất cả các đặc điểm khuôn mặt khác mà bạn có thể theo dõi. Tôi đã để lại một gợi ý về cách mở rộng điều này để kiểm tra những cái cau mày.
Hãy quay lại và nhận xét về bất kỳ dự án thú vị nào bạn tự tạo, tôi vẫn còn chân ướt chân ráo với những thứ này nên rất vui khi thấy các ứng dụng phức tạp hơn.
Tôi đã đăng tất cả mã cho ứng dụng này lên Github để nhận phản hồi và câu hỏi. Cảm ơn đã đọc và chúc may mắn!
Cảm ơn rất nhiều vì đã đọc! Nếu bạn thích câu chuyện này, hãy theo dõi tôi trên Twitter, nơi tôi đăng thông tin cập nhật về những câu chuyện tôi đang làm và những gì tôi đang làm.