iOS 되돌리기 카메라 투영


87

우주에서 QR 코드와 관련된 내 장치 위치를 추정하려고합니다. 저는 ARKit과 Vision 프레임 워크를 사용하고 있는데, 둘 다 iOS11에 도입되었지만이 질문에 대한 대답은 아마도 그들에 의존하지 않을 것입니다.

Vision 프레임 워크를 사용하면 카메라 프레임에서 QR 코드를 묶는 직사각형을 얻을 수 있습니다. 이 사각형을 표준 위치에서 QR 코드를 변환하는 데 필요한 장치 변환 및 회전과 일치시키고 싶습니다.

예를 들어 프레임을 관찰하면 :

*            *

    B
          C
  A
       D


*            *

QR 코드에서 1m 떨어져 있고 그 중앙에 있고 QR 코드의 측면이 10cm라고 가정하면 다음과 같이 표시됩니다.

*            *


    A0  B0

    D0  C0


*            *

이 두 프레임 사이에서 장치 변환은 무엇입니까? 나는 관찰 된 QR 코드가 약간 비평 면적이어서 우리는 완벽하게 하나가 아닌 것에 대한 아핀 변환을 추정하려고하기 때문에 정확한 결과가 불가능할 수 있다는 것을 이해합니다.

나는 추측 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 
}

==== 편집 ====

여러 가지를 시도한 후 openCV 투영 및 원근 솔버를 사용하여 카메라 포즈 추정을 시작했습니다. solvePnP이것은 QR 코드 참조에서 카메라 포즈를 나타내는 회전 및 변환을 제공합니다. 그러나 이러한 값을 사용하고 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
}

다음은 출력입니다.

여기에 이미지 설명 입력

여기서 A, B, C, D는 프로그램에 전달되는 순서대로 QR 코드 모서리입니다.

예상 원점은 전화기가 회전 할 때 제자리에 유지되지만 있어야하는 위치에서 이동합니다. 놀랍게도 관측 값을 변경하면이 문제를 수정할 수 있습니다.

  // (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)

QR 코드를 똑바로 보면 방향은 괜찮지 만 전화 회전과 관련된 것처럼 보이는 방향으로 이동합니다.여기에 이미지 설명 입력

내가 가진 뛰어난 질문은 다음과 같습니다.

  • 회전을 어떻게 해결합니까?
  • 위치 이동 값의 출처는 어디입니까?
  • 회전, 평행 이동, QRCornerCoordinatesInQRRef, 관찰, intrisics는 어떤 간단한 관계를 확인합니까? 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

==== 편집 2 ====

전화기가 QR 코드와 수평으로 평행을 유지하면 회전이 잘 작동하는 것으로 나타났습니다 (예 : 회전 행렬은 [[a, 0, b], [0, 1, 0], [c, 0, d]]) ), 실제 QR 코드 방향에 관계없이 :

여기에 이미지 설명 입력

다른 회전은 작동하지 않습니다.


이봐 요, QR 코드를 통해 기기 거리를 확인하려고하십니까? 그렇다면 아래 내 대답을 참조하십시오.
Ephellon Dantzler

편집 : 뛰어난 질문에 대해 1. 단순히 불필요한 값이 삽입 된 것 같습니다. 아마도 매핑 메서드에서 호출되거나 그려지는 원을 다루는 다른 모든 것 (예 drawCircle(... rotation)
:)

코드를 공유 할 수 있습니까?
Michal Zaborowski

답변:


1

수학 (트리거) :

방정식

참고 : 하단은 l(QR 코드 길이), 왼쪽 각도는 k, 상단 각도는 i(카메라)입니다.

그림


물론, 관찰 된 각도 만 알고 있습니다. i 원래 거리l
Guig

괜찮아요, 반대편을 찾을 수있는 방법이 있나요? i 있습니까? 직각이 아니라면 또는 l을 찾는 데 더 많은 수학이 필요합니다 . . kthetai + k + theta = 180
Ephellon Dantzler

1
삼각법을 사용하려면 두 개의 거리와 한 개의 각도 또는 두 개의 각도와 한 개의 거리가 필요합니다. 한 각도와 거리에서 모든 것을 얻을 수있는 방법은 없습니다.
Guig

QR 코드가 정사각형이므로 수직 및 수평의 두 각도를 관찰 할 수있는 것이 도움이됩니까?
Bob Wakefield

1

문제가 매트릭스에 없다고 생각합니다. 정점 배치에 있습니다. 2D 이미지를 추적하려면 ABCD 정점을 시계 반대 방향으로 배치해야합니다 (시작점은 가상 원점 에있는 정점 x:0, y:0). VNRectangleObservation 클래스 에 대한 Apple 문서 (이미지 분석 요청에 의해 감지 된 투영 된 직사각형 영역에 대한 정보)가 모호하다고 생각합니다. 공식 문서와 동일한 순서로 정점을 배치했습니다.

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

그러나 그들은 Z직교 좌표계에서 양의 회전 방향 ( 축 에 대한 )이 발생 하는 것과 같은 방식으로 배치되어야 합니다.

여기에 이미지 설명 입력

ARKit (SceneKit 및 Vision뿐만 아니라)의 World Coordinate Space는 항상 a right-handed convention(양의 Y축은 위쪽을 가리키고 양의 Z축은 뷰어를 향하고 양의 X축은 뷰어의 오른쪽 을 가리킴 )을 따르지만 세션의 구성에 따라 방향이 지정됩니다. . 카메라는 로컬 좌표 공간에서 작동합니다.

모든 축에 대한 회전 방향은 양수 (시계 반대 방향) 및 음수 (시계 방향)입니다. ARKit 및 Vision에서 추적하려면 매우 중요합니다.

여기에 이미지 설명 입력

회전 순서도 의미가 있습니다. ARKit과 SceneKit은 구성 요소의 역순으로 노드의 피벗 속성을 기준으로 회전을 적용합니다.roll ( Z축 에 대해 ), 다음으로 yaw( Y축 에 대해 ), 다음에 pitch( X축 에 대해 ). 따라서 회전 순서는 ZYX입니다.

또한 Nukepedia 에 Matrix Operations 에 대한 유용한 게시물이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.