Chiếu camera hoàn nguyên iOS


87

Tôi đang cố gắng ước tính vị trí thiết bị của mình liên quan đến mã QR trong không gian. Tôi đang sử dụng ARKit và khung Vision, cả hai đều được giới thiệu trong iOS11, nhưng câu trả lời cho câu hỏi này có lẽ không phụ thuộc vào chúng.

Với khung Vision, tôi có thể lấy hình chữ nhật giới hạn mã QR trong khung máy ảnh. Tôi muốn khớp hình chữ nhật này với bản dịch và xoay thiết bị cần thiết để chuyển đổi mã QR từ vị trí chuẩn.

Ví dụ, nếu tôi quan sát khung hình:

*            *

    B
          C
  A
       D


*            *

trong khi nếu tôi cách mã QR 1m, căn giữa vào nó và giả sử mã QR có cạnh là 10cm, tôi sẽ thấy:

*            *


    A0  B0

    D0  C0


*            *

chuyển đổi thiết bị của tôi giữa hai khung hình đó là gì? Tôi hiểu rằng có thể không có kết quả chính xác, vì có thể mã QR quan sát được hơi không phẳng và chúng tôi đang cố gắng ước tính một chuyển đổi affine trên một thứ không phải là một hoàn hảo.

Tôi đoán sceneView.pointOfView?.camera?.projectionTransformlà hữu ích hơn sceneView.pointOfView?.camera?.projectionTransform?.camera.projectionMatrixvì sau này đã tính đến chuyển đổi được suy ra từ ARKit mà tôi không quan tâm đến vấn đề này.

Tôi sẽ điền như thế nào

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 
}

==== Chỉnh sửa ====

Sau khi thử một số thứ, tôi đã kết thúc ước tính tư thế máy ảnh bằng cách sử dụng công cụ giải phối cảnh và phép chiếu openCV, solvePnPĐiều này mang lại cho tôi cách xoay và bản dịch sẽ đại diện cho tư thế máy ảnh trong tham chiếu mã QR. Tuy nhiên, khi sử dụng các giá trị đó và đặt các đối tượng tương ứng với phép biến đổi nghịch đảo, nơi mã QR phải ở trong không gian máy ảnh, tôi nhận được các giá trị được dịch chuyển không chính xác và tôi không thể xoay vòng hoạt động:

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

Đây là đầu ra:

nhập mô tả hình ảnh ở đây

trong đó A, B, C, D là các góc mã QR theo thứ tự chúng được chuyển đến chương trình.

Điểm gốc dự đoán vẫn giữ nguyên vị trí khi điện thoại xoay, nhưng nó sẽ bị dịch chuyển so với vị trí cần thiết. Đáng ngạc nhiên, nếu tôi thay đổi các giá trị quan sát, tôi có thể sửa điều này:

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

nhập mô tả hình ảnh ở đây

và bây giờ nguồn gốc được dự đoán vẫn giữ nguyên vị trí. Tuy nhiên tôi không hiểu giá trị dịch chuyển đến từ đâu.

Cuối cùng, tôi đã cố gắng cố định hướng tương đối với tham chiếu mã 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)

Định hướng tốt khi tôi nhìn thẳng vào mã QR, nhưng sau đó nó thay đổi theo một thứ gì đó có vẻ liên quan đến xoay điện thoại:nhập mô tả hình ảnh ở đây

Câu hỏi nổi bật mà tôi có là:

  • Làm cách nào để giải quyết vấn đề xoay vòng?
  • giá trị dịch chuyển vị trí đến từ đâu?
  • Những mối quan hệ đơn giản nào mà xoay, dịch, QRCornerCoferencesInQRRef, quan sát, nội hàm xác minh? Có phải là O ~ K ^ -1 * (R_3x2 | T) Q không? Bởi vì nếu vậy thì điều đó giảm đi một vài bậc.

Nếu điều đó hữu ích, đây là một vài giá trị số:

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 ====

