将 ARFrame 的抓图转为 UIImage 方向问题
Convert ARFrame's captured image to UIImage orientation issue
我想检测球并让 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.还有其他方法可以将图像转换为正确的方向吗?
您可以尝试使用 ARSCNView
的 snapshot()
(继承自 SCNView
),其中:
Draws the contents of the view and returns them as a new image object
所以如果你有一个像这样的对象:
@IBOutlet var arkitSceneView:ARSCNView!
你只需要这样做:
let imageFromArkitScene:UIImage? = arkitSceneView.snapshot()
2。为什么会这样?
因为CVPixelBuffer
来自ARFrame
,也就是:
captured (continuously) from the device camera, by the running AR session.
好吧,由于相机方向不会随着设备的旋转而改变(它们是分开的),为了能够将框架的方向调整为当前视图,您应该重新调整从中捕获的图像的方向你的相机应用了用 displayTransform(for:viewportSize:)
:
提取的仿射变换
Returns an affine transform for converting between normalized image coordinates and a coordinate space appropriate for rendering the camera image onscreen.
您可能会找到很好的文档 here,用法示例:
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)
我想检测球并让 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.还有其他方法可以将图像转换为正确的方向吗?
您可以尝试使用 ARSCNView
的 snapshot()
(继承自 SCNView
),其中:
Draws the contents of the view and returns them as a new image object
所以如果你有一个像这样的对象:
@IBOutlet var arkitSceneView:ARSCNView!
你只需要这样做:
let imageFromArkitScene:UIImage? = arkitSceneView.snapshot()
2。为什么会这样?
因为CVPixelBuffer
来自ARFrame
,也就是:
captured (continuously) from the device camera, by the running AR session.
好吧,由于相机方向不会随着设备的旋转而改变(它们是分开的),为了能够将框架的方向调整为当前视图,您应该重新调整从中捕获的图像的方向你的相机应用了用 displayTransform(for:viewportSize:)
:
Returns an affine transform for converting between normalized image coordinates and a coordinate space appropriate for rendering the camera image onscreen.
您可能会找到很好的文档 here,用法示例:
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)