2017-06-16 20 views
63

वापस लेता है मैं अंतरिक्ष में एक क्यूआर कोड से संबंधित अपनी डिवाइस स्थिति का अनुमान लगाने की कोशिश कर रहा हूं। मैं आईओएस 11 में पेश किए गए एआरकिट और विजन फ्रेमवर्क का उपयोग कर रहा हूं, लेकिन इस प्रश्न का उत्तर शायद उन पर निर्भर नहीं है।आईओएस कैमरा प्रक्षेपण

विजन ढांचे के साथ, मैं आयताकार प्राप्त करने में सक्षम हूं जो कैमरा फ्रेम में एक क्यूआर कोड को बाध्य करता है। मैं इस आयत से मानक अनुवाद से क्यूआर कोड को बदलने के लिए आवश्यक डिवाइस अनुवाद और रोटेशन से मिलान करना चाहता हूं।

*   * 

    B 
      C 
    A 
     D 


*   * 

जबकि अगर मैं 1m QR कोड, उस पर केंद्रित है, और QR कोड संभालने से दूर है था 10cm के एक पक्ष मैं देखना चाहते हैं:

उदाहरण के लिए अगर मैं फ्रेम का निरीक्षण

*   * 


    A0 B0 

    D0 C0 


*   * 

उन दो फ्रेमों के बीच मेरा डिवाइस परिवर्तन क्या रहा है? मैं समझता हूं कि एक सटीक परिणाम संभव नहीं हो सकता है, क्योंकि शायद देखा गया क्यूआर कोड थोड़ा गैर प्लानर है और हम किसी चीज पर एक एफ़िन ट्रांसफॉर्म का अनुमान लगाने की कोशिश कर रहे हैं जो पूरी तरह से नहीं है।

मुझे लगता है कि sceneView.pointOfView?.camera?.projectionTransformsceneView.pointOfView?.camera?.projectionTransform?.camera.projectionMatrix से अधिक सहायक है क्योंकि बाद में पहले से ही एआरकेट से अनुमानित रूप से परिवर्तित खाता लेता है कि मुझे इस समस्या के लिए कोई दिलचस्पी नहीं है।

मैं

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 प्रक्षेपण और परिप्रेक्ष्य solver, solvePnP का उपयोग कर आकलन मुद्रा के लिए समाप्त हो गया कैसे को भरना था यह मुझे एक रोटेशन और अनुवाद देता है जो क्यूआर कोड रेफरेंसियल में कैमरा पॉज़ का प्रतिनिधित्व करना चाहिए। लेकिन जब उन मूल्यों का उपयोग करने और उलटा परिवर्तन, जहां 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

जहां ए, बी, सी, डी क्रम में 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

बकाया सवाल मैं है कर रहे हैं:

  • मैं कैसे रोटेशन का समाधान करते हैं?
  • स्थिति शिफ्ट मूल्य कहां से आते हैं?
  • घूर्णन, अनुवाद, QRCornerCoordinatesInQRRef, अवलोकन, intrisics क्या सरल संबंध करते हैं? क्या यह ओ ~ के^-1 * (आर_3x2 | टी) क्यू है? क्योंकि यदि ऐसा है तो यह परिमाण के कुछ क्रम से बंद है।

अगर वह उपयोगी है, यहाँ कुछ संख्यात्मक मान हैं:

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 

==== EDIT2 ====

मैंने देखा है कि रोटेशन ठीक काम करता है जब फोन रहता है क्षैतिज रूप से क्यूआर कोड के समानांतर (यानी रोटेशन मैट्रिक्स [[ए, 0, बी], [0, 1, 0], [सी, 0, डी]]), कोई फर्क नहीं पड़ता कि वास्तविक क्यूआर कोड अभिविन्यास क्या है:

enter image description here

अन्य रोटेशन काम नहीं करते हैं।

+0

अरे, क्या आप क्यूआर कोड के माध्यम से डिवाइस दूरी प्राप्त करने की कोशिश कर रहे हैं? यदि ऐसा है, तो नीचे मेरा जवाब देखें। –

+0

संपादित करें: आपके उत्कृष्ट प्रश्नों के लिए, 1. ऐसा लगता है कि बस एक अनावश्यक मूल्य डाला गया है। संभावित रूप से मैपिंग विधि में कहा जाता है, या मंडलियों से संबंधित कुछ और (जैसे ड्रॉक्रिकल (... रोटेशन) ' 2. चश्मा पढ़ने के लिए समय नहीं था 3. 2 –

+0

के समान कुछ कोड साझा करने में सक्षम हो? – mientus

उत्तर

0

मठ (ट्रिग।):

Equation

नोट: नीचे l (QR कोड लंबाई), बाएं कोने k है, और शीर्ष कोण i है (कैमरा)

Picture

+0

निश्चित है, लेकिन मुझे केवल देखा गया कोण 'i' और मूल दूरी 'l' – Guig

+0

पता है, ठीक है, क्या' i' के विपरीत खोजने का कोई तरीका है? यदि यह 'एल' के लिए सही कोण नहीं है तो 'k' या' theta' खोजने के लिए और अधिक गणित शामिल है; 'i + k + theta = 180'। –

+1

त्रिकोणमिति काम करने के लिए मुझे या तो दो दूरी और एक कोण, या दो कोण और एक दूरी की आवश्यकता है। केवल एक कोण से एक चीज प्राप्त करने का कोई तरीका नहीं है और एक दूरी – Guig

संबंधित मुद्दे