2 ডি পয়েন্টটি 3 ডি লোকেশনে রূপান্তর করা হচ্ছে


9

আমার পরিচিত cameraMatrixএবং সহ একটি স্থির ক্যামেরা রয়েছে distCoeffs। আমার কাছে একটি দাবাবোর্ডও রয়েছে যা খুব ঠিক করা হয়েছে transformএবং rotationভেক্টর ব্যবহার করেও গণনা করা হয় solvePnP

আমি ভাবছি যে নীচের ছবির মতো দাবাবোর্ডটি একই প্লেনে 2 ডি পয়েন্টের 3 ডি অবস্থান কীভাবে পাওয়া সম্ভব:

এখানে চিত্র বর্ণনা লিখুন

নিশ্চিত করার জন্য একটি বিষয় হ'ল যে বিন্দুটির জেড 0, তবে কীভাবে পয়েন্টটির এক্স এবং ওয়াই পাবেন ।


আপনার রূপান্তর এবং ঘূর্ণন ভেক্টরগুলির সাহায্যে, আপনি কি 3D তে দাবাবোর্ডের সমস্ত কোণ ব্যাখ্যা করতে সক্ষম?
মিকা 9 ই

আপনি যদি বলেন যে জেড 0 হবে, আপনার পক্ষে ঠিক সেই বিন্দুটির সমতল-স্থানাঙ্কগুলি পাওয়া ঠিক হবে? "লাল দিকের 10 সেমি এবং সবুজ দিকের বিয়োগ 15 সেন্টিমিটারের মতো?
মিকা

@ মিকা এই কাজ করবে না, কারণ ক্যামেরার নিকটবর্তী পিক্সেলগুলি বৃহত্তর অঞ্চলের প্রতিনিধিত্ব করে
EBAG

প্ল্যাটপ্রেসিভ হোমোগ্রাফির সাথে বিমানের সমন্বয়সাধ্য হওয়া সহজ। তবে আপনার ক্যামেরা কেন্দ্রে 3 ডি স্পেসে 3 ডি পয়েন্টের প্রয়োজন হলে, আপনার ঘোরা এবং ট্রান্সলেশন ভেক্টরগুলি পরে বিমানটিকে রূপান্তর করতে হবে।
মিকা 18

আপনি কি এই পয়েন্ট স্থানাঙ্কের আপনার প্রত্যাশিত ফলাফল প্রদান করতে পারেন?
আবদেল আজিজ আবদেল লাতফ

উত্তর:


6

আপনি এটি 3 টি সহজ পদক্ষেপের সাহায্যে সমাধান করতে পারেন:

ধাপ 1:

ক্যামেরা প্রজেকশন মডেলটি উল্টিয়ে প্রদত্ত 2 ডি চিত্রের পয়েন্টের সাথে রশ্মির সাথে রশ্মির ক্যামের স্থানাঙ্ক ফ্রেমে প্রকাশিত 3 ডি দিকের ভেক্টরটি গণনা করুন:

std::vector<cv::Point2f> imgPt = {{u,v}}; // Input image point
std::vector<cv::Point2f> normPt;
cv::undistortPoints     (imgPt, normPt, cameraMatrix, distCoeffs);
cv::Matx31f ray_dir_cam(normPt[0].x, normPt[0].y, 1);
// 'ray_dir_cam' is the 3d direction of the ray in camera coordinate frame
// In camera coordinate frame, this ray originates from the camera center at (0,0,0)

ধাপ ২:

দাবাবোর্ডের সাথে সংযুক্ত স্থানাঙ্ক ফ্রেমে এই রশ্মির ভেক্টরের 3 ডি দিক গণনা করুন, ক্যামেরা এবং দাবা বোর্ডের মধ্যে আপেক্ষিক পোজ ব্যবহার করুন:

// solvePnP typically gives you 'rvec_cam_chessboard' and 'tvec_cam_chessboard'
// Inverse this pose to get the pose mapping camera coordinates to chessboard coordinates
cv::Matx33f R_cam_chessboard;
cv::Rodrigues(rvec_cam_chessboard, R_cam_chessboard);
cv::Matx33f R_chessboard_cam = R_cam_chessboard.t();
cv::Matx31f t_cam_chessboard = tvec_cam_chessboard;
cv::Matx31f pos_cam_wrt_chessboard = -R_chessboard_cam*t_cam_chessboard;
// Map the ray direction vector from camera coordinates to chessboard coordinates
cv::Matx31f ray_dir_chessboard = R_chessboard_cam * ray_dir_cam;

