我正在尝试通过使用以下命令从当前的ARFrame
获取图像:
if let imageBuffer = sceneView.session.currentFrame?.capturedImage {
let orientation = UIApplication.shared.statusBarOrientation
let viewportSize = sceneView.bounds.size
let transformation = sceneView.session.currentFrame?.displayTransform(for: orientation, viewportSize: viewportSize)
let ciImage = CIImage(cvPixelBuffer: imageBuffer).transformed(by: transformation)
}
对于景观来说,它工作得很好。对于肖像,我得到了一个错误的角度(旋转180)的图像。知道为什么吗?
发布于 2019-02-28 00:10:14
首先,我应该说这绝对是一个令人不快的
。
问题是,当您将ARFrame包含的Portrait
图像转换为CIImage或CGImage时,它会失去方向并将其旋转180度。此问题仅影响Portrait
图像。Landscape
ones完全不受影响。
这是因为Portrait
图像在转换阶段没有关于其方向的信息,因此,即使转换为CIImage或CGImage,肖像中的图像也会保持纵向模式。
要解决此问题,您应该将“标准”景观的 width
/height
与“非标准”肖像的 width
/height
进行比较,如果这些值不同,请将图像旋转到180度CW (或应用方向大小写.portraitUpsideDown)。
希望这能有所帮助。
发布于 2021-04-14 07:16:16
坐标系
我们需要非常清楚我们使用的是哪个坐标系。我们知道UIKit的左上角是(0,0)
,右上角是(1,1)
,但CoreImage并非如此:
由于核心图像的坐标系与UIKit不匹配而导致的
...(参见here)
或视觉(包括CoreML识别):
视觉使用从0.0到1.0的标准化坐标空间,左下原点。(参见here)
但是,displayTransform
使用UIKit方向:
将捕获图像中的标准化图像坐标转换为考虑指定参数的标准化图像坐标的转换矩阵。归一化图像坐标的范围从图像左上角的(0,0)到右下角的(1,1)。(参见here)
因此,如果您将CVPixelBuffer
加载到CIImage
中,然后尝试应用displayTransform
矩阵,它将被翻转(如您所见)。但是,它也弄乱了图像。
的显示转换是什么
显示变换似乎主要用于Metal或其他较低级别的绘制例程,这些例程往往与核心图像方向相匹配。该转换缩放图像并对其进行移位,使其在指定的边界内“方面填充”。
如果你打算在UIImageView
中显示图像,那么它将被颠倒过来,因为它们的方向不同。但此外,图像视图会为您执行方面填充转换,因此没有理由进行移位或缩放,因此根本没有理由使用displayTransform
。只需将图像旋转到正确的方向即可。
// apply an orientation. You can easily make a function
// which converts the screen orientation to this parameter
let rotated = CIImage(cvPixelBuffer: frame.capturedImage).oriented(...)
imageView.image = UIImage(ciImage: rotated)
如果您想要在图像上覆盖内容,例如通过向UIImageView
添加子视图,那么displayTransform
可能会很有帮助。它会将图像坐标(在UIKit方向上)转换为图像视图中的坐标,该坐标与显示的图像(由于纵横比填充而移动和缩放)对齐。
https://stackoverflow.com/questions/54903747
复制相似问题