我目前正在使用ARKit 2.0(测试版)来进行一些图像识别,而我正在努力解决一件事。 当我检测到图像时,会在其旁边放置一个对象(无论是哪个对象,它只是一个节点,其中包含基于所找到图像的材质)。
我的问题是:当重新找到找到的图像时(是否该节点也与imageanchor关联),是否会触发ARKit函数?我正在寻找正确的信息,但没有找到任何好的方法
答案 0 :(得分:4)
在ARKit 3中,我设法使用renderer(_:didUpdate:for)
检测图像何时从视图中消失,并检查锚点的isTracked
属性何时设置为false
。
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
if let imageAnchor = anchor as? ARImageAnchor, imageAnchor.isTracked == false {
view?.sceneView.session.remove(anchor: anchor)
}
}
答案 1 :(得分:1)
当您配置用于检测图像的ARKit会话时,检测到图像时会将锚添加到场景中,并调用 renderer(renderer:nodeFor anchor:)方法。
当图像隐藏并“重新出现”在屏幕上时,我猜应该调用 renderer(renderer:didUpdate节点:用于锚点:)。
如果没有,那么它将再次调用renderer(renderer:nodeFor anchor :)方法,您可以插入一些基于布尔的简单逻辑来检查它是否是第一次检测。
编辑:
我是通过纸牌游戏做到的。 您有一个带有名称的ARReferenceImage存储。 当您呈现目标时,renderer(_ renderer:SCNSceneRenderer,nodeFor锚点:ARAnchor)-> SCNNode?被称为。
将其名称作为可选名称存储在foundImagesNames:[String]中。
然后将其从相机中删除,放回去,再次调用它。 然后,您只需检查是否已被检测到即可。
if let imageAnchor = anchor as? ARImageAnchor,
let name = imageAnchor.referenceImage.name {
if self.foundImagesNames.contains(name) {
//already presented
}
else {
//first time presenting
self.foundImagesNames.append(name)
}
}
答案 2 :(得分:1)
我只想把我的两分钱扔在这里。
如果您查看ARKit文档-它说:
https://developer.apple.com/documentation/arkit/recognizing_images_in_an_ar_experience
考虑何时允许检测每个图像以触发(或重复) AR互动。 ARKit一次将图像锚点添加到会话一次 会话配置的 detectionImages数组。如果您的AR体验会向其中添加虚拟内容 检测到图像时的场景,默认情况下该操作 只发生一次。为了允许用户再次体验该内容 无需重新启动您的应用,请调用会话的remove(anchor :)方法 删除相应的ARImageAnchor。后锚是 移除后,ARKit会在下次检测到 图片。
我还要指出,ARkit中有两个不同的ARConfiguration子类可以进行图像检测:
ARWorldTrackingConfiguration: https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration
ARImageTrackingConfiguration: https://developer.apple.com/documentation/arkit/arimagetrackingconfiguration
我不知道这是否对您有帮助,但我只是想为以后的读者指出这一点。
我们所有人都通过分享我们所学的知识来学习
智能狗
答案 3 :(得分:1)
尝试在{
"schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json",
"hideSelection": "true",
"hideColumnHeader": "true",
"rowFormatter": {
"elmType": "a",
"attributes": {
"href": "[$FileRef]",
"target": "'_blank'"
},
"style": {
"float": "left"
},
"children": [
{
"elmType": "div",
"attributes": {
"class": "ms-bgColor-themeLighterAlt ms-bgColor-themePrimary--hover ms-fontColor-white--hover"
},
"style": {
"display": "flex",
"flex-wrap": "wrap",
"min-width": "180px",
"min-height": "150px",
"margin-right": "10px",
"margin-top": "10px",
"box-shadow": "2px 2px 4px darkgrey"
},
"children": [
{
"elmType": "div",
"style": {
"text-align": "center",
"margin": "auto"
},
"children": [
{
"elmType": "div",
"attributes": {
"class": "sp-row-title "
},
"txtContent": "[$Title]"
},
{
"elmType": "div",
"attributes": {
"iconName": "Test",
"class": "ms-fontSize-su"
}
}
]
}
]
}
]
}
}
的末尾使用self.session.remove(anchor: imageAnchor)
。 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
之后,将调用函数。这个答案并不完美,但是您可以使用它来使其更适合您。
我的解决方案:
在我的应用中,我确实喜欢这样。已创建func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor)
。在var lastImageAnchor: ARAnchor!
中添加了func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
。此功能之后:
self.lastImageAnchor = imageAnchor
答案 4 :(得分:0)
我从上面回答的内容和已经拥有的内容中吸取了一些指导,这对我有用:
//add a variable to store the last image detected
var lastImageAnchor: ARAnchor!
//at every frame, detect image, compare with the last image stored, and show the node corresponding with the image
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else { return }
if self.lastImageAnchor != nil && self.lastImageAnchor != imageAnchor {
self.sceneView.session.remove(anchor: self.lastImageAnchor)
}
//add whatever code you need to have your nodes appear
//lastly change the lastImageAnchor to the one what you just detected
self.lastImageAnchor = imageAnchor
}
希望这会有所帮助;)