iOS kamera projeksiyonunu geri döndürür


87

Uzayda bir QR koduyla ilgili cihaz konumumu tahmin etmeye çalışıyorum. Her ikisi de iOS11'de sunulan ARKit ve Vision çerçevesini kullanıyorum, ancak bu sorunun cevabı muhtemelen onlara bağlı değil.

Vision çerçevesi ile kamera çerçevesindeki bir QR kodunu sınırlayan dikdörtgeni elde edebiliyorum. Bu dikdörtgeni, QR kodunu standart bir konumdan dönüştürmek için gereken cihaz çevirisiyle ve döndürmesiyle eşleştirmek istiyorum.

Örneğin, çerçeveyi gözlemlersem:

*            *

    B
          C
  A
       D


*            *

QR kodundan 1 m uzakta olsaydım, merkezde olsaydım ve QR kodunun 10 cm'lik bir kenarına sahip olduğunu varsayarsam şunu görürdüm:

*            *


    A0  B0

    D0  C0


*            *

bu iki çerçeve arasındaki cihaz dönüşümüm ne oldu? Kesin bir sonucun mümkün olmayabileceğini anlıyorum, çünkü gözlemlenen QR kodu biraz düzlemsel değildir ve mükemmel olmayan bir şey üzerinde afin bir dönüşümü tahmin etmeye çalışıyoruz.

Sanırım sceneView.pointOfView?.camera?.projectionTransform, daha sceneView.pointOfView?.camera?.projectionTransform?.camera.projectionMatrixsonra bu problem için ilgilenmediğim ARKit'ten çıkarılan dönüşümü hesaba kattığı için daha yararlıdır.

Nasıl doldururum

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 
}

==== Düzenle ====

Bir çok şeyi denedikten sonra, openCV projeksiyonu ve perspektif çözücüyü kullanarak kamera poz tahminine gittim, solvePnPBu bana QR kod referansındaki kamera pozunu temsil etmesi gereken bir dönüş ve çeviri sağlıyor. Ancak bu değerleri kullanırken ve ters dönüşüme karşılık gelen nesneleri yerleştirirken, QR kodunun kamera alanında olması gerektiği yerde, yanlış kaydırılmış değerler alıyorum ve döndürmenin çalışmasını sağlayamıyorum:

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

İşte çıktı:

görüntü açıklamasını buraya girin

A, B, C, D, programa geçirildikleri sıraya göre QR kodu köşeleridir.

Tahmin edilen kaynak, telefon döndüğünde yerinde kalır, ancak olması gerektiği yerden kaydırılır. Şaşırtıcı bir şekilde, gözlem değerlerini değiştirirsem, bunu düzeltebilirim:

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

görüntü açıklamasını buraya girin

ve şimdi tahmin edilen kaynak sağlam bir şekilde yerinde kalıyor. Ancak vardiya değerlerinin nereden geldiğini anlamıyorum.

Son olarak, QR kod referansına göre sabitlenmiş bir yön bulmaya çalıştım:

    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)

Doğrudan QR koduna baktığımda yönlendirme gayet iyi, ancak daha sonra telefonun dönüşüyle ​​ilgili görünen bir şeyle değişiyor:görüntü açıklamasını buraya girin

Sahip olduğum en önemli sorular:

  • Dönüşü nasıl çözerim?
  • konum kaydırma değerleri nereden geliyor?
  • Rotasyon, çeviri, QRCornerCoordinatesInQRRef, gözlemler, intrisikler hangi basit ilişkiyi doğrular? O ~ K ^ -1 * (R_3x2 | T) Q mu? Çünkü eğer öyleyse, bu birkaç derece yanlıştır.

Yararlıysa, işte birkaç sayısal değer:

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

==== Düzenle2 ====

Telefon QR koduna yatay olarak paralel kaldığında döndürmenin iyi çalıştığını fark ettim (ör. Döndürme matrisi [[a, 0, b], [0, 1, 0], [c, 0, d]] ), gerçek QR kodu yönü ne olursa olsun:

görüntü açıklamasını buraya girin

Diğer rotasyon çalışmıyor.


Hey, cihazların mesafesini QR kodu ile almaya mı çalışıyorsun? Eğer öyleyse, aşağıdaki cevabıma bakın.
Ephellon Dantzler

DÜZENLEME: olağanüstü sorularınız için, 1. Görünüşe göre gereksiz bir değer girilmiş. Muhtemelen haritalama yönteminde veya çizilen çemberlerle ilgili başka herhangi bir şeyde (örneğin drawCircle(... rotation)) 2.
Spesifikasyonları

Biraz kod paylaşabilecek misin?
Michal Zaborowski

Yanıtlar:


2

Koordinat sistemlerinin yazışmaları

Dikkate al Vision/ CoreMLdeğil tekabül etmek gelmez koordinat sistemi ARKit/ SceneKitkoordinat sistemi. Ayrıntılar için bu gönderiye bakın .

Dönme yönü

Sanırım problem matriste değil. Köşelerin yerleşiminde. 2D görüntüleri izlemek için ABCD köşelerini saat yönünün tersine yerleştirmeniz gerekir (başlangıç ​​noktası hayali orijinli bir köşe noktasıdır x:0, y:0). VNRectangleObservation sınıfındaki Apple Dokümantasyonunun (bir görüntü analizi isteği tarafından algılanan öngörülen dikdörtgen bölgeler hakkında bilgi) belirsiz olduğunu düşünüyorum. Köşelerinizi resmi belgelerde olduğu gibi aynı sıraya yerleştirdiniz:

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

Ancak ZKartezyen koordinat sisteminde pozitif dönüş yönü ( eksen etrafında) gibi yerleştirilmeleri gerekir :

görüntü açıklamasını buraya girin

ARKit'teki (ve ayrıca SceneKit ve Vision'daki) Dünya Koordinat Alanı her zaman a'yı takip eder right-handed convention(pozitif Yeksen yukarı, pozitif Zeksen izleyiciyi işaret eder ve pozitif Xeksen izleyicinin sağına işaret eder), ancak oturumunuzun konfigürasyonuna göre yönlendirilir . Kamera, Yerel Koordinat Alanında çalışır.

Herhangi bir eksen etrafındaki dönüş yönü pozitif (Saat yönünün tersine) ve negatiftir (Saat yönünde). ARKit ve Vision'da izleme için çok önemlidir.

görüntü açıklamasını buraya girin

Dönme sırası da mantıklı. ARKit ve SceneKit, düğümün pivot özelliğine göre bileşenlerin ters sırasına göre döndürme uygular: önce roll( Zeksen hakkında ), sonra yaw( Yeksen hakkında ), sonra pitch( Xeksen hakkında ). Yani rotasyon sırası ZYX.


1

Matematik (Tetik.):

Denklem

Notlar: alt l(QR kod uzunluğu), sol açı kve üst açı i(kamera)

Resim


elbette, ancak sadece gözlemlenen açıyı ive orijinal mesafeyi biliyoruml
Guig

sorun değil, tersini bulmanın bir yolu var imı? Dik açı değilse, lya kda bulmak için daha fazla matematik gerekir theta; i + k + theta = 180.
Ephellon Dantzler

1
Trigonometriyi çalıştırmak için iki mesafeye ve bir açıya veya iki açıya ve bir mesafeye ihtiyacım var. Her şeyi tek bir açıdan ve tek bir mesafeden elde etmenin bir yolu yok
Guig

Hem dikey hem de yatay olmak üzere iki açıyı gözlemleyebilmeniz için QR kodunun kare olması yardımcı olur mu?
Bob Wakefield
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.