gpt4 book ai didi

ios - AR 引用图像平面在 iOS Swift 中的位置不正确?

转载 作者:搜寻专家 更新时间:2023-10-31 22:01:12 25 4
gpt4 key购买 nike

我正在使用 ar 引用图像处理名片资料信息。当引用检测到它会显示公司首席执行官的详细信息、地址、照片和团队成员信息等。最初检测到的图像平面将使用 向右移动运行操作 氨基。

我的问题是检测到 ar refrence,平面位置稳定并且它在这里和那里移动。如何使用 ar 引用图像拟合平面位置。

这是我的结果截图:[![在此处输入图像描述][1]][1]

这是我使用的代码:

var weboverlayview: CALayer?
var loadWeb: UIWebView?
override func viewDidLoad() {
super.viewDidLoad()

// Set the view's delegate
sceneView.delegate = self

// Show statistics such as fps and timing information
sceneView.showsStatistics = true
sceneView.autoenablesDefaultLighting = true
let ARScene = SCNScene()
sceneView.scene = ARScene

}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = [.vertical, .horizontal]
configuration.detectionImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil)
// Run the view's session
sceneView.session.run(configuration)
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

// Pause the view's session
sceneView.session.pause()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}


func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {

let anchorNode = SCNNode()
anchorNode.name = "anchor"
sceneView.scene.rootNode.addChildNode(anchorNode)
return anchorNode

}

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

var labelNode:SCNNode?
var companyLabelNode: SCNNode?
var addressLabelNode: SCNNode?
var webaddressLabelNode: SCNNode?
var maillabelNode: SCNNode?
var mobileLabelNode:SCNNode?
var teamLabelNode:SCNNode?


