我正在尝试使用立体相机获取3D坐标。
第二种方法是在opencv中使用reprojectImageTo3D。
但我不知道这种方法的原理。
结果不是以毫米为单位,因此很难匹配大小。
请告诉我两种方法的区别。
(这些代码中的第一个是匹配后将点要素转换为3D坐标。) (第二个代码是使用SGBM计算整个立体图像的视差,并使用reprojectImageTo3D计算点要素的3d坐标。)
*第一种方法
cv::Mat disparity16S(m_input.m_leftImg.size(), CV_16S);
sgbm->compute(m_input.m_leftImg, m_input.m_rightImg, disparity16S);
cv::Mat xyz;
cv::Matx44d Q = cv::Matx44d(
1.0, 0.0, 0.0, -cX,
0.0, 1.0, 0.0, -cY,
0.0, 0.0, 0.0, fX,
0.0, 0.0, -1.0 / baseLine, 0/*(CX - CX) / baseLine*/
);
cv::reprojectImageTo3D(disparity16S, xyz, Q, true);
cv::Mat pointXYZ(xyz.size(), xyz.type(), cv::Scalar::all(0));
for (int i = 0; i < size; i++)
{
cv::Point pt = cv::Point((int)(feOutput.m_leftKp.at(i).pt.x + 0.5f), (int)(feOutput.m_leftKp.at(i).pt.y + 0.5f));
pointXYZ.at<cv::Vec3f>(pt) = xyz.at<cv::Vec3f>(pt) / 1000.f;
}
*第二种方法
Sub TooMuchHoliday()
Dim daysremaining As Integer, daystaken As Integer, result As String, myValue As Variant
daystaken = Range("B13").Value
daysremaining = Range("D14").Value
If daysremaining <= 1 Then
Msg = " You Do Not Have Enough Holiday! Would You Like To Continue ? " & Application.UserName
Ans = MsgBox(Msg, vbYesNo)
If Ans = vbNo Then
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
End If
If Ans = vbYes Then
Sheets("Request Form").Select
Range("Employee3").ClearContents
Range("DateRequest").ClearContents
Range("Employee3") = Application.UserName
End If
End If
If daystaken >= 25 Then
Msg = " You Do Not Have Enough Holiday! Would You Like To Continue ? " & Application.UserName
Ans = MsgBox(Msg, vbYesNo)
If Ans = vbNo Then
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
End If
If Ans = vbYes Then
Sheets("Request Form").Select
Range("Employee3").ClearContents
Range("DateRequest").ClearContents
Range("Employee3") = Application.UserName
Else
NewBookingCheck.NewBookingCheck
End If
End If
End Sub
添加+ 粉红色是reprojectImageTo3D方法的大小,缩放为1/100,黄色是第一种方法中1/1000(mm 2米)的大小。 如果两种方法相同,为什么规模存在差异?
答案 0 :(得分:0)
理论上没有区别,只有方法。 您可以使用sgbm opencv方法(不执行任何匹配但解决最小化问题)计算单个匹配点(第一种方法)或图像中每个像素的差异。
一旦你有差异D,从三角测量你检索深度Z的第一个公式。这应该是&#34;距离&#34;从你的参考图像平面(通常:左相机)。
z = f*b/d
一旦你有Z,知道投影方程表明主摄像机(伪代码)
f, 0 , cX, 0
K = 0 , f, cY, 0
0 , 0, 1, 0
[x y 1] = 1/Z * K * [X Y Z 1]
你可以逆转。
[X Y Z 1] = inv(K)* [Z*x Z*y Z] /*Z is known from disparity */
发现你的x,y就像在第一张图片的第一列中显示的那样。 这些是在主(左)相机参考系统中,但如果你想在右相机中你的发布图像做2假设
b is all along x
the two camera planes are perfectly parallel
通常对于其他相机,您假设b是已知向量。可以发生这两个参考系统之间的旋转,因此还必须定义R矩阵)。我认为所有这些情况都是用不同的Q矩阵表示的(从立体摄像机校准中获得,例如stereoRectify
)。
cv::reprojectImageTo3D
只是&#34; authomatic方法&#34;。他需要相机参数和连续视差图。它可以与单个选择点的差异一起工作。