Вопрос или проблема
Я хочу позволить пользователям измерять размеры коробки в приложении.
На камере моего 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. С помощью этого подхода пользователи смогут легко измерять размеры коробок, используя только свою камеру. Вы можете доработать этот код, добавив более точные измерения, фильтры для улучшения качества изображения и другие функциональные возможности, чтобы сделать ваше приложение более полезным и интуитивно понятным.