mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge pull request #22598 from savuor:icp_oframe_readonly
Complement PR: #3366@contrib
Changes
OdometryFrame losts its getters: a user can provide data at construction stage only, pyramids and other generated data is read-only now
OdometryFrame is based on UMats: no TMat templates inside, CPU operations are done with UMat::getMat() method, chaining issues are solved ad-hoc
No more Odometry::createOdometryFrame() method, frames are compatible with all odometry algorithms
Normals computer is cached inside Odometry and exposed to API as well as its settings
Volume::raycast() won't return the result in OdometryFrame anymore
Added test for Odometry::prepareFrame*() & other test fixes
Minor code improvements
TODOs:
fix TODOs in code
lower acceptable accuracy errors
This commit is contained in:
committed by
GitHub
parent
8358efaca1
commit
8b7e586faa
@@ -358,8 +358,7 @@ void normal_test_custom_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
Mat points, normals;
|
||||
AccessFlag af = ACCESS_READ;
|
||||
|
||||
OdometryFrame odf(OdometryFrameStoreType::UMAT);
|
||||
odf.setDepth(udepth);
|
||||
OdometryFrame odf(noArray(), udepth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
volume.integrate(depth, poses[0].matrix);
|
||||
@@ -368,24 +367,15 @@ void normal_test_custom_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
|
||||
if (testFunction == VolumeTestFunction::RAYCAST)
|
||||
{
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, upoints, unormals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, odf);
|
||||
odf.getPyramidAt(upoints, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(unormals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
}
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, upoints, unormals);
|
||||
}
|
||||
else if (testFunction == VolumeTestFunction::FETCH_NORMALS)
|
||||
{
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
// takes only point from raycast for checking fetched normals on the display
|
||||
volume.raycast(poses[0].matrix, frameSize.height,frameSize.width, upoints, utmpnormals);
|
||||
//volume.fetchPointsNormals(upoints, utmpnormals);
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, upoints, utmpnormals);
|
||||
// volume.fetchPointsNormals(upoints, utmpnormals);
|
||||
volume.fetchNormals(upoints, unormals);
|
||||
}
|
||||
}
|
||||
@@ -427,8 +417,7 @@ void normal_test_common_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
Mat points, normals;
|
||||
AccessFlag af = ACCESS_READ;
|
||||
|
||||
OdometryFrame odf(OdometryFrameStoreType::UMAT);
|
||||
odf.setDepth(udepth);
|
||||
OdometryFrame odf(noArray(), udepth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
volume.integrate(depth, poses[0].matrix);
|
||||
@@ -437,16 +426,7 @@ void normal_test_common_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
|
||||
if (testFunction == VolumeTestFunction::RAYCAST)
|
||||
{
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, upoints, unormals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, odf);
|
||||
odf.getPyramidAt(upoints, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(unormals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
}
|
||||
}
|
||||
else if (testFunction == VolumeTestFunction::FETCH_NORMALS)
|
||||
{
|
||||
@@ -498,25 +478,14 @@ void valid_points_test_custom_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
AccessFlag af = ACCESS_READ;
|
||||
int anfas, profile;
|
||||
|
||||
OdometryFrame odf(OdometryFrameStoreType::UMAT);
|
||||
odf.setDepth(udepth);
|
||||
OdometryFrame odf(noArray(), udepth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
volume.integrate(depth, poses[0].matrix);
|
||||
else
|
||||
volume.integrate(odf, poses[0].matrix);
|
||||
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, upoints, unormals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, odf);
|
||||
odf.getPyramidAt(upoints, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(unormals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
}
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, upoints, unormals);
|
||||
|
||||
normals = unormals.getMat(af);
|
||||
points = upoints.getMat(af);
|
||||
@@ -526,16 +495,7 @@ void valid_points_test_custom_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
if (cvtest::debugLevel > 0)
|
||||
displayImage(depth, points, normals, depthFactor, lightPose);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, upoints1, unormals1);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, odf);
|
||||
odf.getPyramidAt(upoints1, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(unormals1, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
}
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, upoints1, unormals1);
|
||||
|
||||
normals = unormals1.getMat(af);
|
||||
points = upoints1.getMat(af);
|
||||
@@ -576,25 +536,14 @@ void valid_points_test_common_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
AccessFlag af = ACCESS_READ;
|
||||
int anfas, profile;
|
||||
|
||||
OdometryFrame odf(OdometryFrameStoreType::UMAT);
|
||||
odf.setDepth(udepth);
|
||||
OdometryFrame odf(noArray(), udepth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
volume.integrate(depth, poses[0].matrix);
|
||||
else
|
||||
volume.integrate(odf, poses[0].matrix);
|
||||
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
volume.raycast(poses[0].matrix, upoints, unormals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, odf);
|
||||
odf.getPyramidAt(upoints, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(unormals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
}
|
||||
volume.raycast(poses[0].matrix, upoints, unormals);
|
||||
|
||||
normals = unormals.getMat(af);
|
||||
points = upoints.getMat(af);
|
||||
@@ -604,19 +553,10 @@ void valid_points_test_common_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
if (cvtest::debugLevel > 0)
|
||||
displayImage(depth, points, normals, depthFactor, lightPose);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
volume.raycast(poses[17].matrix, upoints1, unormals1);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[17].matrix, odf);
|
||||
odf.getPyramidAt(upoints1, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(unormals1, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
}
|
||||
volume.raycast(poses[17].matrix, upoints1, unormals1);
|
||||
|
||||
normals = unormals1.getMat(af);
|
||||
points = upoints1.getMat(af);
|
||||
points = upoints1.getMat(af);
|
||||
patchNaNs(points);
|
||||
profile = counterOfValid(points);
|
||||
|
||||
|
||||
@@ -625,7 +625,7 @@ TEST_P(RenderedNormals, check)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(RGBD_Normals, RenderedNormals, ::testing::Combine(::testing::Values(CV_32F, CV_64F),
|
||||
::testing::Values(
|
||||
NormalComputerThresholds { RgbdNormals::RGBD_NORMALS_METHOD_FALS, { 81.8210, 0}},
|
||||
NormalComputerThresholds { RgbdNormals::RGBD_NORMALS_METHOD_FALS, { 81.8213, 0}},
|
||||
NormalComputerThresholds { RgbdNormals::RGBD_NORMALS_METHOD_LINEMOD, { 107.2710, 29168}},
|
||||
NormalComputerThresholds { RgbdNormals::RGBD_NORMALS_METHOD_SRI, { 73.2027, 17693}},
|
||||
NormalComputerThresholds { RgbdNormals::RGBD_NORMALS_METHOD_CROSS_PRODUCT, { 57.9832, 2531}}),
|
||||
|
||||
@@ -136,18 +136,17 @@ void OdometryTest::checkUMats()
|
||||
Mat image, depth;
|
||||
readData(image, depth);
|
||||
|
||||
OdometrySettings ods;
|
||||
ods.setCameraMatrix(K);
|
||||
Odometry odometry = Odometry(otype, ods, algtype);
|
||||
OdometryFrame odf = odometry.createOdometryFrame(OdometryFrameStoreType::UMAT);
|
||||
|
||||
Mat calcRt;
|
||||
|
||||
UMat uimage, udepth;
|
||||
image.copyTo(uimage);
|
||||
depth.copyTo(udepth);
|
||||
odf.setImage(uimage);
|
||||
odf.setDepth(udepth);
|
||||
|
||||
OdometrySettings ods;
|
||||
ods.setCameraMatrix(K);
|
||||
Odometry odometry = Odometry(otype, ods, algtype);
|
||||
OdometryFrame odf(uimage, udepth);
|
||||
|
||||
Mat calcRt;
|
||||
|
||||
uimage.release();
|
||||
udepth.release();
|
||||
|
||||
@@ -155,7 +154,7 @@ void OdometryTest::checkUMats()
|
||||
bool isComputed = odometry.compute(odf, odf, calcRt);
|
||||
ASSERT_TRUE(isComputed);
|
||||
double diff = cv::norm(calcRt, Mat::eye(4, 4, CV_64FC1));
|
||||
ASSERT_FALSE(diff > idError) << "Incorrect transformation between the same frame (not the identity matrix), diff = " << diff << std::endl;
|
||||
ASSERT_LE(diff, idError) << "Incorrect transformation between the same frame (not the identity matrix)" << std::endl;
|
||||
}
|
||||
|
||||
void OdometryTest::run()
|
||||
@@ -167,9 +166,7 @@ void OdometryTest::run()
|
||||
OdometrySettings ods;
|
||||
ods.setCameraMatrix(K);
|
||||
Odometry odometry = Odometry(otype, ods, algtype);
|
||||
OdometryFrame odf = odometry.createOdometryFrame();
|
||||
odf.setImage(image);
|
||||
odf.setDepth(depth);
|
||||
OdometryFrame odf(image, depth);
|
||||
Mat calcRt;
|
||||
|
||||
// 1. Try to find Rt between the same frame (try masks also).
|
||||
@@ -180,7 +177,7 @@ void OdometryTest::run()
|
||||
|
||||
ASSERT_TRUE(isComputed) << "Can not find Rt between the same frame" << std::endl;
|
||||
double ndiff = cv::norm(calcRt, Mat::eye(4,4,CV_64FC1));
|
||||
ASSERT_FALSE(ndiff > idError) << "Incorrect transformation between the same frame (not the identity matrix), diff = " << ndiff << std::endl;
|
||||
ASSERT_LE(ndiff, idError) << "Incorrect transformation between the same frame (not the identity matrix)" << std::endl;
|
||||
|
||||
// 2. Generate random rigid body motion in some ranges several times (iterCount).
|
||||
// On each iteration an input frame is warped using generated transformation.
|
||||
@@ -202,13 +199,8 @@ void OdometryTest::run()
|
||||
warpFrame(depth, image, noArray(), rt.matrix, K, warpedDepth, warpedImage);
|
||||
dilateFrame(warpedImage, warpedDepth); // due to inaccuracy after warping
|
||||
|
||||
OdometryFrame odfSrc = odometry.createOdometryFrame();
|
||||
OdometryFrame odfDst = odometry.createOdometryFrame();
|
||||
|
||||
odfSrc.setImage(image);
|
||||
odfSrc.setDepth(depth);
|
||||
odfDst.setImage(warpedImage);
|
||||
odfDst.setDepth(warpedDepth);
|
||||
OdometryFrame odfSrc(image, depth);
|
||||
OdometryFrame odfDst(warpedImage, warpedDepth);
|
||||
|
||||
odometry.prepareFrames(odfSrc, odfDst);
|
||||
isComputed = odometry.compute(odfSrc, odfDst, calcRt);
|
||||
@@ -235,7 +227,7 @@ void OdometryTest::run()
|
||||
}
|
||||
|
||||
// compare rotation
|
||||
double possibleError = algtype == OdometryAlgoType::COMMON ? 0.11f : 0.015f;
|
||||
double possibleError = algtype == OdometryAlgoType::COMMON ? 0.015f : 0.01f;
|
||||
|
||||
Affine3f src = Affine3f(Vec3f(rvec), Vec3f(tvec));
|
||||
Affine3f res = Affine3f(Vec3f(calcRvec), Vec3f(calcTvec));
|
||||
@@ -275,44 +267,178 @@ void OdometryTest::prepareFrameCheck()
|
||||
{
|
||||
Mat K = getCameraMatrix();
|
||||
|
||||
Mat image, depth;
|
||||
readData(image, depth);
|
||||
Mat gtImage, gtDepth;
|
||||
readData(gtImage, gtDepth);
|
||||
OdometrySettings ods;
|
||||
ods.setCameraMatrix(K);
|
||||
Odometry odometry = Odometry(otype, ods, algtype);
|
||||
OdometryFrame odf = odometry.createOdometryFrame();
|
||||
odf.setImage(image);
|
||||
odf.setDepth(depth);
|
||||
OdometryFrame odf(gtImage, gtDepth);
|
||||
|
||||
odometry.prepareFrame(odf);
|
||||
|
||||
Mat points, mask;
|
||||
odf.getPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(mask, OdometryFramePyramidType::PYR_MASK, 0);
|
||||
std::vector<int> iters;
|
||||
ods.getIterCounts(iters);
|
||||
size_t nlevels = iters.size();
|
||||
|
||||
OdometryFrame todf = odometry.createOdometryFrame();
|
||||
if (otype != OdometryType::DEPTH)
|
||||
Mat points, mask, depth, gray, rgb, scaled;
|
||||
|
||||
odf.getMask(mask);
|
||||
int masknz = countNonZero(mask);
|
||||
ASSERT_GT(masknz, 0);
|
||||
|
||||
odf.getDepth(depth);
|
||||
Mat patchedDepth = depth.clone();
|
||||
patchNaNs(patchedDepth, 0);
|
||||
int depthnz = countNonZero(patchedDepth);
|
||||
double depthNorm = cv::norm(depth, gtDepth, NORM_INF, mask);
|
||||
ASSERT_LE(depthNorm, 0.0);
|
||||
|
||||
Mat gtGray;
|
||||
if (otype == OdometryType::RGB || otype == OdometryType::RGB_DEPTH)
|
||||
{
|
||||
Mat img;
|
||||
odf.getPyramidAt(img, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
todf.setPyramidLevel(1, OdometryFramePyramidType::PYR_IMAGE);
|
||||
todf.setPyramidAt(img, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
}
|
||||
todf.setPyramidLevel(1, OdometryFramePyramidType::PYR_CLOUD);
|
||||
todf.setPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
todf.setPyramidLevel(1, OdometryFramePyramidType::PYR_MASK);
|
||||
todf.setPyramidAt(mask, OdometryFramePyramidType::PYR_MASK, 0);
|
||||
odf.getGrayImage(gray);
|
||||
odf.getImage(rgb);
|
||||
double rgbNorm = cv::norm(rgb, gtImage);
|
||||
ASSERT_LE(rgbNorm, 0.0);
|
||||
|
||||
odometry.prepareFrame(todf);
|
||||
if (gtImage.channels() == 3)
|
||||
cvtColor(gtImage, gtGray, COLOR_BGR2GRAY);
|
||||
else
|
||||
gtGray = gtImage;
|
||||
gtGray.convertTo(gtGray, CV_8U);
|
||||
double grayNorm = cv::norm(gray, gtGray);
|
||||
ASSERT_LE(grayNorm, 0.0);
|
||||
}
|
||||
|
||||
//TODO: remove it when scale issue is fixed
|
||||
odf.getScaledDepth(scaled);
|
||||
int scalednz = countNonZero(scaled);
|
||||
EXPECT_EQ(scalednz, depthnz);
|
||||
|
||||
std::vector<Mat> gtPyrDepth, gtPyrMask;
|
||||
//TODO: this depth calculation would become incorrect when we implement bilateral filtering, fixit
|
||||
buildPyramid(gtDepth, gtPyrDepth, nlevels - 1);
|
||||
for (const auto& gd : gtPyrDepth)
|
||||
{
|
||||
Mat pm = (gd > ods.getMinDepth()) & (gd < ods.getMaxDepth());
|
||||
gtPyrMask.push_back(pm);
|
||||
}
|
||||
|
||||
size_t npyr = odf.getPyramidLevels();
|
||||
ASSERT_EQ(npyr, nlevels);
|
||||
Matx33f levelK = K;
|
||||
for (size_t i = 0; i < nlevels; i++)
|
||||
{
|
||||
Mat depthi, cloudi, maski;
|
||||
|
||||
odf.getPyramidAt(maski, OdometryFramePyramidType::PYR_MASK, i);
|
||||
ASSERT_FALSE(maski.empty());
|
||||
double mnorm = cv::norm(maski, gtPyrMask[i]);
|
||||
EXPECT_LE(mnorm, 16 * 255.0) << "Mask diff is too big at pyr level " << i;
|
||||
|
||||
odf.getPyramidAt(depthi, OdometryFramePyramidType::PYR_DEPTH, i);
|
||||
ASSERT_FALSE(depthi.empty());
|
||||
double dnorm = cv::norm(depthi, gtPyrDepth[i], NORM_INF, maski);
|
||||
EXPECT_LE(dnorm, 8.e-7) << "Depth diff norm is too big at pyr level " << i;
|
||||
|
||||
odf.getPyramidAt(cloudi, OdometryFramePyramidType::PYR_CLOUD, i);
|
||||
ASSERT_FALSE(cloudi.empty());
|
||||
Mat gtCloud;
|
||||
depthTo3d(depthi, levelK, gtCloud);
|
||||
double cnorm = cv::norm(cloudi, gtCloud, NORM_INF, maski);
|
||||
EXPECT_LE(cnorm, 0.0) << "Cloud diff norm is too big at pyr level " << i;
|
||||
// downscale camera matrix for next pyramid level
|
||||
levelK = 0.5f * levelK;
|
||||
levelK(2, 2) = 1.f;
|
||||
}
|
||||
|
||||
if (otype == OdometryType::RGB || otype == OdometryType::RGB_DEPTH)
|
||||
{
|
||||
std::vector<Mat> gtPyrImage;
|
||||
buildPyramid(gtGray, gtPyrImage, nlevels - 1);
|
||||
|
||||
for (size_t i = 0; i < nlevels; i++)
|
||||
{
|
||||
Mat rgbi, texi, dixi, diyi, maski;
|
||||
odf.getPyramidAt(maski, OdometryFramePyramidType::PYR_MASK, i);
|
||||
odf.getPyramidAt(rgbi, OdometryFramePyramidType::PYR_IMAGE, i);
|
||||
ASSERT_FALSE(rgbi.empty());
|
||||
double rnorm = cv::norm(rgbi, gtPyrImage[i], NORM_INF);
|
||||
EXPECT_LE(rnorm, 1.0) << "RGB diff is too big at pyr level " << i;
|
||||
odf.getPyramidAt(texi, OdometryFramePyramidType::PYR_TEXMASK, i);
|
||||
ASSERT_FALSE(texi.empty());
|
||||
int tnz = countNonZero(texi);
|
||||
EXPECT_GE(tnz, 1000) << "Texture mask has too few valid pixels at pyr level " << i;
|
||||
Mat gtDixi, gtDiyi;
|
||||
Sobel(rgbi, gtDixi, CV_16S, 1, 0, ods.getSobelSize());
|
||||
odf.getPyramidAt(dixi, OdometryFramePyramidType::PYR_DIX, i);
|
||||
ASSERT_FALSE(dixi.empty());
|
||||
double dixnorm = cv::norm(dixi, gtDixi, NORM_INF, maski);
|
||||
EXPECT_LE(dixnorm, 0) << "dI/dx diff is too big at pyr level " << i;
|
||||
Sobel(rgbi, gtDiyi, CV_16S, 0, 1, ods.getSobelSize());
|
||||
odf.getPyramidAt(diyi, OdometryFramePyramidType::PYR_DIY, i);
|
||||
ASSERT_FALSE(diyi.empty());
|
||||
double diynorm = cv::norm(diyi, gtDiyi, NORM_INF, maski);
|
||||
EXPECT_LE(diynorm, 0) << "dI/dy diff is too big at pyr level " << i;
|
||||
}
|
||||
}
|
||||
|
||||
if (otype == OdometryType::DEPTH || otype == OdometryType::RGB_DEPTH)
|
||||
{
|
||||
Ptr<RgbdNormals> normalComputer = odometry.getNormalsComputer();
|
||||
ASSERT_FALSE(normalComputer.empty());
|
||||
Mat normals;
|
||||
odf.getNormals(normals);
|
||||
std::vector<Mat> gtPyrNormals;
|
||||
buildPyramid(normals, gtPyrNormals, nlevels - 1);
|
||||
for (size_t i = 0; i < nlevels; i++)
|
||||
{
|
||||
Mat gtNormal = gtPyrNormals[i];
|
||||
CV_Assert(gtNormal.type() == CV_32FC4);
|
||||
for (int y = 0; y < gtNormal.rows; y++)
|
||||
{
|
||||
Vec4f *normals_row = gtNormal.ptr<Vec4f>(y);
|
||||
for (int x = 0; x < gtNormal.cols; x++)
|
||||
{
|
||||
Vec4f n4 = normals_row[x];
|
||||
Point3f n(n4[0], n4[1], n4[2]);
|
||||
double nrm = cv::norm(n);
|
||||
n *= 1.f / nrm;
|
||||
normals_row[x] = Vec4f(n.x, n.y, n.z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Mat normmaski;
|
||||
odf.getPyramidAt(normmaski, OdometryFramePyramidType::PYR_NORMMASK, i);
|
||||
ASSERT_FALSE(normmaski.empty());
|
||||
int nnm = countNonZero(normmaski);
|
||||
EXPECT_GE(nnm, 1000) << "Normals mask has too few valid pixels at pyr level " << i;
|
||||
|
||||
Mat ptsi;
|
||||
odf.getPyramidAt(ptsi, OdometryFramePyramidType::PYR_CLOUD, i);
|
||||
|
||||
Mat normi;
|
||||
odf.getPyramidAt(normi, OdometryFramePyramidType::PYR_NORM, i);
|
||||
ASSERT_FALSE(normi.empty());
|
||||
double nnorm = cv::norm(normi, gtNormal, NORM_INF, normmaski);
|
||||
EXPECT_LE(nnorm, 1.8e-7) << "Normals diff is too big at pyr level " << i;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
double pnnorm = cv::norm(normals, normi, NORM_INF, normmaski);
|
||||
EXPECT_GE(pnnorm, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* Tests registrations *
|
||||
\****************************************************************************************/
|
||||
|
||||
TEST(RGBD_Odometry_Rgbd, algorithmic)
|
||||
TEST(RGBD_Odometry_Rgb, algorithmic)
|
||||
{
|
||||
OdometryTest test(OdometryType::RGB, OdometryAlgoType::COMMON, 0.99, 0.89);
|
||||
OdometryTest test(OdometryType::RGB, OdometryAlgoType::COMMON, 0.99, 0.99);
|
||||
test.run();
|
||||
}
|
||||
|
||||
@@ -330,14 +456,14 @@ TEST(RGBD_Odometry_RgbdICP, algorithmic)
|
||||
|
||||
TEST(RGBD_Odometry_FastICP, algorithmic)
|
||||
{
|
||||
OdometryTest test(OdometryType::DEPTH, OdometryAlgoType::FAST, 0.99, 0.89, FLT_EPSILON);
|
||||
OdometryTest test(OdometryType::DEPTH, OdometryAlgoType::FAST, 0.99, 0.87, 1.84e-5);
|
||||
test.run();
|
||||
}
|
||||
|
||||
|
||||
TEST(RGBD_Odometry_Rgbd, UMats)
|
||||
TEST(RGBD_Odometry_Rgb, UMats)
|
||||
{
|
||||
OdometryTest test(OdometryType::RGB, OdometryAlgoType::COMMON, 0.99, 0.89);
|
||||
OdometryTest test(OdometryType::RGB, OdometryAlgoType::COMMON, 0.99, 0.99);
|
||||
test.checkUMats();
|
||||
}
|
||||
|
||||
@@ -355,14 +481,15 @@ TEST(RGBD_Odometry_RgbdICP, UMats)
|
||||
|
||||
TEST(RGBD_Odometry_FastICP, UMats)
|
||||
{
|
||||
OdometryTest test(OdometryType::DEPTH, OdometryAlgoType::FAST, 0.99, 0.89, FLT_EPSILON);
|
||||
// OpenCL version has slightly less accuracy than CPU version
|
||||
OdometryTest test(OdometryType::DEPTH, OdometryAlgoType::FAST, 0.99, 0.99, 1.84e-5);
|
||||
test.checkUMats();
|
||||
}
|
||||
|
||||
|
||||
TEST(RGBD_Odometry_Rgbd, prepareFrame)
|
||||
TEST(RGBD_Odometry_Rgb, prepareFrame)
|
||||
{
|
||||
OdometryTest test(OdometryType::RGB, OdometryAlgoType::COMMON, 0.99, 0.89);
|
||||
OdometryTest test(OdometryType::RGB, OdometryAlgoType::COMMON, 0.99, 0.99);
|
||||
test.prepareFrameCheck();
|
||||
}
|
||||
|
||||
@@ -380,7 +507,7 @@ TEST(RGBD_Odometry_RgbdICP, prepareFrame)
|
||||
|
||||
TEST(RGBD_Odometry_FastICP, prepareFrame)
|
||||
{
|
||||
OdometryTest test(OdometryType::DEPTH, OdometryAlgoType::FAST, 0.99, 0.89, FLT_EPSILON);
|
||||
OdometryTest test(OdometryType::DEPTH, OdometryAlgoType::FAST, 0.99, 0.99, FLT_EPSILON);
|
||||
test.prepareFrameCheck();
|
||||
}
|
||||
|
||||
|
||||
+28
-102
@@ -489,9 +489,7 @@ void normal_test_custom_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
Mat rgb = scene->rgb(poses[0]);
|
||||
Mat points, normals, tmpnormals, colors;
|
||||
|
||||
OdometryFrame odf;
|
||||
odf.setDepth(depth);
|
||||
odf.setImage(rgb);
|
||||
OdometryFrame odf(rgb, depth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
@@ -507,21 +505,10 @@ void normal_test_custom_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
|
||||
if (testFunction == VolumeTestFunction::RAYCAST)
|
||||
{
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, odf);
|
||||
odf.getPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(normals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
odf.getPyramidAt(colors, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
}
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals);
|
||||
}
|
||||
else if (testFunction == VolumeTestFunction::FETCH_NORMALS)
|
||||
{
|
||||
@@ -568,9 +555,7 @@ void normal_test_common_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
Mat rgb = scene->rgb(poses[0]);
|
||||
Mat points, normals, tmpnormals, colors;
|
||||
|
||||
OdometryFrame odf;
|
||||
odf.setDepth(depth);
|
||||
odf.setImage(rgb);
|
||||
OdometryFrame odf(rgb, depth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
@@ -586,21 +571,10 @@ void normal_test_common_framesize(VolumeType volumeType, VolumeTestFunction test
|
||||
|
||||
if (testFunction == VolumeTestFunction::RAYCAST)
|
||||
{
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, points, normals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, odf);
|
||||
odf.getPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(normals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
odf.getPyramidAt(colors, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
}
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, points, normals);
|
||||
}
|
||||
else if (testFunction == VolumeTestFunction::FETCH_NORMALS)
|
||||
{
|
||||
@@ -648,9 +622,7 @@ void valid_points_test_custom_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
Mat points, normals, colors, newPoints, newNormals;
|
||||
int anfas, profile;
|
||||
|
||||
OdometryFrame odf;
|
||||
odf.setDepth(depth);
|
||||
odf.setImage(rgb);
|
||||
OdometryFrame odf(rgb, depth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
@@ -664,21 +636,10 @@ void valid_points_test_custom_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
volume.integrate(odf, poses[0].matrix);
|
||||
}
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, odf);
|
||||
odf.getPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(normals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
odf.getPyramidAt(colors, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
}
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, points, normals);
|
||||
|
||||
patchNaNs(points);
|
||||
anfas = counterOfValid(points);
|
||||
@@ -694,21 +655,10 @@ void valid_points_test_custom_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
points.release();
|
||||
normals.release();
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, points, normals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, odf);
|
||||
odf.getPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(normals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
odf.getPyramidAt(colors, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
}
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, points, normals);
|
||||
|
||||
patchNaNs(points);
|
||||
profile = counterOfValid(points);
|
||||
@@ -748,9 +698,7 @@ void valid_points_test_common_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
Mat points, normals, colors, newPoints, newNormals;
|
||||
int anfas, profile;
|
||||
|
||||
OdometryFrame odf;
|
||||
odf.setDepth(depth);
|
||||
odf.setImage(rgb);
|
||||
OdometryFrame odf(rgb, depth);
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT)
|
||||
{
|
||||
@@ -764,21 +712,10 @@ void valid_points_test_common_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
volume.integrate(odf, poses[0].matrix);
|
||||
}
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, points, normals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[0].matrix, odf);
|
||||
odf.getPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(normals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
odf.getPyramidAt(colors, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
}
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[0].matrix, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[0].matrix, points, normals);
|
||||
|
||||
patchNaNs(points);
|
||||
anfas = counterOfValid(points);
|
||||
@@ -794,21 +731,10 @@ void valid_points_test_common_framesize(VolumeType volumeType, VolumeTestSrcType
|
||||
points.release();
|
||||
normals.release();
|
||||
|
||||
if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats
|
||||
{
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[17].matrix, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[17].matrix, points, normals);
|
||||
}
|
||||
else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME)
|
||||
{
|
||||
volume.raycast(poses[17].matrix, odf);
|
||||
odf.getPyramidAt(points, OdometryFramePyramidType::PYR_CLOUD, 0);
|
||||
odf.getPyramidAt(normals, OdometryFramePyramidType::PYR_NORM, 0);
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
odf.getPyramidAt(colors, OdometryFramePyramidType::PYR_IMAGE, 0);
|
||||
}
|
||||
if (volumeType == VolumeType::ColorTSDF)
|
||||
volume.raycast(poses[17].matrix, points, normals, colors);
|
||||
else
|
||||
volume.raycast(poses[17].matrix, points, normals);
|
||||
|
||||
patchNaNs(points);
|
||||
profile = counterOfValid(points);
|
||||
|
||||
Reference in New Issue
Block a user