我正在使用ARKit(使用SceneKit)添加虚拟对象(例如球) . 我通过使用Vision框架并在视觉请求完成处理程序方法中接收其更新位置来跟踪真实世界对象(例如,脚) .
let request = VNTrackObjectRequest(detectedObjectObservation: lastObservation, completionHandler: self.handleVisionRequestUpdate)
我想用虚拟替换跟踪的现实世界对象(例如用立方体替换脚)但是我不知道如何将边界框矩形(我们在视觉请求完成中接收)替换为场景套件节点,因为坐标系统是不同的 .
以下是视觉请求完成处理程序的代码:
private func handleVisionRequestUpdate(_ request: VNRequest, error: Error?) {
// Dispatch to the main queue because we are touching non-atomic, non-thread safe properties of the view controller
DispatchQueue.main.async {
// make sure we have an actual result
guard let newObservation = request.results?.first as? VNDetectedObjectObservation else { return }
// prepare for next loop
self.lastObservation = newObservation
// check the confidence level before updating the UI
guard newObservation.confidence >= 0.3 else {
return
}
// calculate view rect
var transformedRect = newObservation.boundingBox
//How to convert transformedRect into AR Coordinate
self.node.position = SCNVector3Make(?.worldTransform.columns.3.x,
?.worldTransform.columns.3.y,
}
}
请指导我转移坐标系 .
2 回答
假设矩形位于水平平面上,您可以对所有4个角上的场景执行命中测试,并使用其中3个角来计算矩形的宽度,高度,中心和方向 .
我在GitHub上有一个演示应用程序就是这样做的:https://github.com/mludowise/ARKitRectangleDetection
来自
VNRectangleObservation
的矩形角的坐标将相对于图像的大小,并且根据手机的不同坐标需要将它们乘以视图大小并根据手机的旋转反转它们:然后你可以对所有4个角进行命中测试 . 执行命中测试时使用
.existingPlaneUsingExtent
类型非常重要,以便ARKit返回水平平面的命中 .然后它变得有点复杂......
因为每个命中测试都可以返回0到n的结果,所以您需要过滤掉不同平面上包含的任何命中测试 . 你可以通过比较每个
ARHitTestResult
的锚来做到这一点:此外,如果一个角落没有返回任何命中测试结果,您只需要4个角中的3个来识别矩形's dimensions, position, and orientation so it'即可 . 看看我如何做到这一点here .
您可以根据左右角之间的距离(顶部或底部)计算矩形的宽度 . 同样,您可以根据顶角和底角之间的距离(左侧或右侧)计算矩形的高度 .
您可以通过从矩形的相对角(topLeft&bottomRight或topRight&bottomLeft)获取中点来计算其位置:
您还可以从左右角(顶部或底部)计算矩形的方向(沿y轴旋转):
然后将它们全部放在一起并在矩形上显示AR中的某些内容 . 这是通过子类化
SCNNode
显示虚拟矩形的示例:要考虑的主要是边界矩形在2D图像中,而ARKit的场景是3D . 这意味着在您选择深度之前,未定义边界矩形在3D中的位置 .
您应该做的是对场景进行命中测试以从2D坐标到3D: