SwiftUI + Core ML + ARKit - Tạo ứng dụng iOS phát hiện đối tượng

Trong khi tôi đang đọc và nghiên cứu các bài báo về iOS trên Medium gần đây, tôi nhận ra rằng có rất ít bài viết về Core ML, ARKit và SwiftUI. Đó là lý do tại sao tôi muốn gộp ba thư viện này lại với nhau và viết một ứng dụng đơn giản.

Tóm lại, ứng dụng sử dụng phiên bản Swift của thư viện deep learning có tên là ResNet được viết bằng Python.

Bây giờ chúng ta hãy nói về logic ứng dụng. Khi chúng tôi nhấp vào màn hình trong ứng dụng, chúng tôi sẽ chụp hình ảnh hiện tại của trung tâm màn hình, xử lý nó với mô hình Core ML của chúng tôi và tạo văn bản thực tế tăng cường. Logic rất đơn giản.

Khóa học Lập trình di động iOS Swift tại Techmaster

Hãy bắt đầu!

Đầu tiên, chúng tôi tải xuống mô hình của chúng tôi từ các mô hình do Apple cung cấp và đặt mô hình của chúng tôi vào thư mục gốc dự án của chúng tôi. Một trong những điều chúng ta cần chú ý ở đây là thiết bị mục tiêu của chúng ta là thiết bị thực. Nếu không, mô hình và ARView có thể bị lỗi. Tôi đoán đó là lỗi Xcode.

Chúng ta sẽ làm gì?

Chúng tôi sẽ tạo một dự án thực tế tăng cường có giao diện là SwiftUI. Sau đó, chúng tôi sẽ xóa tên Experience.rcproject trong dự án. Chúng tôi không cần nó.

Sau đó, chúng tôi sẽ tạo mô hình ResNet của chúng tôi trong UIViewRepresentable. Vì mô hình ResNet của chúng tôi có thể gây ra lỗi, chúng tôi định cấu hình mô hình của mình theo do catch khối.

let resnetModel : Resnet50 = {
    do {
        let configuration = MLModelConfiguration()
        return try Resnet50(configuration: configuration)
    } catch let error {
        fatalError("Error An Occurred: ", error)
    }
}()

Chúng tôi di chuyển hằng số của chúng tôi được đặt tên là arView trong makeUIView() ra khỏi hàm và tạo ra một đối tượng ARRaycastResult mà chúng ta có thể nhận được thông tin của điểm chạm trên màn hình và một mảng VNRequest nơi chúng tôi sẽ thu thập các yêu cầu cốt lõi ML của chúng tôi.

let arView = ARView (frame: .zero)
var hitTestResultValue: ARRaycastResult!
var visionRequests = [VNRequest] ()

Sau khi hoàn thành tất cả các bước này, chúng tôi xác định một Coordinator lớp trong Struct và cung cấp một tham chiếu đến phương thức init trong lớp vào đối tượng UIViewRepresentable của chúng tôi và giới thiệu nó với đối tượng UIViewRepesentable của chúng tôi bằng hàm makeCoordinator().

Chúng tôi đã thực hiện các hoạt động đơn giản cho đến nay. Bây giờ chúng ta hãy chuyển sang các thao tác chính.

Đầu tiên, chúng ta thêm một tapGesture để đối tượng arView trong hàm makeUIView() và thêm các phương thức action để vào lớp Coordinator của chúng tôi.

func makeUIView(context: Context) -> ARView {
    let tapGesture = UITapGestureRecognizer(
        target: context.coordinator,
        action: #selector(Coordinator.tapGestureMethod(_:))
    )
    arView.addGestureRecognizer(tapGesture)
    return arView
}

Đây là công việc của chúng ta trong UIViewRepresentable. Bây giờ chúng ta hãy chuyển sang các thao tác trong lớp Coordinator .

Đầu tiên, chúng ta tạo một hàm mà trong đó chúng ta sẽ đặt tên đối tượng được xác định trên màn hình và xác định một tham số văn bản cho hàm này.

Hãy nói về hàm một cách ngắn gọn. Chúng tôi tạo một đối tượng thực tế tăng cường trong hàm genrateText trong lớp meshresource và chúng tôi tạo một đối tượng Simple Material. Những đối tượng này giúp áp dụng một số thuộc tính (v.v. màu sắc, độ nhám) cho đối tượng thực tế tăng cường của chúng ta.

Chúng tôi chuyển đổi vật liệu này thành một đối tượng Entity, và theo tọa độ trong rayCastValue chúng tôi đã tạo ở trên, chúng tôi đặt nó theo tọa độ trong thế giới thực.

Và sau đó chúng tôi tạo một hàm trong visionRequest tên sẽ xử lý hình ảnh. Hàm này nhận một giá trị của kiểu “ CVPixelBuffer ”.

Sau khi tạo một yêu cầu Core ML thông qua chức năng xử lý yêu cầu này, chúng tôi đã tạo một đối tượng văn bản trong thế giới thực với tên và tỷ lệ phần trăm của đối tượng mà chúng tôi muốn hiển thị thông tin.

Là quá trình cuối cùng, chúng tôi tạo phương thức của chúng tôi được gắn nhãn obj. Trong phương pháp này, chúng tôi có được các vị trí 3D trong thế giới thực theo tọa độ màn hình đến từ đối tượng tapGesture của chúng tôi nhờ vào phương thức raycast của chúng tôi.

Sau khi chúng tôi nhận được ảnh chụp nhanh thời điểm khi chúng tôi nhấp vào màn hình này, vị trí chúng tôi đã nhấp từ dữ liệu này là rayCastResultValue. Chúng tôi đang chuyển hằng số và ảnh chụp màn hình mà chúng tôi thu được tại thời điểm đó sang phương pháp của chúng tôi, sau đó chúng tôi gửi ảnh chụp màn hình này đến mô hình Core ML của chúng tôi.

Kết quả

Chỉ có một vấn đề nhỏ ở đây. Các đối tượng văn bản dường như không có hai mặt và không có API cho việc này. Tôi hy vọng Apple sẽ sớm mang lại một số đổi mới cho vấn đề này.

Phần kết luận

Sử dụng Core ML và thư viện ARKit4, chúng tôi đã phát triển một ứng dụng nhận dạng đối tượng trong giao diện SwiftUI. Bạn có thể tìm thấy toàn bộ dự án trên GitHub. Tôi đã để lại các nguồn hữu ích bên dưới để biết thêm thông tin.

Cảm ơn bạn đã đọc!

Core ML

https://developer.apple.com/documentation/vision/recognizing_objects_in_live_capture

https://www.raywenderlich.com/7960296-core-ml-and-vision-tutorial-on-device-training-on-ios

ARKit

https://developer.apple.com/augmented-reality/

https://medium.com/flawless-app-stories/how-to-enforce-swift-style-and-conventions-into-the-project-using-swiftlint-7588b4ffba66

Tìm hiểu thêm về khóa học lập trình di động iOS Swift tại Techmaster - dành cho người mới bắt đầu

Nguồn bài viết tại đây