Как правильно перевести ось X из ограничивающего поля VNFaceObservation (Vision + ARKit) - PullRequest
0 голосов
/ 06 января 2019

Я использую ARKit & Vision, следуя примеру проекта Apple «Использование Vision в реальном времени с ARKit». Так что я не настраиваю свою камеру, поскольку ARKit справляется с этим для меня.

Используя VNDetectFaceRectanglesRequest от Vision, я могу получить коллекцию объектов VNFaceObservation.

Следуя различным инструкциям в Интернете, я могу преобразовать ограничивающий ящик VNFaceObservation в тот, который я могу использовать в UIView моего ViewController.

Ось Y является правильной, если ее поместить в мой UIView в ARKit, но ось X полностью отключена и неточна.

// face is an instance of VNFaceObservation  
let transform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -view.frame.height)  
let translate = CGAffineTransform.identity.scaledBy(x: view.frame.width, y: view.frame.height)  
let rect = face.boundingBox.applying(translate).applying(transform)  

Как правильно отобразить boundingBox на экране (в ARKit / UIKit), чтобы ось X и Y соответствовала правильно обнаруженному прямоугольнику лица? Я не могу использовать self.cameraLayer.layerRectConverted(fromMetadataOutputRect: transformedRect), так как я не использую AVCaptureSession.


Обновление: углубляясь в это, изображение камеры составляет 1920 x 1440. Большая часть изображения не отображается на экране ARKit. Экран iPhone XS составляет 375 х 812 точек.

После того, как я получил BindingBox для наблюдения Vision, я преобразовал его, чтобы он соответствовал текущему виду (375 x 812). Это не работает, так как фактическая ширина кажется 500 (левая и правая стороны находятся за пределами экрана). Как мне CGAffineTransform ограничивающий прямоугольник CGRect (кажется, 500x812, общее предположение) из 375x812?

1 Ответ

0 голосов
/ 13 февраля 2019

Здесь отсутствует ключевая часть displayTransform(for:viewportSize:) ARFrame. Вы можете прочитать документацию для этого здесь .

Эта функция сгенерирует соответствующее преобразование для данного кадра и размера области просмотра (CGRect вида, в котором вы отображаете изображение и ограничивающий прямоугольник).

func visionTransform(frame: ARFrame, viewport: CGRect) -> CGAffineTransform {
    let orientation = UIApplication.shared.statusBarOrientation
    let transform = frame.displayTransform(for: orientation,
                                           viewportSize: viewport.size)
    let scale = CGAffineTransform(scaleX: viewport.width,
                                  y: viewport.height)

    var t = CGAffineTransform()
    if orientation.isPortrait {
        t = CGAffineTransform(scaleX: -1, y: 1)
        t = t.translatedBy(x: -viewport.width, y: 0)
    } else if orientation.isLandscape {
        t = CGAffineTransform(scaleX: 1, y: -1)
        t = t.translatedBy(x: 0, y: -viewport.height)
    }

    return transform.concatenating(scale).concatenating(t)
}

Затем вы можете использовать это так:

let transform = visionTransform(frame: yourARFrame, viewport: yourViewport)
let rect = face.boundingBox.applying(transform)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...