IOS कैमरा प्रक्षेपण वापस


87

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

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

उदाहरण के लिए यदि मैं फ्रेम का निरीक्षण करता हूं:

*            *

    B
          C
  A
       D


*            *

अगर मैं क्यूआर कोड से 1 मी दूर था, तो उस पर केंद्रित था, और मान लिया कि क्यूआर कोड में 10 सेमी का एक पक्ष होता है।

*            *


    A0  B0

    D0  C0


*            *

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

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

मैं कैसे भरूंगा?

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 
}

==== संपादित करें ====

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

// 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
}

यहाँ उत्पादन है:

यहाँ छवि विवरण दर्ज करें

जहां ए, बी, सी, डी क्यूआर कोड कोनों होते हैं, जिस क्रम में उन्हें कार्यक्रम में भेजा जाता है।

पूर्वानुमानित उत्पत्ति तब होती है जब फ़ोन घूमता है, लेकिन यह कहाँ से स्थानांतरित किया जाना चाहिए। हैरानी की बात है, अगर मैं टिप्पणियों के मूल्यों को स्थानांतरित करता हूं, तो मैं इसे ठीक करने में सक्षम हूं:

  // (imageSize.height * (1 - $0.y), imageSize.width * $0.x)
  // replaced by:
  (imageSize.height * (1.35 - $0.y), imageSize.width * ($0.x - 0.2))

यहाँ छवि विवरण दर्ज करें

और अब भविष्यवाणी की गई जगह में मजबूती से रहता है। हालाँकि मुझे यह समझ में नहीं आया कि शिफ्ट वैल्यू कहाँ से आती है।

अंत में, मैंने 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)

जब मैं सीधे क्यूआर कोड को देखता हूं, तो अभिविन्यास ठीक है, लेकिन फिर यह कुछ इस तरह से बदल जाता है कि फोन रोटेशन से संबंधित प्रतीत होता है:यहाँ छवि विवरण दर्ज करें

मेरे पास बकाया प्रश्न हैं:

  • मैं रोटेशन को कैसे हल करूं?
  • स्थिति शिफ्ट मान कहां से आते हैं?
  • क्या सरल रिश्ता रोटेशन, अनुवाद, QRCornerCoordinatesInQRRef, टिप्पणियों, इंट्रिक्टिक्स को सत्यापित करता है? क्या यह O ~ K ^ -1 * (R_3x2 | T) Q है? क्योंकि यदि ऐसा है तो परिमाण के कुछ क्रम से बंद है।

यदि यह मददगार है, तो यहां कुछ संख्यात्मक मूल्य दिए गए हैं:

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, डी] के समानांतर होता है तो रोटेशन ठीक काम करता है। ), कोई फर्क नहीं पड़ता कि वास्तविक क्यूआर कोड अभिविन्यास क्या है:

यहाँ छवि विवरण दर्ज करें

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


अरे, आप क्यूआर कोड के माध्यम से उपकरणों की दूरी पाने की कोशिश कर रहे हैं? यदि हां, तो मेरा जवाब नीचे देखें।
एपिलॉन डांटलर

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

क्या आप कुछ कोड साझा कर पाएंगे?
मिशाल ज़बोरोव्स्की

जवाबों:


1

गणित (ट्रिग।):

समीकरण

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

चित्र


यकीन है, लेकिन मैं केवल मनाया कोण iऔर मूल दूरी जानता हूँl
गुइग

यह ठीक है, वहाँ के विपरीत खोजने के लिए एक रास्ता है i? यदि यह एक समकोण नहीं है , lतो kया तो खोजने के लिए अधिक गणित शामिल है या theta; i + k + theta = 180
एपिलॉन डांटलर

1
त्रिकोणमिति को काम करने के लिए मुझे दो दूरी और एक कोण या दो कोण और एक दूरी की आवश्यकता होती है। सिर्फ एक कोण और एक दूरी से सब कुछ पाने का कोई तरीका नहीं है
गुइग

क्या यह मदद करता है कि क्यूआर कोड वर्गाकार है, ताकि आप ऊर्ध्वाधर और क्षैतिज दोनों कोणों का निरीक्षण कर सकें?
बॉब वेकफील्ड

1

मुझे लगता है कि समस्या मैट्रिक्स में नहीं है। यह कोने में स्थित है। 2 डी छवियों को ट्रैक करने के लिए आपको एबीसीडी को काउंटर-क्लॉकवाइज (प्रारंभिक बिंदु काल्पनिक मूल में स्थित एक शीर्ष x:0, y:0) की आवश्यकता होती है। मुझे लगता है कि VNRectangleObservation क्लास पर Apple डॉक्यूमेंटेशन (छवि विश्लेषण अनुरोध द्वारा पता लगाए गए आयताकार क्षेत्रों के बारे में जानकारी) अस्पष्ट है। आपने अपने दस्तावेज़ उसी क्रम में रखे हैं जैसा कि आधिकारिक दस्तावेज़ में है:

var bottomLeft: CGPoint
var bottomRight: CGPoint
var topLeft: CGPoint
var topRight: CGPoint

लेकिन उन्हें उसी तरह रखा जाना चाहिए जैसे Zकि कार्टेशियन निर्देशांक प्रणाली में सकारात्मक रोटेशन दिशा ( अक्ष के बारे में ) होती है:

यहाँ छवि विवरण दर्ज करें

ARKit में विश्व समन्वित स्थान (साथ ही दृश्य और दृष्टि में) हमेशा एक right-handed convention(सकारात्मक Yअक्ष बिंदु ऊपर Zकी ओर, दर्शक की ओर सकारात्मक Xअक्ष बिंदु और दर्शक के दाईं ओर सकारात्मक अक्ष बिंदु ) का अनुसरण करता है , लेकिन आपके सत्र के कॉन्फ़िगरेशन के आधार पर उन्मुख होता है । कैमरा लोकल कोऑर्डिनेट स्पेस में काम करता है।

किसी भी अक्ष के बारे में रोटेशन की दिशा सकारात्मक (काउंटर-क्लॉकवाइज) और नकारात्मक (क्लॉकवाइज) है। ARKit और विजन में ट्रैकिंग के लिए यह महत्वपूर्ण रूप से महत्वपूर्ण है।

यहाँ छवि विवरण दर्ज करें

रोटेशन का क्रम भी समझ में आता है। ARKit, साथ ही SceneKit, घटकों के रिवर्स ऑर्डर में नोड की धुरी संपत्ति के सापेक्ष रोटेशन लागू करता है: पहले roll( Zअक्ष के बारे में ), फिर yaw( Yअक्ष के बारे में ), फिर pitch( Xअक्ष के बारे में )। तो रोटेशन क्रम है ZYX

इसके अलावा, Nukepedia पर मैट्रिक्स ऑपरेशन के बारे में उपयोगी पोस्ट है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.