guard let imageAnchor = anchor as? ARImageAnchor else {return}
if let imageName = imageAnchor.referenceImage.name {

print(imageName)



if imageName == "card"{



let plane = SCNPlane(width: 20,height: 24)
plane.firstMaterial?.diffuse.contents = UIColor.black.withAlphaComponent(0.75)
plane.cornerRadius = 0.25

let planeNodee = SCNNode(geometry: plane)
planeNodee.eulerAngles.x = -.pi / 2
planeNodee.runAction(SCNAction.moveBy(x: -5, y: 0, z: 19, duration: 0.75))

labelNode = self.addLabel(text: "Gowdhaman Kandasamy \nFounder and CEO", anchor: imageAnchor)
labelNode?.runAction(SCNAction.moveBy(x: -1.3, y: 1, z: 16.8, duration: 0.75))



companyLabelNode = self.addLabel(text: "CZ Smart Mobility", anchor: imageAnchor)
companyLabelNode?.runAction(SCNAction.moveBy(x: 1.5, y: 1, z: 22, duration: 0.75))

addressLabelNode = self.addAddressLabel(text: "Official Address:\n\n1st floor, TBI Office,\nDr.col JEPPIAR Research Park,\nResearch and development center,\nSathyabama University,\nChennai-600119\nTamil nadu, India.", anchor: imageAnchor)
addressLabelNode?.runAction(SCNAction.moveBy(x: -4.8, y: 1, z: 16.8, duration: 0.75))



let userImagePlane = SCNPlane(width: 3.5, height: 3.5)
userImagePlane.firstMaterial?.diffuse.contents = UIImage(named: "gow")
userImagePlane.cornerRadius = 0.25
let userPlaneNode = SCNNode(geometry: userImagePlane)
userPlaneNode.eulerAngles.x = -.pi/2
userPlaneNode.runAction(SCNAction.moveBy(x: -1, y: 1, z: 9.5, duration: 0.75))


let webImagePlane = SCNPlane(width: 1, height: 1)
webImagePlane.firstMaterial?.diffuse.contents = UIImage(named: "web")

webImagePlane.cornerRadius = 0.25
let webPlanenode = SCNNode(geometry: webImagePlane)
webPlanenode.eulerAngles.x = -.pi/2
webPlanenode.runAction(SCNAction.moveBy(x: -7, y: 1, z: 12.5, duration: 0.75))
webaddressLabelNode = addAddressLabel(text: "www.czsm.co.in", anchor: imageAnchor)
webaddressLabelNode?.runAction(SCNAction.moveBy(x: -8.7, y: 1, z: 18.2, duration: 0.75))

let mailImagePlane = SCNPlane(width: 1, height: 1)
mailImagePlane.firstMaterial?.diffuse.contents = UIImage(named: "mail")

mailImagePlane.cornerRadius = 0.25
let mailPlanenode = SCNNode(geometry: mailImagePlane)
mailPlanenode.eulerAngles.x = -.pi/2
mailPlanenode.runAction(SCNAction.moveBy(x: -7, y: 1, z: 17.5, duration: 0.75))
maillabelNode = addAddressLabel(text: "gowdhaman@czsm.co.in", anchor: imageAnchor)
maillabelNode?.runAction(SCNAction.moveBy(x: -8.7, y: 1, z: 23.2, duration: 0.75))

let mobileImagePlane = SCNPlane(width: 1, height: 1)
mobileImagePlane.firstMaterial?.diffuse.contents = UIImage(named: "mobile")

mobileImagePlane.cornerRadius = 0.25
let mobilePlanenode = SCNNode(geometry: mobileImagePlane)
mobilePlanenode.eulerAngles.x = -.pi/2
mobilePlanenode.runAction(SCNAction.moveBy(x: -7, y: 1, z: 23.9, duration: 0.75))
mobileLabelNode = addAddressLabel(text: "+919941123110", anchor: imageAnchor)
mobileLabelNode?.runAction(SCNAction.moveBy(x: -8.7, y: 1, z: 29.7, duration: 0.75))


/************Team members*************/

teamLabelNode = self.addLabel(text: "Team Members", anchor: imageAnchor)
teamLabelNode?.runAction(SCNAction.moveBy(x: -9.8, y: 1, z: 22, duration: 0.75))


let sivaImagePlane = SCNPlane(width: 2.7, height: 2.7)
sivaImagePlane.firstMaterial?.diffuse.contents = UIImage(named: "pic2")

sivaImagePlane.cornerRadius = 0.25
let sivaPlanenode = SCNNode(geometry: sivaImagePlane)
sivaPlanenode.eulerAngles.x = -.pi/2
sivaPlanenode.runAction(SCNAction.moveBy(x: -11, y: 1, z: 9.5, duration: 0.75))


let parameshImagePlane = SCNPlane(width: 2.7, height: 2.7)
parameshImagePlane.firstMaterial?.diffuse.contents = UIImage(named: "pic4")

parameshImagePlane.cornerRadius = 0.25
let parameshPlanenode = SCNNode(geometry: parameshImagePlane)
parameshPlanenode.eulerAngles.x = -.pi/2
parameshPlanenode.runAction(SCNAction.moveBy(x: -11, y: 1, z: 9.5, duration: 0.75))






node.addChildNode(planeNodee)
node.addChildNode(labelNode!)
node.addChildNode(companyLabelNode!)
node.addChildNode(userPlaneNode)
node.addChildNode(addressLabelNode!)
node.addChildNode(webPlanenode)
node.addChildNode(webaddressLabelNode!)
node.addChildNode(mailPlanenode)
node.addChildNode(maillabelNode!)
node.addChildNode(mobilePlanenode)
node.addChildNode(mobileLabelNode!)
node.addChildNode(teamLabelNode!)

node.addChildNode(sivaPlanenode)
node.addChildNode(parameshPlanenode)


// node.addChildNode(czwebPlaneNode)
self.sceneView.scene.rootNode.addChildNode(node)



}

}


}
func webButton() {






}


func addLabel(text: String, anchor: ARImageAnchor) -> SCNNode {
let plane = SCNPlane(width: 10,
height: 4)

let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = (-.pi)/2
planeNode.eulerAngles.y = (-.pi)/2
// planeNode.eulerAngles.z = (-.pi)/2



let skScene = SKScene(size: CGSize(width: 400, height: 100))

skScene.backgroundColor = UIColor.clear

let substrings: [String] = text.components(separatedBy: "\n")
for aSubstring in substrings {
let lbl = SKLabelNode(text: aSubstring)
lbl.fontSize = 18
lbl.numberOfLines = 1
lbl.fontColor = UIColor.white
lbl.fontName = "Avenir-medium"
let y = CGFloat(substrings.index(of: aSubstring)! + 1) * lbl.fontSize
print("yname::::\(y)")
lbl.position = CGPoint(x: 0, y: y)
lbl.horizontalAlignmentMode = .left
lbl.yScale *= -1
skScene.addChild(lbl)



}




let material = SCNMaterial()
material.isDoubleSided = false
material.diffuse.contents = skScene
plane.materials = [material]

return planeNode
}

