我试图对使用相同相机拍摄的一系列立体图像(类Step
)执行分发调整(BA)。
每个Step
都离开了&右图像(校正和同步),生成的深度图,左图像的关键点+描述符& 2个4x4矩阵 - 1个用于局部(图像平面)到全局(3D世界),以及它的反向(分别为T_L2G和T_G2L)。
针对第一张图片注册了步骤。
我试图在结果上运行BA以改进转换,并且我尝试使用PBA(https://grail.cs.washington.edu/projects/mcba/)
设置摄像机的代码:
for (int i = 0; i < steps.size(); i++)
{
Step& step = steps[i];
cv::Mat& T_G2L = step.T_G2L;
cv::Mat R;
cv::Mat t;
T_G2L(cv::Rect(0, 0, 3, 3)).copyTo(R);
T_G2L(cv::Rect(3, 0, 1, 3)).copyTo(t);
CameraT camera;
// Camera Parameters
camera.SetFocalLength((double)m_focalLength); // Same camera, global focal length
camera.SetTranslation((float*)t.data);
camera.SetMatrixRotation((float*)R.data);
if (i == 0)
{
camera.SetConstantCamera();
}
camera_data.push_back(camera);
}
然后,我通过运行所有图像对和匹配来生成全局关键点 (目前正在使用SURF)。
然后,生成BA指向数据:
for (size_t i = 0; i < globalKps.size(); i++)
{
cv::Point3d& globalPoint = globalKps[i].AbsolutePoint;
cv::Point3f globalPointF((float)globalPoint.x, (float)globalPoint.y, (float)globalPoint.z);
int num_obs = 0;
std::vector < std::pair<int/*stepID*/, int/*KP_ID*/>>& localKps = globalKps[i].LocalKeypoints;
if (localKps.size() >= 2)
{
Point3D pointData;
pointData.SetPoint((float*)&globalPointF);
// For this point, set all the measurements
for (size_t j = 0; j < localKps.size(); j++)
{
int& stepID = localKps[j].first;
int& kpID = localKps[j].second;
int cameraID = stepsLUT[stepID];
Step& step = steps[cameraID];
cv::Point3d p3d = step.KeypointToLocal(kpID);
Point2D measurement = Point2D(p3d.x, p3d.y);
measurements.push_back(measurement);
camidx.push_back(cameraID);
ptidx.push_back((int)point_data.size());
}
point_data.push_back(pointData);
}
}
然后,跑BA:
ParallelBA pba(ParallelBA::PBA_CPU_FLOAT);
pba.SetFixedIntrinsics(true); // Same camera with known intrinsics
pba.SetCameraData(camera_data.size(), &camera_data[0]); //set camera parameters
pba.SetPointData(point_data.size(), &point_data[0]); //set 3D point data
pba.SetProjection(measurements.size(), &measurements[0], &ptidx[0], &camidx[0]);//set the projections
pba.SetNextBundleMode(ParallelBA::BUNDLE_ONLY_MOTION);
pba.RunBundleAdjustment(); //run bundle adjustment, and camera_data/point_data will be
然后,在我遇到问题的地方,从PBA中提取数据:
for (int i = 1/*First camera is stationary*/; i < camera_data.size(); i++)
{
Step& step = steps[i];
CameraT& camera = camera_data[i];
int type = CV_32F;
cv::Mat t(3, 1, type);
cv::Mat R(3, 3, type);
cv::Mat T_L2G = cv::Mat::eye(4, 4, type);
cv::Mat T_G2L = cv::Mat::eye(4, 4, type);
camera.GetTranslation((float*)t.data);
camera.GetMatrixRotation((float*)R.data);
t.copyTo(T_G2L(TranslationRect));
R.copyTo(T_G2L(RotationRect));
cv::invert(T_G2L, T_L2G);
step.SetTransformation(T_L2G); // Step expects local 2 global transformation
}
一切都以我期望的方式运行。 PBA报告相对较小的初始错误(目前使用少量成对注册图像进行测试,因此错误不应该太大),并且在运行之后报告较小的错误。 (快速收敛,通常少于3次迭代)
然而,当我使用新发现的转换来转储关键点时,云似乎已经相互远离。
(我也尝试在T_G2L和T_L2G之间切换到&#34;让他们更接近&#34;。不能工作)。
我想知道我是否遗失了使用它。
答案 0 :(得分:0)
乌云似乎已经彼此分开
这似乎不是PBA特定的问题,而是捆绑包调整的一般问题。
执行束调整时,需要约束云,对于7自由度至少要约束7个。如果不是这样,您的云将沿3个轴,3个旋转和比例漂移。
在本地BA中,边界点设置为固定的。在完整的BA中,通常有指定的点(例如原点)和一个额外的对,用于固定比例和方向。