ধাপ 3:

3 ডি রে এবং দাবাবোর্ড বিমানের মধ্যে ছেদটি জেড = 0 দিয়ে ছেদ করে কাঙ্ক্ষিত 3 ডি পয়েন্টটি সন্ধান করুন:

// Expressed in the coordinate frame of the chessboard, the ray originates from the
// 3d position of the camera center, i.e. 'pos_cam_wrt_chessboard', and its 3d
// direction vector is 'ray_dir_chessboard'
// Any point on this ray can be expressed parametrically using its depth 'd':
// P(d) = pos_cam_wrt_chessboard + d * ray_dir_chessboard
// To find the intersection between the ray and the plane of the chessboard, we
// compute the depth 'd' for which the Z coordinate of P(d) is equal to zero
float d_intersection = -pos_cam_wrt_chessboard.val[2]/ray_dir_chessboard.val[2];
cv::Matx31f intersection_point = pos_cam_wrt_chessboard + d_intersection * ray_dir_chessboard;

আপনার পদ্ধতিটি নিখুঁতভাবে কাজ করে, ধন্যবাদ :)
EBAG

1

যেহেতু আপনার ক্ষেত্রে সমভূমি সীমাবদ্ধ, তাই সহজ উপায় হমোগ্রাফি ব্যবহার করা।

প্রথমে আপনার চিত্রটি আনস্টোর্ট করুন ort তারপরে হোমোগ্রাফি ম্যাট্রিক্স গণনা করতে ফাইন্ড হোমোগ্রাফিটি ব্যবহার করুন যা আপনার পিক্সেল স্থানাঙ্ক (চিত্র) কে সত্যিকারের স্থানাঙ্কে রূপান্তরিত করে (ইউক্লিডিয়ান স্পেস যেমন সেমি)। এর মতো কিছু:

#include <opencv2/calib3d.hpp>
//...

//points on undistorted image (in pixel). more is better
vector<Point2f>  src_points = { Point2f(123,321), Point2f(456,654), Point2f(789,987), Point2f(123,321) };
//points on chessboard (e.g. in cm)
vector<Point2f>  dst_points = { Point2f(0, 0), Point2f(12.5, 0), Point2f(0, 16.5), Point2f(12.5, 16.5) }; 
Mat H = findHomography(src_points, dst_points, RANSAC);

//print euclidean coordinate of new point on undistorted image (in pixel)
cout << H * Mat(Point3d(125, 521, 0)) << endl;

আপনি যা বলেছিলেন তা আমি করেছি: ভেক্টর <Point2f> কোণ, ভেক্টর <Point2f> অবজেক্টপয়েন্টস 2 ডি; FindChessboardCorners (img, પેટર્નসাইজ, কর্নার); ক্যালকচিসবোর্ড কর্নার্স (প্যাটার্ন সাইজ, স্কোয়ারসাইজ, অবজেক্টপয়েন্টস 2 ডি); দাবা বোর্ডহোমোগ্রাফি = সন্ধান হোমোগ্রাফি (কোণ, অবজেক্টপয়েন্টস 2 ডি, আরএনএসএসি);
EBAG

এটি কাজ করে না, এবং এটি যে স্থানাঙ্ক ফেরত দেয় তা সঠিক নয়
EBAG

এমনকি যদি আপনি দাবাবোর্ডে অবস্থিত পিক্সেলটির সাথে হোমোগ্রাফি ম্যাট্রিক্সকে গুণিত করেন [0,0,0] এটি ফিরে আসবে [-192, -129, 0.33]
EBAG

@ ইবাগ আপনি কি প্রথমে চিত্রটি আনস্টোর করবেন? অবজেক্টপয়েন্টস 2 ডি সঠিক হবে কিনা তা পরীক্ষা করুন। ইভেন্ট মুদ্রণ এবং ম্যানুয়ালি তাদের পরীক্ষা করুন।
ma.mehralian
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.