func addCompanyLabel(text: String, anchor: ARImageAnchor) -> SCNNode {
let plane1 = SCNPlane(width: 10,
height: 4)

let planeNode1 = SCNNode(geometry: plane1)
planeNode1.eulerAngles.x = (-.pi)/2
planeNode1.eulerAngles.y = (-.pi)/2
// planeNode.eulerAngles.z = (-.pi)/2



let skScene1 = SKScene(size: CGSize(width: 400, height: 100))

skScene1.backgroundColor = UIColor.clear

let substrings: [String] = text.components(separatedBy: "\n")
for aSubstring in substrings {
let lbl1 = SKLabelNode(text: aSubstring)
lbl1.fontSize = 20
lbl1.numberOfLines = 1
lbl1.fontColor = UIColor.white
lbl1.fontName = "Avenir-medium"
let y = CGFloat(substrings.index(of: aSubstring)! + 1) * lbl1.fontSize
print("ycompanname::::\(y)")
lbl1.position = CGPoint(x: 0, y: y)
lbl1.horizontalAlignmentMode = .left
lbl1.yScale *= -1
skScene1.addChild(lbl1)



}

let material = SCNMaterial()
material.isDoubleSided = false
material.diffuse.contents = skScene1
plane1.materials = [material]

return planeNode1
}

func addAddressLabel(text: String, anchor: ARImageAnchor) -> SCNNode {
let plane = SCNPlane(width: 10,
height: 4)

let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = (-.pi)/2
planeNode.eulerAngles.y = (-.pi)/2
// planeNode.eulerAngles.z = (-.pi)/2



let skScene = SKScene(size: CGSize(width: 500, height: 200))

skScene.backgroundColor = UIColor.clear

let substrings: [String] = text.components(separatedBy: "\n")
for aSubstring in substrings {
let lbl = SKLabelNode(text: aSubstring)
lbl.fontSize = 20
// lbl.numberOfLines = 1
lbl.fontColor = UIColor.white
lbl.fontName = "Avenir-medium"
let y = CGFloat(substrings.index(of: aSubstring)! + 1) * lbl.fontSize
print("yaddress::::\(y)")
lbl.position = CGPoint(x: 0, y: y)
lbl.horizontalAlignmentMode = .left
lbl.yScale *= -1
skScene.addChild(lbl)



}

let material = SCNMaterial()
material.isDoubleSided = false
material.diffuse.contents = skScene
plane.materials = [material]

return planeNode
}




func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {


// guard let planeAnchor = anchor as? ARPlaneAnchor else {return}
// let planeGeometry = planeAnchor.geometry
// guard let device = MTLCreateSystemDefaultDevice() else {return}
// let plane = ARSCNPlaneGeometry(device: device)
// plane?.update(from: planeGeometry)
// node.geometry = plane
// node.geometry?.firstMaterial?.diffuse.contents = UIColor.black
// node.geometry?.firstMaterial?.transparency = 1
// node.geometry?.firstMaterial?.fillMode = SCNFillMode.lines

}



}

像这样 ar 引用平面这样的异常(exception)结果将适合卡 https://www.facebook.com/oscarfalmer/videos/10156651667309345/

最佳答案

首先需要考虑的是是否要使用ARWorldTrackingConfigurationARImageTrackingConfiguration ( IOS12 )。

如果您使用 ARImageTrackingConfiguration ,您不能使用 PlaneDetection,因为这是仅图像跟踪配置:

which lets you anchor virtual content to known images only when those images are in view of the camera. World tracking with image detection lets you use known images to add virtual content to the 3D world, and continues to track the position of that content in world space even after the image is no longer in view.



如果您希望您的内容始终 anchor 定在图像上(当您看到相机时),这将是您最好的选择,因为:

it tracks their movement with six degrees of freedom (6DOF): specifically, the three rotation axes (roll, pitch, and yaw), and three translation axes (movement in x, y, and z).



另一方面,如果你想检测 ARPlaneAnchors ,以及 ARImageAnchors ,但不必担心与您的 ARImageAnchor 相关的任何内容不会经常跟踪,那么你应该使用 ARWorldTrackingConfiguration .

正如@Trinca 还说的,您需要确保为图像提供的测量值尽可能准确,如 ARKit使用这些返回 physicalSizephysicalWidth可以让您的虚拟内容更准确地放置(例如,如果您指定的尺寸大于现实生活中图像的实际尺寸,您将无法准确对齐您的虚拟内容)。

enter image description here

创建名片或任何 imageTarget 时,我们必须确保在 ARReferenceImage Settings 中准确设置我们的尺寸。盒子:

enter image description here

然后我们可以检查我们的 imageTarget 是否像这样检测到:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

//1. Check We Have Detected An ARImageAnchor & Check It's The One We Want
guard let validImageAnchor = anchor as? ARImageAnchor,
let targetName = validImageAnchor.referenceImage.name, targetName == "TargetCard" else { return}


//2. Check To See The Detected Size Of Our Business Card (Should By 5cm*3cm)
let businessCardWidth = validImageAnchor.referenceImage.physicalSize.width
let businessCardHeight = validImageAnchor.referenceImage.physicalSize.height