Tôi nhận thấy rằng xoay hoạt động tốt khi điện thoại nằm ngang song song với mã QR (tức là ma trận xoay là [[a, 0, b], [0, 1, 0], [c, 0, d]] ), bất kể hướng mã QR thực tế là gì:

nhập mô tả hình ảnh ở đây

Vòng quay khác không hoạt động.


Này, bạn có đang cố lấy khoảng cách giữa các thiết bị thông qua mã QR không? Nếu vậy, hãy xem câu trả lời của tôi dưới đây.
Ephellon Dantzler

CHỈNH SỬA: đối với các câu hỏi còn tồn tại của bạn, 1. Có vẻ như chỉ đơn giản là có một giá trị không cần thiết được chèn vào. Có thể trong phương pháp lập bản đồ gọi, hoặc bất cứ điều gì khác giao dịch với các vòng tròn được vẽ (như drawCircle(... rotation)) 2. Có không có thời gian để đọc các thông số kỹ thuật 3. Tương tự như 2
Ephellon Dantzler

Bạn sẽ có thể chia sẻ một số mã?
Michal Zaborowski

Câu trả lời:


1

Math (Trig.):

Phương trình

Lưu ý: dưới cùng là l(chiều dài mã QR), góc bên trái kvà góc trên cùng là i(máy ảnh)

Hình ảnh


chắc chắn, nhưng tôi chỉ biết góc quan sát ivà khoảng cách ban đầul
Guig

đó là tốt, có cách nào để tìm thấy điều ngược lại của i? Nếu nó không phải là một góc vuông lthì sẽ có nhiều toán học hơn để tìm một trong hai khoặc theta; i + k + theta = 180.
Ephellon Dantzler,

1
Để lượng giác hoạt động, tôi cần hai khoảng cách và một góc, hoặc hai góc và một khoảng cách. Không có cách nào để có được tất cả mọi thứ từ một góc và một khoảng cách
Guig

Nó có giúp mã QR là hình vuông, để bạn có thể quan sát hai góc, cả dọc và ngang?
Bob Wakefield

1

Tôi cho rằng vấn đề không nằm trong ma trận. Nó ở vị trí đỉnh. Để theo dõi hình ảnh 2D, bạn cần đặt các đỉnh ABCD ngược chiều kim đồng hồ (điểm bắt đầu là đỉnh A nằm trong gốc tưởng tượng x:0, y:0 ). Tôi nghĩ Tài liệu của Apple trên lớp VNRectangleObservation (thông tin về các vùng hình chữ nhật dự kiến ​​được phát hiện bởi một yêu cầu phân tích hình ảnh) là mơ hồ. Bạn đã đặt các đỉnh của mình theo thứ tự như trong tài liệu chính thức:

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

Nhưng chúng cần được đặt giống như hướng quay dương (về Ztrục) xảy ra trong hệ tọa độ Descartes:

nhập mô tả hình ảnh ở đây

Không gian tọa độ thế giới trong ARKit (cũng như trong SceneKit và Vision) luôn tuân theo a right-handed convention( Ytrục dương hướng lên trên, Ztrục dương hướng về phía người xem và Xtrục dương hướng về phía bên phải của người xem), nhưng được định hướng dựa trên cấu hình phiên của bạn . Máy ảnh hoạt động trong Không gian tọa độ cục bộ.

Hướng quay về bất kỳ trục nào là dương (Ngược chiều kim đồng hồ) và âm (Theo chiều kim đồng hồ). Để theo dõi trong ARKit và Vision, điều này cực kỳ quan trọng.

nhập mô tả hình ảnh ở đây

Thứ tự quay cũng có ý nghĩa. ARKit, cũng như SceneKit, áp dụng xoay liên quan đến thuộc tính pivot của nút theo thứ tự ngược lại của các thành phần: đầu tiên roll(về Ztrục), sau đó yaw(về Ytrục), sau đó pitch(về Xtrục). Vậy thứ tự luân chuyển là ZYX.

Ngoài ra, có một bài đăng hữu ích về Hoạt động Ma trận trên Nukepedia.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.