আমি স্পেসে কোনও QR কোড সম্পর্কিত আমার ডিভাইসের অবস্থান অনুমান করার চেষ্টা করছি। আমি এআরকিট এবং ভিশন ফ্রেমওয়ার্ক ব্যবহার করছি, উভয়ই আইওএস 11-এ প্রবর্তিত, তবে এই প্রশ্নের উত্তর সম্ভবত তাদের উপর নির্ভর করে না।
ভিশন ফ্রেমওয়ার্কের সাহায্যে আমি আয়তক্ষেত্রটি পেতে সক্ষম হয়েছি যা ক্যামেরার ফ্রেমে কোনও কিউআর কোডকে সীমাবদ্ধ করে। আমি একটি আদর্শ অবস্থান থেকে কিউআর কোড রূপান্তর করতে প্রয়োজনীয় ডিভাইস অনুবাদ এবং রোটেশনের সাথে এই আয়তক্ষেত্রটি মিলাতে চাই।
উদাহরণস্বরূপ যদি আমি ফ্রেমটি পর্যবেক্ষণ করি:
* *
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
}
এখানে ফলাফল:
যেখানে A, B, C, D হল সেই প্রোগ্রামে যে অর্ডার দেওয়া হয় তাতে কিউআর কোড কর্নার।
ফোনটি ঘোরার সময় পূর্বাভাস উত্পন্ন জায়গায় থাকে তবে এটি যেখানে হওয়া উচিত সেখান থেকে স্থানান্তরিত হয়। আশ্চর্যের বিষয়, আমি যদি পর্যবেক্ষণের মানগুলি স্থানান্তর করি তবে আমি এটি সংশোধন করতে সক্ষম হয়েছি:
// (imageSize.height * (1 - $0.y), imageSize.width * $0.x)
// replaced by:
(imageSize.height * (1.35 - $0.y), imageSize.width * ($0.x - 0.2))
এবং এখন পূর্বাভাস উত্সটি দৃ rob়ভাবে স্থানে থাকে। তবে শিফট মানগুলি কোথা থেকে এসেছে তা আমি বুঝতে পারি না।
পরিশেষে, আমি কিউআর কোড রেফারেনশিয়ালের সাথে তুলনামূলকভাবে স্থির করার চেষ্টা করেছি:
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)
আমি যখন সরাসরি কিউআর কোডটি দেখি তখন ওরিয়েন্টেশনটি ঠিকঠাক হয় তবে তারপরে এটি এমন কোনও কিছুতে স্থানান্তরিত হয় যা মনে হয় ফোন রোটেশনের সাথে সম্পর্কিত:
আমার কাছে অসামান্য প্রশ্নগুলি হ'ল:
- আমি ঘূর্ণনটি কীভাবে সমাধান করব?
- অবস্থান শিফট মানগুলি কোথা থেকে আসে?
- ঘূর্ণন, অনুবাদ, কিউআরকর্নারকর্ডিনেটসআইএনকিউআরএফ, পর্যবেক্ষণগুলি, আন্তঃবিজ্ঞান যাচাই করে কোন সাধারণ সম্পর্ক? এটি কি ও ~ কে ^ -1 * (R_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
==== সম্পাদনা ====
আমি লক্ষ্য করেছি যে ফোনটি যখন কিউআর কোডের সাথে অনুভূমিকভাবে সমান্তরাল থাকে তখন ঘূর্ণনটি সূক্ষ্মভাবে কাজ করে (যেমন রোটেশন ম্যাট্রিক্সটি [[a, 0, খ], [0, 1, 0], [সি, 0, ডি]]] ), আসল কিউআর কোড ওরিয়েন্টেশন কী তা বিবেচনাধীন নয়:
অন্যান্য ঘূর্ণন কাজ করে না।