#ios #swift #image-processing #augmented-reality #vdsp
Вопрос:
Я ищу быстрый способ сравнить два кадра видео и решить, много ли изменилось между ними. Это будет использовано для принятия решения о том , следует ли мне отправлять запрос в службу распознавания изображений REST
, поэтому я не хочу продолжать их отправлять, пока не появятся какие-то другие результаты. Нечто подобное происходит Vuforia SDK
и сейчас . Я начинаю с Framebuffer
«от ARKit
«, и я масштабировал его до 640:480 и преобразовал в RGB888 vBuffer_image
. Он мог бы сравнить всего несколько пунктов, но ему нужно выяснить, является ли разница существенной. Я начал с вычисления разницы между несколькими точками с помощью vDSP
функций, но у этого есть недостаток — если я перемещаю камеру даже очень немного влево/вправо, то одни и те же точки имеют разные участки изображения, и вычисленная разница высока, даже если на самом деле ничего сильно не изменилось. Я думал об использовании histograms
, но я еще не тестировал этот подход. Каково было бы лучшее решение для этого? Он должен быть быстрым, он может сравнивать только меньшую версию изображения и т. Д.
Я протестировал другой подход, используя VNFeaturePointObservation
from Vision
. Это работает намного лучше, но я боюсь, что это может быть более требовательным к процессору. Мне нужно протестировать это на некоторых старых устройствах. В любом случае, это часть кода, которая хорошо работает. Если кто-то может предложить какой-то лучший подход к тестированию, пожалуйста, дайте знать:
private var lastScanningImageFingerprint: VNFeaturePrintObservation?
// Returns true if these are different enough
private func compareScanningImages(current: VNFeaturePrintObservation, last: VNFeaturePrintObservation?) -> Bool {
guard let last = last else { return true }
var distance = Float(0)
try! last.computeDistance(amp;distance, to: current)
print(distance)
return distance > 10
}
// After scanning is done, subclass should prepare suggestedTargets array.
private func performScanningIfNeeded(_ sender: Timer) {
guard !scanningInProgress else { return } // Wait for previous scanning to finish
guard let vImageBuffer = deletate?.currentFrameScalledImage else { return }
guard let image = CGImage.create(from: vImageBuffer) else { return }
func featureprintObservationForImage(image: CGImage) -> VNFeaturePrintObservation? {
let requestHandler = VNImageRequestHandler(cgImage: image, options: [:])
let request = VNGenerateImageFeaturePrintRequest()
do {
try requestHandler.perform([request])
return request.results?.first as? VNFeaturePrintObservation
} catch {
print("Vision error: (error)")
return nil
}
}
guard let imageFingerprint = featureprintObservationForImage(image: image) else { return }
guard compareScanningImages(current: imageFingerprint, last: lastScanningImageFingerprint) else { return }
print("SCANN (Date())")
lastScanningImageFingerprint = featureprintObservationForImage(image: image)
executeScanning(on: image) { [weak self] in
self?.scanningInProgress = false
}
}
Протестировано на старых iPhone — как и ожидалось, это приводит к некоторым сбросам кадров при предварительном просмотре камеры. Поэтому мне нужен более быстрый алгоритм
Комментарии:
1. «Что было бы лучшим решением для этого?» Что делает одно решение лучшим из всех? Покажите одно из имеющихся у вас решений в коде, чтобы мы могли определить, существует ли более эффективный подход.
2. Решение такого рода проблем не является тривиальным. Вы в основном спрашиваете о компьютерном зрении. Вы можете рассмотреть возможность использования библиотеки OpenCV. Чем больше вы знаете об изображениях, которые сравниваете, тем больше вы можете адаптировать свой алгоритм сравнения к данным. Всегда ли изображения одного и того же предмета? Есть ли на изображении геометрические фигуры, которые вы можете искать? В контексте, в котором вы работаете, есть ли у вас представление о том, что означает «многое», которое меняется? Вы ищете изменения в форме? Должность? Яркость? Цвет?
3. Приложение, над которым я работаю, — это приложение AR, которое отображает видео на фотографиях. Проблема в том, что моя база данных содержит около 1000 изображений, поэтому один только АРКит не может с ними справиться. Вместо этого — когда ARKit ничего не обнаруживает, я использую веб-сервис Vuforia, если он может видеть что-либо на кадре, и тогда я могу загрузить, например, до 25 изображений одновременно для отслеживания ARKit. Я хочу ограничить количество запросов, отправляемых веб — сервису Vuforia-если на одном кадре он не обнаружил никакой цели, то я хотел бы отправить другой запрос, только если, например, пользователь много перемещает камеру или добавил изображение перед камерой.