matProjDepth = __matProjDepth.colRange(0, h); vMPCurrentFrame = _vMPCurrentFrame.colRange(0, h); vAllMatRefFrame = _vAllMatRefFrame.rowRange(0, h); vLabels = _vLabels.rowRange(0, h); vAllDepthRefFrame = __vAllDepthRefFrame.rowRange(0, h); cv::Mat aux; cv::hconcat(cv::Mat::eye(3, 3, CV_32F), cv::Mat::zeros(3, 1, CV_32F), aux); cv::Mat matCurrentFrame = K * aux * vMPCurrentFrame; cv::Mat mat2CurrentFrame(matCurrentFrame.cols, 2, CV_32F); cv::Mat v2AllMatRefFrame(matCurrentFrame.cols, 3, CV_32F); cv::Mat mat2ProjDepth(matCurrentFrame.cols, 1, CV_32F); cv::Mat v2Labels(matCurrentFrame.cols, 1, CV_32F); cv::Mat _vAllDepthRefFrame(matCurrentFrame.cols, 1, CV_32F); int j = 0; for (int i(0); i < matCurrentFrame.cols; i++) { float x = ceil(matCurrentFrame.at<float>(0, i) / matCurrentFrame.at<float>(2, i)); float y = ceil(matCurrentFrame.at<float>(1, i) / matCurrentFrame.at<float>(2, i)); if (IsInFrame(x, y, currentFrame)) { const float d = currentFrame.mImDepth.at<float>(y, x); if (d > 0) { mat2CurrentFrame.at<float>(j, 0) = x; mat2CurrentFrame.at<float>(j, 1) = y; v2AllMatRefFrame.at<float>(j, 0) = vAllMatRefFrame.at<float>(i, 0); v2AllMatRefFrame.at<float>(j, 1) = vAllMatRefFrame.at<float>(i, 1); v2AllMatRefFrame.at<float>(j, 2) = vAllMatRefFrame.at<float>(i, 2); _vAllDepthRefFrame.at<float>(j, 0) = vAllDepthRefFrame.at<float>(i, 0); float d1 = matProjDepth.at<float>(0, i); mat2ProjDepth.at<float>(j, 0) = d1; v2Labels.at<float>(j, 0) = vLabels.at<float>(i, 0); j++; } } }这段代码的主要作用是根据之前代码段中的筛选和复制操作后得到的数据,对一些新的矩阵进行初始化和 赋值 。
具体解释如下:
matProjDepth = __matProjDepth.colRange(0, h);:将之前 _matProjDepth 矩阵中的列范围从0到h的部分复制给 matProjDepth 矩阵。vMPCurrentFrame = _vMPCurrentFrame.colRange(0, h);:将之前 _vMPCurrentFrame 矩阵中的列范围从0到h的部分复制给 vMPCurrentFrame 矩阵。vAllMatRefFrame = _vAllMatRefFrame.rowRange(0, h);:将之前 _vAllMatRefFrame 矩阵中的行范围从0到h的部分复制给 vAllMatRefFrame 矩阵。vLabels = _vLabels.rowRange(0, h);:将之前 _vLabels 矩阵中的行范围从0到h的部分复制给 vLabels 矩阵。vAllDepthRefFrame = __vAllDepthRefFrame.rowRange(0, h);:将之前 __vAllDepthRefFrame 矩阵中的行范围从0到h的部分复制给 vAllDepthRefFrame 矩阵。这些操作是为了截取之前复制并筛选的矩阵的有效范围。
接下来,代码创建了几个新的矩阵并进行了初始化:
aux 矩阵是一个3×4的矩阵,通过在3×3的单位矩阵右边添加一个3×1的零矩阵得到。matCurrentFrame 矩阵通过将矩阵 aux 与矩阵 vMPCurrentFrame 相乘,并再次与矩阵 K 相乘得到。mat2CurrentFrame 矩阵是一个大小为 matCurrentFrame 列数×2的矩阵。v2AllMatRefFrame 矩阵是一个大小为 matCurrentFrame 列数×3的矩阵。mat2ProjDepth 矩阵是一个大小为 matCurrentFrame 列数×1的矩阵。v2Labels 矩阵是一个大小为 matCurrentFrame 列数×1的矩阵。_vAllDepthRefFrame 矩阵是一个大小为 matCurrentFrame 列数×1的矩阵。
循环,根据一些条件筛选和赋值操作,通过将符合条件的数据从一个矩阵复制到另外一些矩阵中。
具体的解释如下:
int j = 0;:初始化一个变量 j 为 0,用于记录符合条件数据的索引。for (int i(0); i < matCurrentFrame.cols; i++):循环遍历 matCurrentFrame 矩阵的列数,i 从 0 开始递增。float x = ceil(matCurrentFrame.at<float>(0, i) / matCurrentFrame.at<float>(2, i));:计算将 matCurrentFrame 矩阵第一行第 i 列的值除以第三行第 i 列的值,并向上取整,得到 x 坐标。float y = ceil(matCurrentFrame.at<float>(1, i) / matCurrentFrame.at<float>(2, i));:计算将 matCurrentFrame 矩阵第二行第 i 列的值除以第三行第 i 列的值,并向上取整,得到 y 坐标。if (IsInFrame(x, y, currentFrame)):判断坐标 (x, y) 是否在 currentFrame 的帧范围内。这段代码的目的是根据条件筛选并复制符合条件的数据到新的矩阵中,以便进行后续处理和计算。
vAllDepthRefFrame = _vAllDepthRefFrame.rowRange(0, j); vAllMatRefFrame = v2AllMatRefFrame.rowRange(0, j); matProjDepth = mat2ProjDepth.rowRange(0, j); matCurrentFrame = mat2CurrentFrame.rowRange(0, j); vLabels = v2Labels.rowRange(0, j); cv::Mat u1((2 * mDmax + 1) * (2 * mDmax + 1), 2, CV_32F); int m(0); for (int i(-mDmax); i <= mDmax; i++) { for (int j(-mDmax); j <= mDmax; j++) { u1.at<float>(m, 0) = i; u1.at<float>(m, 1) = j; m++; } }
这段代码涉及到一些矩阵操作和循环。
具体的解释如下:
vAllDepthRefFrame = _vAllDepthRefFrame.rowRange(0, j);:将 _vAllDepthRefFrame 矩阵的前 j 行(索引从 0 到 j-1)复制给 vAllDepthRefFrame 矩阵。vAllMatRefFrame = v2AllMatRefFrame.rowRange(0, j);:将 v2AllMatRefFrame 矩阵的前 j 行复制给 vAllMatRefFrame 矩阵。matProjDepth = mat2ProjDepth.rowRange(0, j);:将 mat2ProjDepth 矩阵的前 j 行复制给 matProjDepth 矩阵。matCurrentFrame = mat2CurrentFrame.rowRange(0, j);:将 mat2CurrentFrame 矩阵的前 j 行复制给 matCurrentFrame 矩阵。vLabels = v2Labels.rowRange(0, j);:将 v2Labels 矩阵的前 j 行复制给 vLabels 矩阵。cv::Mat u1((2 * mDmax + 1) * (2 * mDmax + 1), 2, CV_32F);:创建一个 CV_32F 类型的矩阵 u1,其行数为 (2 * mDmax + 1) * (2 * mDmax + 1),列数为 2。int m(0);:初始化一个变量 m 为 0,用于记录索引。for (int i(-mDmax); i <= mDmax; i++):循环遍历 i,从 -mDmax 开始,每次增加 1,直到 mDmax。这段代码的目的是根据一些参数和条件,进行矩阵操作、数据筛选和数值赋值。最后,在一个循环中生成一个新的矩阵 u1,其中的值根据循环变量 i 和 j 的值依次进行赋值。
cv::Mat matDepthCurrentFrame(matCurrentFrame.rows, 1, CV_32F); cv::Mat _matProjDepth(matCurrentFrame.rows, 1, CV_32F); cv::Mat _matCurrentFrame(matCurrentFrame.rows, 2, CV_32F); int _s(0); for (int i(0); i < matCurrentFrame.rows; i++) { int s(0); cv::Mat _matDiffDepth(u1.rows, 1, CV_32F); cv::Mat _matDepth(u1.rows, 1, CV_32F); for (int j(0); j < u1.rows; j++) { int x = (int)matCurrentFrame.at<float>(i, 0) + (int)u1.at<float>(j, 0); int y = (int)matCurrentFrame.at<float>(i, 1) + (int)u1.at<float>(j, 1); float _d = currentFrame.mImDepth.at<float>(y, x); if ((_d > 0) && (_d < matProjDepth.at<float>(i, 0))) { _matDepth.at<float>(s, 0) = _d; _matDiffDepth.at<float>(s, 0) = matProjDepth.at<float>(i, 0) - _d; s++; } } if (s > 0) { _matDepth = _matDepth.rowRange(0, s); _matDiffDepth = _matDiffDepth.rowRange(0, s); double minVal, maxVal; cv::Point minIdx, maxIdx; cv::minMaxLoc(_matDiffDepth, &minVal, &maxVal, &minIdx, &maxIdx); int xIndex = minIdx.x; int yIndex = minIdx.y; matDepthCurrentFrame.at<float>(_s, 0) = _matDepth.at<float>(yIndex, 0); _matProjDepth.at<float>(_s, 0) = matProjDepth.at<float>(i, 0); _matCurrentFrame.at<float>(_s, 0) = matCurrentFrame.at<float>(i, 0); _matCurrentFrame.at<float>(_s, 1) = matCurrentFrame.at<float>(i, 1); _s++; } }
这段代码执行了一些计算,涉及到矩阵的操作、条件判断和循环。
具体的解释如下:
cv::Mat matDepthCurrentFrame(matCurrentFrame.rows, 1, CV_32F);:创建一个大小为 matCurrentFrame.rows 行 1 列的浮点型矩阵 matDepthCurrentFrame。cv::Mat _matProjDepth(matCurrentFrame.rows, 1, CV_32F);:创建一个大小为 matCurrentFrame.rows 行 1 列的浮点型矩阵 _matProjDepth。cv::Mat _matCurrentFrame(matCurrentFrame.rows, 2, CV_32F);:创建一个大小为 matCurrentFrame.rows 行 2 列的浮点型矩阵 _matCurrentFrame。以上步骤是为了创建存储结果的矩阵。
int _s(0);:初始化一个变量 _s 为 0,用于记录索引。for (int i(0); i < matCurrentFrame.rows; i++):循环遍历 i,从 0 开始,逐个增加,直到 matCurrentFrame 矩阵的行数。这段代码的目的是根据一些条件和数据进行筛选和计算,从而得到最终的结果矩阵和索引值。
matDepthCurrentFrame = matDepthCurrentFrame.rowRange(0, _s); matProjDepth = _matProjDepth.rowRange(0, _s); matCurrentFrame = _matCurrentFrame.rowRange(0, _s); mDepthThreshold = 0.6; cv::Mat matDepthDifference = matProjDepth - matDepthCurrentFrame; mVarThreshold = 0.001; // 0.040; vector<Geometry::DynKeyPoint> vDynPoints; for (int i(0); i < matCurrentFrame.rows; i++) { if (matDepthDifference.at<float>(i, 0) > mDepthThreshold) { int xIni = (int)matCurrentFrame.at<float>(i, 0) - mDmax; int yIni = (int)matCurrentFrame.at<float>(i, 1) - mDmax; int xEnd = (int)matCurrentFrame.at<float>(i, 0) + mDmax + 1; int yEnd = (int)matCurrentFrame.at<float>(i, 1) + mDmax + 1; cv::Mat patch = currentFrame.mImDepth.rowRange(yIni, yEnd).colRange(xIni, xEnd); cv::Mat mean, stddev; cv::meanStdDev(patch, mean, stddev); double _stddev = stddev.at<double>(0, 0); double var = _stddev * _stddev; if (var < mVarThreshold) { DynKeyPoint dynPoint; dynPoint.mPoint.x = matCurrentFrame.at<float>(i, 0); dynPoint.mPoint.y = matCurrentFrame.at<float>(i, 1); dynPoint.mRefFrameLabel = vLabels.at<float>(i, 0); vDynPoints.push_back(dynPoint); } } } return vDynPoints; } else { vector<Geometry::DynKeyPoint> vDynPoints; return vDynPoints; } }这段代码是一个函数,根据给定的输入参数进行深度图像处理,并返回动态关键点的向量。
函数首先对一些变量进行初始化,包括matDepthCurrentFrame、matProjDepth和matCurrentFrame(这些都是OpenCV的cv::Mat对象)。然后,定义了一些阈值(mDepthThreshold和mVarThreshold)。
接下来,通过对matProjDepth和matDepthCurrentFrame进行减法操作,计算了matDepthDifference。然后,使用一个循环遍历matCurrentFrame的每一行。
在循环中,首先检查matDepthDifference当前行的第一个元素是否大于mDepthThreshold。如果是,则进一步处理该点。
然后,根据matCurrentFrame当前行的前两个元素(即坐标)计算出一个矩形区域,并提取当前帧的深度图像中对应区域的一个小块(patch)。
接下来,使用cv::meanStdDev函数计算patch的均值和标准差,并根据标准差计算方差(var)。
最后,如果方差小于mVarThreshold,则创建一个DynKeyPoint对象,将相关信息(包括位置和参考帧标签)存储在其中,并将该对象添加到vDynPoints向量中。
最后,在函数的末尾,如果输入参数不满足某些条件(判断条件看不到提供的完整代码部分),则返回一个空的vDynPoints向量。
综上所述,该函数的作用是从给定的深度图像中提取满足一定条件的动态关键点,并将这些关键点以DynKeyPoint对象的形式存储在一个向量中返回。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删