gpt4 book ai didi

augmented-reality - iOS 还原相机投影

转载 作者:IT王子 更新时间:2023-10-29 07:30:35 36 4
gpt4 key购买 nike

我正在尝试估计我的设备在空间中与二维码相关的位置。我正在使用 iOS11 中引入的 ARKit 和 Vision 框架,但这个问题的答案可能不取决于它们。

借助 Vision 框架,我能够在相机框架中获取限定 QR 码的矩形。我想将此矩形与从标准位置转换 QR 码所需的设备平移和旋转相匹配。

例如,如果我观察框架:

*            *

B
C
A
D


* *

如果我距离 QR 码 1 米,以它为中心,假设 QR 码有 10 厘米的边,我会看到:

*            *


A0 B0

D0 C0


* *

这两个框架之间我的设备转换是什么?我知道可能无法获得准确的结果,因为观察到的 QR 码可能略微不是平面的,而我们正试图在不完美的事物上估计仿射变换。

我想 sceneView.pointOfView?.camera?.projectionTransformsceneView.pointOfView?.camera?.projectionTransform?.camera.projectionMatrix 更有帮助,因为后来已经考虑了从 ARKit 推断出的转换,我对此问题不感兴趣。

我要怎么填写

func get transform(
qrCodeRectangle: VNBarcodeObservation,
cameraTransform: SCNMatrix4) {
// qrCodeRectangle.topLeft etc is the position in [0, 1] * [0, 1] of A0

// expected real world position of the QR code in a referential coordinate system
let a0 = SCNVector3(x: -0.05, y: 0.05, z: 1)
let b0 = SCNVector3(x: 0.05, y: 0.05, z: 1)
let c0 = SCNVector3(x: 0.05, y: -0.05, z: 1)
let d0 = SCNVector3(x: -0.05, y: -0.05, z: 1)

let A0, B0, C0, D0 = ?? // CGPoints representing position in
// camera frame for camera in 0, 0, 0 facing Z+

// then get transform from 0, 0, 0 to current position/rotation that sees
// a0, b0, c0, d0 through the camera as qrCodeRectangle
}

====编辑====

在尝试了很多东西之后,我最终使用 openCV 投影和透视求解器进行相机姿势估计,solvePnP 这给了我一个旋转和平移,应该代表 QR 码引用中的相机姿势.然而,当使用这些值并放置对应于逆变换的对象时,QR 码应该在相机空间中,我得到不准确的移位值,并且我无法使旋转工作:

// some flavor of pseudo code below
func renderer(_ sender: SCNSceneRenderer, updateAtTime time: TimeInterval) {
guard let currentFrame = sceneView.session.currentFrame, let pov = sceneView.pointOfView else { return }
let intrisics = currentFrame.camera.intrinsics
let QRCornerCoordinatesInQRRef = [(-0.05, -0.05, 0), (0.05, -0.05, 0), (-0.05, 0.05, 0), (0.05, 0.05, 0)]

// uses VNDetectBarcodesRequest to find a QR code and returns a bounding rectangle
guard let qr = findQRCode(in: currentFrame) else { return }

let imageSize = CGSize(
width: CVPixelBufferGetWidth(currentFrame.capturedImage),
height: CVPixelBufferGetHeight(currentFrame.capturedImage)
)

let observations = [
qr.bottomLeft,
qr.bottomRight,
qr.topLeft,
qr.topRight,
].map({ (imageSize.height * (1 - $0.y), imageSize.width * $0.x) })
// image and SceneKit coordinated are not the same
// replacing this by:
// (imageSize.height * (1.35 - $0.y), imageSize.width * ($0.x - 0.2))
// weirdly fixes an issue, see below

let rotation, translation = openCV.solvePnP(QRCornerCoordinatesInQRRef, observations, intrisics)
// calls openCV solvePnP and get the results

let positionInCameraRef = -rotation.inverted * translation
let node = SCNNode(geometry: someGeometry)
pov.addChildNode(node)
node.position = translation
node.orientation = rotation.asQuaternion
}

这是输出:

enter image description here

其中 A、B、C、D 是按传递给程序的顺序排列的 QR 码角。

当手机旋转时,预测的原点保持不变,但它偏离了应有的位置。令人惊讶的是,如果我改变观察值,我能够更正这个:

  // (imageSize.height * (1 - $0.y), imageSize.width * $0.x)
// replaced by:
(imageSize.height * (1.35 - $0.y), imageSize.width * ($0.x - 0.2))

enter image description here

现在预测的起源稳固地保持在原位。但是我不明白移位值从何而来。

最后,我尝试相对于 QR 码引用固定方向:

    var n = SCNNode(geometry: redGeometry)
node.addChildNode(n)
n.position = SCNVector3(0.1, 0, 0)
n = SCNNode(geometry: blueGeometry)
node.addChildNode(n)
n.position = SCNVector3(0, 0.1, 0)
n = SCNNode(geometry: greenGeometry)
node.addChildNode(n)
n.position = SCNVector3(0, 0, 0.1)

当我直视 QR 码时,方向很好,但随后它发生了一些似乎与手机旋转有关的变化:enter image description here

我有 Unresolved 问题是:

  • 如何解决旋转问题?
  • 位置偏移值从何而来?
  • 旋转、平移、QRCornerCoordinatesInQRRef、观察、本征验证什么简单关系?是 O ~ K^-1 * (R_3x2 | T) Q 吗?因为如果是这样的话,那就相差几个数量级了。

如果这有帮助,这里有一些数值:

Intrisics matrix
Mat 3x3
1090.318, 0.000, 618.661
0.000, 1090.318, 359.616
0.000, 0.000, 1.000

imageSize
1280.0, 720.0
screenSize
414.0, 736.0

==== 编辑2 ====

我注意到当手机与 QR 码保持水平平行时旋转效果很好(即旋转矩阵为 [[a, 0, b], [0, 1, 0], [c, 0, d]]),不管二维码的实际方向是什么:

enter image description here

其他旋转不起作用。

最佳答案

坐标系对应

考虑到 Vision/CoreML 坐标系与 ARKit/SceneKit 坐标系不对应.详情看this post .

旋转方向

我想问题不在矩阵中。它位于顶点位置。要跟踪 2D 图像,您需要逆时针放置 ABCD 顶点(起点是位于假想原点 x:0, y:0 的 A 顶点)。我认为关于 VNRectangleObservation 的 Apple 文档类(关于图像分析请求检测到的投影矩形区域的信息)是模糊的。您放置顶点的​​顺序与官方文档中的顺序相同:

var bottomLeft: CGPoint
var bottomRight: CGPoint
var topLeft: CGPoint
var topRight: CGPoint

但它们的放置方式与笛卡尔坐标系中出现的正旋转方向(关于 Z 轴)相同:

enter image description here

ARKit(以及 SceneKit 和 Vision)中的世界坐标空间始终遵循 右手惯例(正 Y 轴指向上方,正 Z 轴指向观察者,正向 X 轴指向观察者的右侧),但方向取决于 session 的配置。相机在局部坐标空间中工作。

绕任何轴的旋转方向为正(逆时针)和负(顺时针)。对于 ARKit 和 Vision 中的跟踪,这一点至关重要。

enter image description here

旋转的顺序也是有道理的。 ARKit 和 SceneKit 以组件的相反顺序应用相对于节点的 pivot 属性的旋转:首先是 roll(关于 Z 轴),然后是 yaw (关于 Y 轴),然后是 pitch(关于 X 轴)。所以旋转顺序是ZYX

关于augmented-reality - iOS 还原相机投影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44579839/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com