Преобразование захваченного изображения ARFrame в проблему ориентации UIImage

Я хочу обнаружить мяч и заставить модель AR взаимодействовать с ним. Я использовал opencv для обнаружения мяча и отправки центра мяча, который я могу использовать в hitTest, чтобы получить координаты в sceneView. Я конвертировал CVPixelBuffer в UIImage, используя следующую функцию:

static func convertToUIImage(buffer: CVPixelBuffer) -> UIImage?{
    let ciImage = CIImage(cvPixelBuffer: buffer)
    let temporaryContext = CIContext(options: nil)
    if let temporaryImage = temporaryContext.createCGImage(ciImage, from: CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(buffer), height: CVPixelBufferGetHeight(buffer)))
    {
        let capturedImage = UIImage(cgImage: temporaryImage)
        return capturedImage
    }
    return nil
}

Это дало мне повернутое изображение:

введите описание изображения здесь

Затем я узнал об изменении ориентации с помощью:

let capturedImage = UIImage(cgImage: temporaryImage, scale: 1.0, orientation: .right)

Хотя он дал правильную ориентацию, когда устройство было в портретной ориентации, поворот устройства в альбомную ориентацию снова дал повернутое изображение.

Теперь думаю о том, чтобы справиться с этим с помощью viewWillTransition. Но перед этим я хочу знать:

  1. Есть ли другой способ конвертировать изображение с правильной ориентацией?
  2. Почему это происходит?

person Alok Subedi    schedule 26.01.2018    source источник


Ответы (1)


1. Есть ли другой способ преобразовать изображение с правильной ориентацией?

Вы можете попробовать использовать snapshot() из ARSCNView (унаследованный от SCNView), который:

Рисует содержимое представления и возвращает его как новый объект изображения

поэтому, если у вас есть такой объект, как:

@IBOutlet var arkitSceneView:ARSCNView!

вам нужно только это сделать:

let imageFromArkitScene:UIImage? = arkitSceneView.snapshot()

2. Почему это происходит?

Это потому, что CVPixelBuffer происходит от ARFrame, то есть:

захватывается (непрерывно) с камеры устройства во время текущего сеанса дополненной реальности.

Что ж, поскольку ориентация камеры не меняется с поворотом устройства (они отдельные), чтобы иметь возможность настроить ориентацию вашего кадра в соответствии с текущим видом, вы должны переориентировать изображение, снятое с вашей камеры, применяя аффинный преобразование извлечено с помощью displayTransform(for:viewportSize:):

Возвращает аффинное преобразование для преобразования между нормализованными координатами изображения и пространством координат, подходящим для рендеринга изображения камеры на экране.

вы можете найти хорошую документацию здесь, пример использования:

let orient = UIApplication.shared.statusBarOrientation
let viewportSize = yourSceneView.bounds.size
let transform = frame.displayTransform(for: orient, viewportSize: viewportSize).inverted()
var finalImage = CIImage(cvPixelBuffer: pixelBuffer).transformed(by: transform)
person Andrea Mugnaini    schedule 26.01.2018
comment
Спасибо за Ваш ответ. Снимок никогда не был вариантом, потому что я должен находить мяч в каждом кадре. 'displayTransform (for: viewportSize :):' может быть тем, что мне нужно. - person Alok Subedi; 26.01.2018
comment
Добро пожаловать, надеюсь, вы найдете хороший компромисс. Кроме того, если вам нужно обрабатывать каждый кадр, может быть лучше использовать буфер пикселей + displayTransform, похоже, более производительное решение. - person Andrea Mugnaini; 26.01.2018
comment
ага, это то, что я хотел. Спасибо - person Alok Subedi; 26.01.2018
comment
Я обнаружил, что при корректировке ориентации изображения все еще растягиваются. Например: stackoverflow.com/questions/58501761/ - person Joe; 12.03.2020