vector<Geometry::DynKeyPoint> Geometry::ExtractDynPoints(const vector<ORB_SLAM2::Frame> &vRefFrames, const ORB_SLAM2::Frame ¤tFrame){ cv::Mat K = cv::Mat::eye(3,3,CV_32F); K.at<float>(0,0) = currentFrame.fx; K.at<float>(1,1) = currentFrame.fy; K.at<float>(0,2) = currentFrame.cx; K.at<float>(1,2) = currentFrame.cy; cv::Mat vAllMPw; cv::Mat vAllMatRefFrame; cv::Mat vAllLabels; cv::Mat vAllDepthRefFrame; for (int i(0); i < mnRefFrames; i++) { ORB_SLAM2::Frame refFrame = vRefFrames[i]; // Fill matrix with points cv::Mat matRefFrame(refFrame.N,3,CV_32F); cv::Mat matDepthRefFrame(refFrame.N,1,CV_32F); cv::Mat matInvDepthRefFrame(refFrame.N,1,CV_32F); cv::Mat vLabels(refFrame.N,1,CV_32F); int k(0); for(int j(0); j < refFrame.N; j++){ const cv::KeyPoint &kp = refFrame.mvKeys[j]; const float &v = kp.pt.y; const float &u = kp.pt.x; const float d = refFrame.mImDepth.at<float>(v,u); if (d > 0 && d < 6){ matRefFrame.at<float>(k,0) = refFrame.mvKeysUn[j].pt.x; matRefFrame.at<float>(k,1) = refFrame.mvKeysUn[j].pt.y; matRefFrame.at<float>(k,2) = 1.; matInvDepthRefFrame.at<float>(k,0) = 1./d; matDepthRefFrame.at<float>(k,0) = d; vLabels.at<float>(k,0) = i; k++; } }
这段代码是一个循环,用于遍历参考帧向量vRefFrames中的每个参考帧,并填充一些矩阵变量。
在循环中,首先通过ORB_SLAM2::Frame refFrame = vRefFrames[i];将当前参考帧赋值给refFrame。
然后,以下是循环中的每一步操作:
matRefFrame.at<float>(k, 0) = refFrame.mvKeysUn[j].pt.x;:将当前特征点在无畸变像素坐标系下的x坐标存储在matRefFrame中。matRefFrame.at<float>(k, 1) = refFrame.mvKeysUn[j].pt.y;:将当前特征点在无畸变像素坐标系下的y坐标存储在matRefFrame中。matRefFrame.at<float>(k, 2) = 1.;:给定参考帧特征点在相机坐标系中的z坐标为1。matInvDepthRefFrame.at<float>(k, 0) = 1. / d;:将特征点的逆深度值存储在matInvDepthRefFrame中。matDepthRefFrame.at<float>(k, 0) = d;:将特征点的深度值存储在matDepthRefFrame中。vLabels.at<float>(k, 0) = i;:将当前特征点的标签(即参考帧索引)存储在vLabels中。k的值。这段代码的目的是在每个参考帧中提取出有效的动态点,并将相关的信息存储在相应的矩阵中。这些信息将在后续操作中用于提取和处理动态点的信息。
matRefFrame = matRefFrame.rowRange(0, k); matInvDepthRefFrame = matInvDepthRefFrame.rowRange(0, k); matDepthRefFrame = matDepthRefFrame.rowRange(0, k); vLabels = vLabels.rowRange(0, k); cv::Mat vMPRefFrame = K.inv() * matRefFrame.t(); cv::vconcat(vMPRefFrame, matInvDepthRefFrame.t(), vMPRefFrame); cv::Mat vMPw = refFrame.mTcw.inv() * vMPRefFrame; cv::Mat _vMPw = cv::Mat(4, vMPw.cols, CV_32F); cv::Mat _vLabels = cv::Mat(vLabels.rows, 1, CV_32F); cv::Mat _matRefFrame = cv::Mat(matRefFrame.rows, 3, CV_32F); cv::Mat _matDepthRefFrame = cv::Mat(matDepthRefFrame.rows, 1, CV_32F);int h(0); mParallaxThreshold = 30; for (int j(0); j < k; j++) { cv::Mat mp = cv::Mat(3, 1, CV_32F); mp.at<float>(0, 0) = vMPw.at<float>(0, j) / matInvDepthRefFrame.at<float>(0, j); mp.at<float>(1, 0) = vMPw.at<float>(1, j) / matInvDepthRefFrame.at<float>(0, j); mp.at<float>(2, 0) = vMPw.at<float>(2, j) / matInvDepthRefFrame.at<float>(0, j); cv::Mat tRefFrame = refFrame.mTcw.rowRange(0, 3).col(3); cv::Mat tCurrentFrame = currentFrame.mTcw.rowRange(0, 3).col(3); cv::Mat nMPRefFrame = mp - tRefFrame; cv::Mat nMPCurrentFrame = mp - tCurrentFrame; double dotProduct = nMPRefFrame.dot(nMPCurrentFrame); double normMPRefFrame = cv::norm(nMPRefFrame, cv::NORM_L2); double normMPCurrentFrame = cv::norm(nMPCurrentFrame, cv::NORM_L2); double angle = acos(dotProduct / (normMPRefFrame * normMPCurrentFrame)) * 180 / M_PI; if (angle < mParallaxThreshold) { _vMPw.at<float>(0, h) = vMPw.at<float>(0, j); _vMPw.at<float>(1, h) = vMPw.at<float>(1, j); _vMPw.at<float>(2, h) = vMPw.at<float>(2, j); _vMPw.at<float>(3, h) = vMPw.at<float>(3, j); _vLabels.at<float>(h, 0) = vLabels.at<float>(j, 0); _matRefFrame.at<float>(h, 0) = matRefFrame.at<float>(j, 0); _matRefFrame.at<float>(h, 1) = matRefFrame.at<float>(j, 1); _matRefFrame.at<float>(h, 2) = matRefFrame.at<float>(j, 2); _matDepthRefFrame.at<float>(h, 0) = matDepthRefFrame.at<float>(j, 0); h++; } }以下是代码的 详细解释 :
综上所述,该部分代码的主要目的是通过计算特征点之间的角度,并根据视差阈值对这些特征点进行筛选。被筛选出的特征点和相关数据将存储在新的矩阵中,供后续处理使用。
vMPw = _vMPw.colRange(0, h); vLabels = _vLabels.rowRange(0, h); matRefFrame = _matRefFrame.rowRange(0, h); matDepthRefFrame = _matDepthRefFrame.rowRange(0, h); if (vAllMPw.empty()) { vAllMPw = vMPw; vAllMatRefFrame = matRefFrame; vAllLabels = vLabels; vAllDepthRefFrame = matDepthRefFrame; } else { if (!vMPw.empty()) { hconcat(vAllMPw, vMPw, vAllMPw); vconcat(vAllMatRefFrame, matRefFrame, vAllMatRefFrame); vconcat(vAllLabels, vLabels, vAllLabels); vconcat(vAllDepthRefFrame, matDepthRefFrame, vAllDepthRefFrame); } }这段代码是根据之前的筛选结果将不同变量的数据合并到一个整体的数据集中。以下是代码的解释:
综上所述,这段代码的作用是将之前筛选出来的特征点和相关的数据合并到一个整体的数据集中,以便进行后续处理或分析。
cv::Mat vLabels = vAllLabels; if (!vAllMPw.empty()) { cv::Mat vMPCurrentFrame = currentFrame.mTcw * vAllMPw; // Divide by last column for (int i(0); i < vMPCurrentFrame.cols; i++) { vMPCurrentFrame.at<float>(0, i) /= vMPCurrentFrame.at<float>(3, i); vMPCurrentFrame.at<float>(1, i) /= vMPCurrentFrame.at<float>(3, i); vMPCurrentFrame.at<float>(2, i) /= vMPCurrentFrame.at<float>(3, i); vMPCurrentFrame.at<float>(3, i) /= vMPCurrentFrame.at<float>(3, i); } cv::Mat matProjDepth = vMPCurrentFrame.row(2); cv::Mat _vMPCurrentFrame = cv::Mat(vMPCurrentFrame.size(), CV_32F); cv::Mat _vAllMatRefFrame = cv::Mat(vAllMatRefFrame.size(), CV_32F); cv::Mat _vLabels = cv::Mat(vLabels.size(), CV_32F); cv::Mat __vAllDepthRefFrame = cv::Mat(vAllDepthRefFrame.size(), CV_32F); int h(0); cv::Mat __matProjDepth = cv::Mat(matProjDepth.size(), CV_32F);这段代码的作用如下:
总体而言,这段代码主要完成了以下功能:根据保存的变换矩阵将之前筛选出来的特征点位置矩阵 vAllMPw 进行变换,然后进行归一化处理,并提取 深度 信息。同时,创建了一些新的 cv::Mat 变量,用于存储相应的数据。
for (int i(0); i < matProjDepth.cols; i++) { if (matProjDepth.at<float>(0, i) < 7) { __matProjDepth.at<float>(0, h) = matProjDepth.at<float>(0, i); _vMPCurrentFrame.at<float>(0, h) = vMPCurrentFrame.at<float>(0, i); _vMPCurrentFrame.at<float>(1, h) = vMPCurrentFrame.at<float>(1, i); _vMPCurrentFrame.at<float>(2, h) = vMPCurrentFrame.at<float>(2, i); _vMPCurrentFrame.at<float>(3, h) = vMPCurrentFrame.at<float>(3, i); _vAllMatRefFrame.at<float>(h, 0) = vAllMatRefFrame.at<float>(i, 0); _vAllMatRefFrame.at<float>(h, 1) = vAllMatRefFrame.at<float>(i, 1); _vAllMatRefFrame.at<float>(h, 2) = vAllMatRefFrame.at<float>(i, 2); _vLabels.at<float>(h, 0) = vLabels.at<float>(i, 0); __vAllDepthRefFrame.at<float>(h, 0) = vAllDepthRefFrame.at<float>(i, 0); h++; } }这段代码是一个循环,遍历了matProjDepth矩阵的每一列。
在循环的每次迭代中,首先检查matProjDepth矩阵的当前列(index为i)的值是否小于7。如果满足这个条件,那么执行以下操作:
总体来说,这段代码的目的是根据matProjDepth矩阵的值来筛选和复制相关的数据到不同的矩阵和向量中。具体的选择和复制依赖于满足条件的元素的位置。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删