From 288a9bf2160c91b47171579a16032271275a89c6 Mon Sep 17 00:00:00 2001 From: Ufuk Kaan Tugay <ufuk.tugay@ruhr-uni-bochum.de> Date: Wed, 15 Sep 2021 11:17:04 +0000 Subject: [PATCH] Replace ViewController.swift --- .../ViewController.swift | 304 +++++++++++------- 1 file changed, 189 insertions(+), 115 deletions(-) diff --git a/Objekterkennung in AR mit ARKit und CoreML/ViewController.swift b/Objekterkennung in AR mit ARKit und CoreML/ViewController.swift index 5c69123..4964128 100644 --- a/Objekterkennung in AR mit ARKit und CoreML/ViewController.swift +++ b/Objekterkennung in AR mit ARKit und CoreML/ViewController.swift @@ -12,15 +12,61 @@ import Vision class ViewController: UIViewController, ARSCNViewDelegate { - @IBOutlet var sceneView: ARSCNView! + @IBOutlet var sceneView: ARSCNView! + var detectionMode = "click" - var node_array: [SCNNode] = [] var scene_bounds: (CGFloat,CGFloat) = (0,0) var object_detector = ObjectDetection() var ar_functions = View() - let label = UILabel(frame: CGRect(x: 5, y: 20, width: 400, height: 30)) + var start_position_array: [simd_float4x4] = [] + var classification_object = "" + var bounding_box_object = SCNNode() + var text_object = SCNNode() + var text_node: SCNNode { + return text_object + } + var bounding_box_node: SCNNode { + return bounding_box_object + } + + var test_node: SCNNode{ + switch classification_object { + case "90T_Tyre": + return ar_functions.getTire90T() + case "beam_0412-140": + return ar_functions.getBeam0412_140() + case "beam_0412-92": + return ar_functions.getBeam0412_092() + case "beam_0824-112": + return ar_functions.getBeam0824_112() + case "beam_0824-16": + return ar_functions.getBeam0824_016() + case "beam_0824-80": + return ar_functions.getBeam0824_080() + case "beam_0824-96": + return ar_functions.getBeam0824_096() + case "bracket_3x3": + return ar_functions.getBracket3x3() + case "plate_3x6": + return ar_functions.getPlate3x6() + case "unnamed_nut": + return ar_functions.getBrassStud() + case "unnamed_angle": + return ar_functions.getPlate45() + default: + let no_model_node = SCNNode() + no_model_node.name = "no_model" + return no_model_node + + } + + } + + var start_position: simd_float4x4{ + return sceneView.session.currentFrame!.camera.transform + } func createLabel(){ if detectionMode == "loop"{ @@ -33,26 +79,7 @@ class ViewController: UIViewController, ARSCNViewDelegate { self.view.addSubview(label) } - - func createButtons(){ - let mode_button = UIButton() - mode_button.frame = CGRect(x:20, y: 700, width: 200, height: 100) - mode_button.backgroundColor = .white - mode_button.setTitle("Change Detection Mode", for: .normal) - mode_button.setTitleColor( .black, for: .normal) - mode_button.addTarget(self, action: #selector(changeDetectionMode), for: .touchUpInside) - - - let detect_button = UIButton() - detect_button.frame = CGRect(x:240, y: 700, width: 200, height: 100) - detect_button.backgroundColor = .white - detect_button.setTitle("Perform Detection", for: .normal) - detect_button.setTitleColor( .black, for: .normal) - detect_button.addTarget(self, action: #selector(detect), for: .touchUpInside) - - self.view.addSubview(mode_button) - self.view.addSubview(detect_button) - } + @objc func changeDetectionMode(){ if detectionMode == "loop" { @@ -73,13 +100,13 @@ class ViewController: UIViewController, ARSCNViewDelegate { } - + override func viewDidLoad() { super.viewDidLoad() let configuration = ARWorldTrackingConfiguration() - configuration.planeDetection = .horizontal + configuration.planeDetection = [.horizontal, .vertical] sceneView.scene = SCNScene() sceneView.session.run(configuration) @@ -90,122 +117,141 @@ class ViewController: UIViewController, ARSCNViewDelegate { createButtons() createLabel() } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - } - + + func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { + if anchor.name == "model" { + node.addChildNode(test_node) + + } + else if anchor.name == "bb"{ + bounding_box_node.position = node.position + node.addChildNode(bounding_box_node) + } + else if anchor.name == "text"{ + text_node.position = node.position + node.addChildNode(text_node) + + } + } func performDetection() { + guard let frame = sceneView.session.currentFrame else { return } - + if frame.anchors.isEmpty { print("anchors are empty") return - } - let start_time = Date() + } + + sceneView.scene = SCNScene() + object_detector.detectObjects(on: sceneView.session.currentFrame!.capturedImage) - let end_timee = Date() - print(end_timee.timeIntervalSince(start_time)) - if let new_detection = self.object_detector.detection_object_array.first { - if new_detection.confidence > 0.7 { - sceneView.scene = SCNScene() - } - - } for observations in self.object_detector.detection_object_array{ - - if observations.confidence > 0.7 { + if observations.confidence > 0.5 { for observations in self.object_detector.detection_object_array{ - //print(observations) - //print(observations.boundingBox.midX) - //print(observations.boundingBox.midY) DispatchQueue.main.async { self.scene_bounds = self.sceneBounds() } + classification_object = observations.classification + + if test_node.name == "no_model" { + continue + } + var translation = matrix_identity_float4x4 + translation.columns.3.z = test_node.position.z + translation.columns.3.x = test_node.position.x + translation.columns.3.y = test_node.position.y + let transform = simd_mul(start_position_array[0], translation) + let model_anchor = ARAnchor(name: "model", transform: transform) + + sceneView.session.add(anchor: model_anchor) - print(observations.classification) let detectionLocation = VNImageRectForNormalizedRect( observations.boundingBox, Int(self.scene_bounds.0), Int(self.scene_bounds.1)) - - //self.objectDetector.detection_object_array.removeAll() - drawModel(observations.classification) - //let bb2d_view = ar_functions.drawboundingbox2d(detectionLocation: detectionLocation) - //bb2d_view.removeFromSuperview() - //self.view.addSubview(bb2d_view) - - ar_functions.drawBoundingBox3D(detectionLocation: detectionLocation, vision_bb: observations.boundingBox, sceneView: sceneView) - sceneView.scene.rootNode.addChildNode(ar_functions.draw_text_node(detectionLocation: detectionLocation, classification: observations.classification, sceneView: sceneView )) - let end_time = Date() - print(end_time.timeIntervalSince(start_time)) - - } - -// sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in -// node.removeFromParentNode() } + let bb_node = ar_functions.drawBoundingBox3D(detectionLocation: detectionLocation, sceneView: sceneView) + bounding_box_object = bb_node + let anchor_bb = ARAnchor(name: "bb", transform: bb_node.simdTransform) + sceneView.session.add(anchor: anchor_bb) + + let drawn_text_node = ar_functions.draw_text_node(detectionLocation: detectionLocation, classification: observations.classification, sceneView: sceneView) + text_object = drawn_text_node + let anchor_text = ARAnchor(name: "text", transform: drawn_text_node.simdTransform) + sceneView.session.add(anchor: anchor_text) + } } } self.object_detector.detection_object_array.removeAll() - } -// func removeNodes(){ -// self.sceneView.scene.rootNode.enumerateChildNodes { (existingNode, _) in -// node_array.append(existingNode) -// existingNode.removeFromParentNode() -// node_array.removeFirst() -// } -// } - func drawModel(_ object_type: String){ - switch object_type { - case ("plate_3x6"): - sceneView.scene.rootNode.addChildNode(ar_functions.getPlate3x6()) - - case ("90T_Tyre"): - sceneView.scene.rootNode.addChildNode(ar_functions.getTire90T()) - - case ("beam_0412-140"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0412_140()) - case ("beam_0412-92"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0412_092()) - - case ("beam_0824-112"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_096()) - - case ("beam_0824-16"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_016()) - case ("beam_0824-80"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_080()) - case ("beam_0824-96"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_096()) - case ("bracket_3x3"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBracket3x3()) - case ("unnamed_angle"): - sceneView.scene.rootNode.addChildNode(ar_functions.getPlate45()) - case ("unnamed_nut"): - sceneView.scene.rootNode.addChildNode(ar_functions.getBrassStud()) - default: - print("Kein Modell für diese Detection vorhanden") - } +// func drawModel(_ object_type: String){ +// switch object_type { +// case ("plate_3x6"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getPlate3x6()) +// // case ("90T_Tyre"): +// //sceneView.scene.rootNode.addChildNode(ar_functions.getTire90T()) +// +// case ("beam_0412-140"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0412_140()) +// +// case ("beam_0412-92"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0412_092()) +// +// case ("beam_0824-112"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_096()) +// +// case ("beam_0824-16"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_016()) +// case ("beam_0824-80"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_080()) +// case ("beam_0824-96"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBeam0824_096()) +// case ("bracket_3x3"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBracket3x3()) +// case ("unnamed_angle"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getPlate45()) +// case ("unnamed_nut"): +// sceneView.scene.rootNode.addChildNode(ar_functions.getBrassStud()) +// default: +// print("Kein Modell für diese Detection vorhanden") +// } +// } + + func createButtons(){ + let mode_button = UIButton() + mode_button.frame = CGRect(x:20, y: 680, width: 200, height: 100) + mode_button.backgroundColor = .white + mode_button.setTitle("Change Detection Mode", for: .normal) + mode_button.setTitleColor( .black, for: .normal) + mode_button.addTarget(self, action: #selector(changeDetectionMode), for: .touchUpInside) - - } - - + let detect_button = UIButton() + detect_button.frame = CGRect(x:240, y: 680, width: 200, height: 100) + detect_button.backgroundColor = .white + detect_button.setTitle("Perform Detection", for: .normal) + detect_button.setTitleColor( .black, for: .normal) + detect_button.addTarget(self, action: #selector(detect), for: .touchUpInside) + + let position_button = UIButton() + position_button.frame = CGRect(x: 460,y: 680, width: 200, height: 100) + position_button.backgroundColor = .white + position_button.setTitle("Select Position", for: .normal) + position_button.setTitleColor(.black, for: .normal) + position_button.addTarget(self, action: #selector(generateStartPosition), for: .touchUpInside) + position_button.tag = 192 + self.view.addSubview(mode_button) + self.view.addSubview(detect_button) + self.view.addSubview(position_button) + } func sceneBounds() -> (CGFloat, CGFloat) { return (self.sceneView.bounds.width,self.sceneView.bounds.height) @@ -215,20 +261,48 @@ class ViewController: UIViewController, ARSCNViewDelegate { if detectionMode == "loop" { let dispatch_queue = DispatchQueue.main scene_bounds = sceneBounds() - dispatch_queue.asyncAfter(deadline: .now() + 1, execute: DispatchWorkItem{self.performDetection();self.detectionLoop()}) + dispatch_queue.asyncAfter(deadline: .now() + 0.2 , execute: DispatchWorkItem{self.performDetection();self.detectionLoop()}) } - else if detectionMode == "click" { performDetection() } - } + + @objc func generateStartPosition(){ + while true{ + if let start_pos = sceneView.session.currentFrame { + start_position_array.append(start_pos.camera.transform) + print("start position bestimmt") + self.view.subviews.forEach ({ + if $0 is UIButton { + if $0.tag == 192{ + $0.removeFromSuperview() + } + } + }) - + + break + } + } + } + func session(_ session: ARSession) { - detectionLoop() } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + } + } -- GitLab