Как мне создать простое приложение камеры в Swift с помощью CoreML, которое не использует интерактивный ввод?

Я пытался создать простое приложение для распознавания изображений с камеры в xcode с быстрым, которое позволяет пользователю делать снимки. Затем фотография вводится в уже обученную модель coreML, а результат с предсказанной точностью выводится на метку.

Я искал несколько веб-сайтов, и все, что я могу найти, это учебные пособия, такие как

https://medium.freecodecamp.org/ios-coreml-vision-image-recognition-3619cf319d0b

которые позволяют распознавать изображения в режиме реального времени. Я не хочу, чтобы это было в реальном времени, а просто позволить кому-то сделать снимок. Я хотел бы знать, как преобразовать этот код таким образом, чтобы он не был живым вводом:

  import UIKit
  import AVFoundation
  import Vision

class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
let label: UILabel = {
    let label = UILabel()
    label.textColor = .white
    label.translatesAutoresizingMaskIntoConstraints = false
    label.text = "Label"
    label.font = label.font.withSize(30)
    return label
}()
override func viewDidLoad() {

    super.viewDidLoad()

    // establish the capture session and add the label
    setupCaptureSession()
    view.addSubview(label)
    setupLabel()
    // Do any additional setup after loading the view, typically from a nib.
}
func setupCaptureSession() {
    // create a new capture session
    let captureSession = AVCaptureSession()

    // find the available cameras
    let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices

    do {
        // select a camera
        if let captureDevice = availableDevices.first {
            captureSession.addInput(try AVCaptureDeviceInput(device: captureDevice))
        }
    } catch {
        // print an error if the camera is not available
        print(error.localizedDescription)
    }

    // setup the video output to the screen and add output to our capture session
    let captureOutput = AVCaptureVideoDataOutput()
    captureSession.addOutput(captureOutput)
    let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = view.frame
    view.layer.addSublayer(previewLayer)

    // buffer the video and start the capture session
    captureOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
    captureSession.startRunning()
}

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    // load our CoreML Pokedex model
    guard let model = try? VNCoreMLModel(for: aslModel().model) else { return }

    // run an inference with CoreML
    let request = VNCoreMLRequest(model: model) { (finishedRequest, error) in

        // grab the inference results
        guard let results = finishedRequest.results as? [VNClassificationObservation] else { return }

        // grab the highest confidence result
        guard let Observation = results.first else { return }

        // create the label text components
        let predclass = "\(Observation.identifier)"
        let predconfidence = String(format: "%.02f%", Observation.confidence * 100)

        // set the label text
        DispatchQueue.main.async(execute: {
            self.label.text = "\(predclass) \(predconfidence)"
        })
    }


    // create a Core Video pixel buffer which is an image buffer that holds pixels in main memory
    // Applications generating frames, compressing or decompressing video, or using Core Image
    // can all make use of Core Video pixel buffers
    guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }

    // execute the request
    try? VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]).perform([request])
}
func setupLabel() {
    // constrain the label in the center
    label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

    // constrain the the label to 50 pixels from the bottom
    label.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50).isActive = true
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

Прямо сейчас, как было сказано ранее, он принимает ввод изображения в реальном времени.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
309
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я написал об этом пост на Medium, но он на португальском языке. Посмотрите, позволяет ли автоматический перевод Medium понять пост.

Свифт + базовое машинное обучение

Я надеюсь это тебе поможет.

Спасибо, это привело меня в правильном направлении. Мне просто интересно, есть ли причина, по которой вход в модель должен быть CIImage? И мне также было интересно, поскольку ожидаемый ввод модели, которую я использую, представляет собой изображение 112 на 112, должен ли я увеличивать изображение перед его вводом в модель?

Nikhil Chandra 09.04.2019 22:04

CIImage был использован из-за init из VNImageRequestHandler. Это зависит от вашей модели, какая модель имеет свои собственные входные свойства. Вы должны проверить это, когда будете добавлять свою модель в проект.

J. Lopes 10.04.2019 01:50

Другие вопросы по теме