Быстрое видение для определения размеров коробки

Вопрос или проблема

Я хочу позволить пользователям измерять размеры коробки в приложении.

На камере моего iPhone я заметил, что могу измерить объект, перемещая камеру вдоль него. Как я могу представить камеру в SwiftUI, которая позволяет пользователю сделать 3 измерения (Ш, В, Д)? Также есть ли способ использовать фреймворк Vision для обнаружения прямоугольного объекта на изображении и получения его размеров?

пример копируемого кода, который на самом деле не работает.

import UIKit
import Vision

func detectBoxDimensions(in image: UIImage, completion: @escaping (CGRect?) -> Void) {
   guard let cgImage = image.cgImage else {
       completion(nil)
       return
   }
   
   let request = VNDetectRectanglesRequest { request, error in
       guard let results = request.results as? [VNRectangleObservation],
             let box = results.first else {
           completion(nil)
           return
       }
       
       // Преобразовать нормализованные координаты в координаты изображения
       let imageWidth = CGFloat(cgImage.width)
       let imageHeight = CGFloat(cgImage.height)
       
       // Получить ограничивающий прямоугольник для обнаруженного прямоугольника
       let boundingBox = box.boundingBox
       let boxFrame = CGRect(
           x: boundingBox.origin.x * imageWidth,
           y: (1 - boundingBox.origin.y - boundingBox.height) * imageHeight,
           width: boundingBox.width * imageWidth,
           height: boundingBox.height * imageHeight
       )
       
       completion(boxFrame)
   }
   
   request.minimumAspectRatio = VNAspectRatio(0.5)
   request.maximumAspectRatio = VNAspectRatio(1.5)
   
   let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
   
   DispatchQueue.global().async {
       do {
           try handler.perform([request])
       } catch {
           print("Ошибка при выполнении обнаружения прямоугольников: \(error)")
           completion(nil)
       }
   }
}

Ответ или решение

Определение размеров коробки с помощью Vision и SwiftUI

В современном мире мобильных технологий возникает все больше возможностей для создания удобных приложений. Если вы хотите разработать приложение, которое будет позволять пользователям измерять размеры коробок с использованием камеры iPhone, то вот подробное руководство, как это можно реализовать с помощью Swift и Vision.

Использование Vision Framework для обнаружения прямоугольников

Vision — это мощная библиотека от Apple, позволяющая выполнять задачи компьютерного зрения. Для обнаружения размеров коробки мы можем использовать VNDetectRectanglesRequest, который позволяет находить прямоугольные объекты на изображении.

Основная функция для обнаружения размеров

Ваша исходная функция detectBoxDimensions содержит основные принципы работы, однако предлагаю несколько улучшений и сопутствующих комментариев:

import UIKit
import Vision

func detectBoxDimensions(in image: UIImage, completion: @escaping (CGRect?) -> Void) {
    guard let cgImage = image.cgImage else {
        completion(nil)
        return
    }

    let request = VNDetectRectanglesRequest { request, error in
        guard error == nil else {
            print("Ошибка обнаружения: \(error!.localizedDescription)")
            completion(nil)
            return
        }

        guard let results = request.results as? [VNRectangleObservation],
              let box = results.first else {
            completion(nil)
            return
        }

        let imageWidth = CGFloat(cgImage.width)
        let imageHeight = CGFloat(cgImage.height)
        let boundingBox = box.boundingBox
        let boxFrame = CGRect(
            x: boundingBox.origin.x * imageWidth,
            y: (1 - boundingBox.origin.y - boundingBox.height) * imageHeight,
            width: boundingBox.width * imageWidth,
            height: boundingBox.height * imageHeight
        )

        completion(boxFrame)
    }

    request.minimumAspectRatio = VNAspectRatio(0.5)
    request.maximumAspectRatio = VNAspectRatio(1.5)

    let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])

    DispatchQueue.global().async {
        do {
            try handler.perform([request])
        } catch {
            print("Ошибка выполнения запроса: \(error)")
            completion(nil)
        }
    }
}

Интеграция с SwiftUI для визуализации камеры

Для создания пользовательского интерфейса с возможностью захвата изображения и отображения камеры можно использовать UIViewControllerRepresentable для интеграции UIImagePickerController или использовать AVCaptureSession.

Вот пример, что можно сделать с AVCaptureSession:

import SwiftUI
import AVFoundation

struct CameraView: UIViewControllerRepresentable {
    class Coordinator: NSObject, AVCapturePhotoCaptureDelegate {
        var parent: CameraView

        init(parent: CameraView) {
            self.parent = parent
        }

        func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
            guard let imageData = photo.fileDataRepresentation(),
                  let image = UIImage(data: imageData) else { return }
            detectBoxDimensions(in: image) { boxFrame in
                // Обработка полученных размеров коробки
                print("Размеры коробки: \(String(describing: boxFrame))")
            }
        }
    }

    func makeUIViewController(context: Context) -> UIViewController {
        let viewController = UIViewController()
        let captureSession = AVCaptureSession()
        guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return viewController }
        let videoInput: AVCaptureDeviceInput

        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            return viewController
        }

        if (captureSession.canAddInput(videoInput)) {
            captureSession.addInput(videoInput)
        } else {
            return viewController
        }

        let photoOutput = AVCapturePhotoOutput()
        if (captureSession.canAddOutput(photoOutput)) {
            captureSession.addOutput(photoOutput)
        } else {
            return viewController
        }

        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = viewController.view.layer.bounds
        previewLayer.videoGravity = .resizeAspectFill
        viewController.view.layer.addSublayer(previewLayer)

        captureSession.startRunning()

        return viewController
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}

struct ContentView: View {
    var body: some View {
        CameraView()
            .edgesIgnoringSafeArea(.all)
    }
}

Выводы

Мы рассмотрели, как интегрировать функцию обнаружения коробок с использованием Vision и обработку изображений с применением SwiftUI. С помощью этого подхода пользователи смогут легко измерять размеры коробок, используя только свою камеру. Вы можете доработать этот код, добавив более точные измерения, фильтры для улучшения качества изображения и другие функциональные возможности, чтобы сделать ваше приложение более полезным и интуитивно понятным.

Оцените материал
Добавить комментарий

Капча загружается...