print(
"""
We Have Detected Business Card With Name \(targetName)
\(targetName)'s Width Is \(businessCardWidth)
\(targetName)'s Height Is \(businessCardHeight)
""")

}

检查我们检测到的大小是否准确后,我们可以放置任何我们喜欢的内容。

与以编程方式完成所有工作相比,实现您正在寻找的结果的更简单方法是创建 SCNScene .

更新:

正如您要求的示例项目,我为每个人创建了一个完整的示例,可以在此处下载: ARKit Business Card

无需经过每个 Class详细我将为您提供基本的细节。

我们将使用 SCNScene作为一个可重用的模板,它包含的范围是 SCNNode它们用作按钮,按下它们时可以执行不同的操作。

基本模板如下所示:

enter image description here

BusinessCard 节点使用 A BusinessCardData Struct 初始化,如下所示:
typealias SocialLinkData = (link: String, type: SocialLink)

/// The Information For The Business Card Node & Contact Details
struct BusinessCardData{

var firstName: String
var surname: String
var position: String
var company: String
var address: BusinessAddress
var website: SocialLinkData
var phoneNumber: String
var email: String
var stackOverflowAccount: SocialLinkData
var githubAccount: SocialLinkData

}

/// The Associates Business Address
struct BusinessAddress{

var street: String
var city: String
var state: String
var postalCode: String
var coordinates: (latittude: Double, longtitude: Double)
}

/// The Type Of Social Link
///
/// - Website: Business Website
/// - StackOverFlow: StackOverFlow Account
/// - GitHub: Github Account
enum SocialLink: String{

case Website
case StackOverFlow
case GitHub
}

由此提供的所有数据都映射到每个 SCNNode在模板中,并有助于执行必要的功能。

通过使用 struct我们可以简单地创建多个交互式名片,例如:
//--------------------------
//MARK: - ARSessionDelegate
//--------------------------

extension ViewController: ARSCNViewDelegate{

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

//1. Check We Have A Valid Image Anchor
guard let imageAnchor = anchor as? ARImageAnchor else { return }

//2. Get The Detected Reference Image
let referenceImage = imageAnchor.referenceImage

//3. Load Our Business Card
if let matchedBusinessCardName = referenceImage.name, matchedBusinessCardName == "BlackMirrorz"{

//4. Create Our Business Card
let businessCardData = BusinessCardData(firstName: "Josh",
surname: "Robbins",
position: "Software Engineer",
company: "BlackMirrorz",
address: BusinessAddress(street: "1 Infinite Loop",
city: "Cupertino",
state: "CA",
postalCode: "95015",
coordinates: (latittude: 37.3349, longtitude: -122.0090201)),
website: SocialLinkData(link: "https://www.blackmirrorz.tech", type: .Website),
phoneNumber: "+821076337633",
email: "josh.robbins@blackmirroz.tech",
stackOverflowAccount: SocialLinkData(link: "https://stackoverflow.com/users/8816868/josh-robbins", type: .StackOverFlow),
githubAccount: SocialLinkData(link: "https://github.com/BlackMirrorz", type: .GitHub))

//5. Assign It To The Business Card Node
let businessCard = BusinessCard(data: businessCardData, cardType: .noProfileImage)
businessCardPlaced = true
node.addChildNode(businessCard)

}
}
}

由于设计已经布局,我们不需要做任何复杂的计算。一切都为我们做了!

用户的交互使用以下图标完成:
enter image description here
  • StackOverFlow Button展示幻灯片 WKWebView显示用户 StackOverFlow帐户。
  • GitHub Button展示幻灯片 WKWebView显示用户 GitHub帐户。
  • Internet Button展示幻灯片 WKWebView显示用户的网站。
  • Phone Button允许用户调用商务电话号码。
  • SMS Button赠送 MFMessageComposeViewController允许用户向企业发送短信。
  • Email Button赠送 MFMailComposeViewController允许用户通过电子邮件发送业务。
  • Contact Button创建一个 CNMutableContact并将业务保存为用户设备上的新联系人。
  • Location Button展示幻灯片 MKMapView显示用户的企业位置。

  • 由于渲染了 WKWebView作为 SCNMaterial ,我不得不寻找其他方法来让内容完全互动。

    因此,我使用了神话般的存储库 SideMenu来自 Jonkykong可在此处获得:
    SideMenu

    这让用户仍然可以体验 ARKit同时允许几乎分屏效果:

    enter image description here

    一如既往,希望它能帮助你和其他对学习 ARKit 感兴趣的人......

    关于ios - AR 引用图像平面在 iOS Swift 中的位置不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51239089/

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