从二维图像求墙的藏格位置

2024-03-28 20:40:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我在现实生活中有一个3D矩形墙,可以转换成2D图像。考虑到我有他所有的4点坐标。我怎样才能找到他相对于摄像机的真实Z角位置?你知道吗

我试着从不同角度测量矩形的边与边之间的比率,通过这个,我可以找到常数,如果我将他乘以某些边的比率,它将给出当前的Z角。它不工作,因为当一个旋转的墙壁之间的边缘比例并不总是改变。 还有什么我能做的吗?你知道吗

图1: image 1 预期输出:0度

图2: image 2

预期输出:20度左右

图3: image 3

预期输出:45度左右


Tags: 图像image常数边缘比例摄像机比率角度
1条回答
网友
1楼 · 发布于 2024-03-28 20:40:05

基础数学

假设你有两个二维图像,你希望找到它们之间的旋转。例如,第一个图像是前平行0度。第二个是你想找的角度。你知道吗

请从这里学习一些基本知识https://www.ifi.uzh.ch/dam/jcr:5759a719-55db-4930-8051-4cc534f812b1/VO_Part_I_Scaramuzza.pdf

enter image description here

它是从图像特征对应中捕捉二维到二维运动。数学太多了。我一点也不去。本质上,你在寻找一个基本矩阵,它是秩2,包含所有的旋转和平移向量

enter image description here

enter image description here

最小情况解决方案涉及五个2-D到2-D对应,如中所述

E.Kruppa,“我的目标是我的个人目标 内部定位“Sitzungsberichte der Akademie der Wissenschaften, Wien,Mathematisch Naturwissenschafttlichen Klasse,Abteilung IIa数学教授, 第122卷,第1939-1948页,1913年。你知道吗

更流行的方法是朗格特-希金斯的八点算法。超过8个对应的匹配点。你知道吗

只需列出匹配点如下所示

enter image description here

因为你可以先校准相机,再校准手柄,所以F可以直接用E代替。你知道吗

此外,你还必须通过在多视图几何书中的极线几何,如上图所示

如果你的相机是RGBD相机,那么你只需要3个点进行匹配,它叫3D到3D运动估计中的第一个环节。你知道吗

编码

假设你知道所有的数学背景。相应地安装opencv

假设您使用的图像位于img1和img2中。img 1是前平行线。图2是你想要找到的旋转角度。你知道吗

  Mat img_1_c = imread(filename1);
  Mat img_2_c = imread(filename2); //each file should not have any color drawing inside

您可以手动编辑匹配点,例如带有中心点的4个角

vector<Point2f> points1, points2;  //each topic have at least 5 point inside

最简单的方法是在OpenCV中使用特征检测路由(可选)

  cvtColor(img_1_c, img_1, COLOR_BGR2GRAY);
  cvtColor(img_2_c, img_2, COLOR_BGR2GRAY);
  featureDetection(img_1, points1);        //detect features in img_1
  vector<uchar> status;
  featureTracking(img_1,img_2,points1,points2, status); //track those features to img_2

如果基线移动太大,你可以用探测器描述符匹配器的方式。(可选)

SurfFeatureDetector detector(400);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img_1, keypoints1);
detector.detect(img_2, keypoints2);

// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img_1, keypoints1, descriptors1);
extractor.compute(img_2, keypoints2, descriptors2);

// matching descriptors
BFMatcher matcher(NORM_L2);
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);

// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img_1, keypoints1, img_2, keypoints2, matches, img_matches);
imshow("matches", img_matches);

输入相机焦点和原理点从相机内部校准https://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html

  double focal = XXXX;
  cv::Point2d pp(XXXXX, XXxxx); // this should be around the center of image if it is too far away, check you calibration process

Mat E, R, t, mask;
E = findEssentialMat(points2, points1, focal, pp, RANSAC, 0.999, 1.0, mask);   
recoverPose(E, points2, points1, R, t, focal, pp, mask);

R和t包含旋转和平移(不是真实世界的比例)。你知道吗

Mat Euler_vec;
Rodrigues(R,Euler_vec);
cout<<Euler_vec<<endl;

那么Euler_vec应该包含你想要的角度。您要查找的值应该位于第一列或最后一列

相关问题 更多 >