diff --git a/modules/3d/include/opencv2/3d/volume_settings.hpp b/modules/3d/include/opencv2/3d/volume_settings.hpp index b57e647756..a6f7d57c6b 100644 --- a/modules/3d/include/opencv2/3d/volume_settings.hpp +++ b/modules/3d/include/opencv2/3d/volume_settings.hpp @@ -31,7 +31,6 @@ public: * @param volumeType volume type. */ VolumeSettings(VolumeType volumeType); - VolumeSettings(const VolumeSettings& vs); ~VolumeSettings(); diff --git a/modules/3d/perf/perf_tsdf.cpp b/modules/3d/perf/perf_tsdf.cpp index 99847a4d18..ae78295f78 100644 --- a/modules/3d/perf/perf_tsdf.cpp +++ b/modules/3d/perf/perf_tsdf.cpp @@ -416,549 +416,261 @@ void displayColorImage(Mat depth, Mat rgb, Mat points, Mat normals, Mat colors, static const bool display = false; -// Perf_TSDF_GPU.integrate_mat +enum PlatformType +{ + CPU = 0, GPU = 1 +}; +CV_ENUM(PlatformTypeEnum, PlatformType::CPU, PlatformType::GPU); + +enum Sequence +{ + ALL = 0, FIRST = 1 +}; +CV_ENUM(SequenceEnum, Sequence::ALL, Sequence::FIRST); + +enum class VolumeTestSrcType +{ + MAT = 0, + ODOMETRY_FRAME = 1 +}; + +// used to store current OpenCL status (on/off) and revert it after test is done +// works even after exceptions thrown in test body +struct OpenCLStatusRevert +{ #ifdef HAVE_OPENCL -PERF_TEST(Perf_TSDF_GPU, integrate_mat) + OpenCLStatusRevert() + { + originalOpenCLStatus = cv::ocl::useOpenCL(); + } + ~OpenCLStatusRevert() + { + cv::ocl::setUseOpenCL(originalOpenCLStatus); + } + void off() + { + cv::ocl::setUseOpenCL(false); + } + bool originalOpenCLStatus; #else -PERF_TEST(Perf_TSDF, integrate_mat) + void off() { } #endif +}; + +// CV_ENUM does not support enum class types, so let's implement the class explicitly +namespace { - VolumeType volumeType = VolumeType::TSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) + struct VolumeTypeEnum { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); + static const std::array vals; + static const std::array svals; - startTimer(); - volume.integrate(depth, pose); - stopTimer(); + VolumeTypeEnum(VolumeType v = VolumeType::TSDF) : val(v) {} + operator VolumeType() const { return val; } + void PrintTo(std::ostream *os) const + { + int v = int(val); + if (v >= 0 && v < 3) + { + *os << svals[v]; + } + else + { + *os << "UNKNOWN"; + } + } + static ::testing::internal::ParamGenerator all() + { + return ::testing::Values(VolumeTypeEnum(vals[0]), VolumeTypeEnum(vals[1]), VolumeTypeEnum(vals[2])); + } - } - SANITY_CHECK_NOTHING(); + private: + VolumeType val; + }; + const std::array VolumeTypeEnum::vals{VolumeType::TSDF, VolumeType::HashTSDF, VolumeType::ColorTSDF}; + const std::array VolumeTypeEnum::svals{std::string("TSDF"), std::string("HashTSDF"), std::string("ColorTSDF")}; + + static inline void PrintTo(const VolumeTypeEnum &t, std::ostream *os) { t.PrintTo(os); } + + + struct VolumeTestSrcTypeEnum + { + static const std::array vals; + static const std::array svals; + + VolumeTestSrcTypeEnum(VolumeTestSrcType v = VolumeTestSrcType::MAT) : val(v) {} + operator VolumeTestSrcType() const { return val; } + void PrintTo(std::ostream *os) const + { + int v = int(val); + if (v >= 0 && v < 3) + { + *os << svals[v]; + } + else + { + *os << "UNKNOWN"; + } + } + static ::testing::internal::ParamGenerator all() + { + return ::testing::Values(VolumeTestSrcTypeEnum(vals[0]), VolumeTestSrcTypeEnum(vals[1])); + } + + private: + VolumeTestSrcType val; + }; + const std::array VolumeTestSrcTypeEnum::vals{VolumeTestSrcType::MAT, VolumeTestSrcType::ODOMETRY_FRAME}; + const std::array VolumeTestSrcTypeEnum::svals{std::string("UMat"), std::string("OdometryFrame")}; + + static inline void PrintTo(const VolumeTestSrcTypeEnum &t, std::ostream *os) { t.PrintTo(os); } } -// Perf_TSDF_GPU.integrate_frame -#ifdef HAVE_OPENCL -PERF_TEST(Perf_TSDF_GPU, integrate_frame) -#else -PERF_TEST(Perf_TSDF, integrate_frame) -#endif +typedef std::tuple PlatformVolumeType; +class VolumePerfFixture : public perf::TestBaseWithParam> { - VolumeType volumeType = VolumeType::TSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) +protected: + void SetUp() override { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - OdometryFrame odf(noArray(), depth); + TestBase::SetUp(); - startTimer(); - volume.integrate(odf, pose); - stopTimer(); + auto p = GetParam(); + gpu = std::get<0>(std::get<0>(p)); + volumeType = std::get<1>(std::get<0>(p)); + + testSrcType = std::get<1>(p); + + repeat1st = (std::get<2>(p) == Sequence::FIRST); + + if (!gpu) + oclStatus.off(); + + VolumeSettings vs(volumeType); + volume = makePtr(volumeType, vs); + + frameSize = Size(vs.getRaycastWidth(), vs.getRaycastHeight()); + Matx33f intrIntegrate; + vs.getCameraIntegrateIntrinsics(intrIntegrate); + vs.getCameraRaycastIntrinsics(intrRaycast); + bool onlySemisphere = false; + depthFactor = vs.getDepthFactor(); + scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); + poses = scene->getPoses(); } - SANITY_CHECK_NOTHING(); -} -// Perf_TSDF_GPU.raycast_mat -#ifdef HAVE_OPENCL -PERF_TEST(Perf_TSDF_GPU, raycast_mat) -#else -PERF_TEST(Perf_TSDF, raycast_mat) -#endif + bool gpu; + VolumeType volumeType; + VolumeTestSrcType testSrcType; + bool repeat1st; + + OpenCLStatusRevert oclStatus; + + Ptr volume; + Size frameSize; + Matx33f intrRaycast; + Ptr scene; + std::vector poses; + float depthFactor; +}; + + +PERF_TEST_P_(VolumePerfFixture, integrate) { - VolumeType volumeType = VolumeType::TSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - Mat points, normals; - - volume.integrate(depth, pose); - - startTimer(); - volume.raycast(pose, frameSize.height, frameSize.width, intrRaycast, points, normals); - stopTimer(); - - if (display) - displayImage(depth, points, normals, depthFactor, lightPose); - - } - SANITY_CHECK_NOTHING(); -} - - -#ifdef HAVE_OPENCL -// Perf_TSDF_CPU.integrate_mat -PERF_TEST(Perf_TSDF_CPU, integrate_mat) -{ - cv::ocl::setUseOpenCL(false); - - VolumeType volumeType = VolumeType::TSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - - startTimer(); - volume.integrate(depth, pose); - stopTimer(); - - } - SANITY_CHECK_NOTHING(); - - cv::ocl::setUseOpenCL(true); -} - -// Perf_TSDF_CPU.integrate_frame -PERF_TEST(Perf_TSDF_CPU, integrate_frame) -{ - cv::ocl::setUseOpenCL(false); - - VolumeType volumeType = VolumeType::TSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - OdometryFrame odf(noArray(), depth); - - startTimer(); - volume.integrate(odf, pose); - stopTimer(); - - } - SANITY_CHECK_NOTHING(); - - cv::ocl::setUseOpenCL(true); -} - -// Perf_TSDF_CPU.raycast_mat -PERF_TEST(Perf_TSDF_CPU, raycast_mat) -{ - cv::ocl::setUseOpenCL(false); - - VolumeType volumeType = VolumeType::TSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - Mat points, normals; - - volume.integrate(depth, pose); - - startTimer(); - volume.raycast(pose, frameSize.height, frameSize.width, intrRaycast, points, normals); - stopTimer(); - - if (display) - displayImage(depth, points, normals, depthFactor, lightPose); - - } - SANITY_CHECK_NOTHING(); - - cv::ocl::setUseOpenCL(true); -} - -#endif - -// Perf_HashTSDF_GPU.integrate_mat -#ifdef HAVE_OPENCL -PERF_TEST(Perf_HashTSDF_GPU, integrate_mat) -#else -PERF_TEST(Perf_HashTSDF, integrate_mat) -#endif -{ - VolumeType volumeType = VolumeType::HashTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - - startTimer(); - volume.integrate(depth, pose); - stopTimer(); - - } - SANITY_CHECK_NOTHING(); -} - -// Perf_HashTSDF_GPU.integrate_frame -#ifdef HAVE_OPENCL -PERF_TEST(Perf_HashTSDF_GPU, integrate_frame) -#else -PERF_TEST(Perf_HashTSDF, integrate_frame) -#endif -{ - VolumeType volumeType = VolumeType::HashTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - OdometryFrame odf(noArray(), depth); - - startTimer(); - volume.integrate(odf, pose); - stopTimer(); - - } - SANITY_CHECK_NOTHING(); -} - -// Perf_HashTSDF_GPU.raycast_mat -#ifdef HAVE_OPENCL -PERF_TEST(Perf_HashTSDF_GPU, raycast_mat) -#else -PERF_TEST(Perf_HashTSDF, raycast_mat) -#endif -{ - VolumeType volumeType = VolumeType::HashTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - Mat points, normals; - - volume.integrate(depth, pose); - - startTimer(); - volume.raycast(pose, frameSize.height, frameSize.width, intrRaycast, points, normals); - stopTimer(); - - if (display) - displayImage(depth, points, normals, depthFactor, lightPose); - - } - SANITY_CHECK_NOTHING(); -} - -#ifdef HAVE_OPENCL -// Perf_HashTSDF_CPU.integrate_mat -PERF_TEST(Perf_HashTSDF_CPU, integrate_mat) -{ - cv::ocl::setUseOpenCL(false); - - VolumeType volumeType = VolumeType::HashTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - - startTimer(); - volume.integrate(depth, pose); - stopTimer(); - - } - SANITY_CHECK_NOTHING(); - - cv::ocl::setUseOpenCL(true); -} - -// Perf_HashTSDF_CPU.integrate_frame -PERF_TEST(Perf_HashTSDF_CPU, integrate_frame) -{ - cv::ocl::setUseOpenCL(false); - - VolumeType volumeType = VolumeType::HashTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - OdometryFrame odf(noArray(), depth); - - startTimer(); - volume.integrate(odf, pose); - stopTimer(); - - } - SANITY_CHECK_NOTHING(); - - cv::ocl::setUseOpenCL(true); -} - -// Perf_HashTSDF_CPU.raycast_mat -PERF_TEST(Perf_HashTSDF_CPU, raycast_mat) -{ - cv::ocl::setUseOpenCL(false); - - VolumeType volumeType = VolumeType::HashTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - Mat points, normals; - - volume.integrate(depth, pose); - - startTimer(); - volume.raycast(pose, frameSize.height, frameSize.width, intrRaycast, points, normals); - stopTimer(); - - if (display) - displayImage(depth, points, normals, depthFactor, lightPose); - } - SANITY_CHECK_NOTHING(); - - cv::ocl::setUseOpenCL(true); -} -#endif - - -// Perf_ColorTSDF_CPU.integrate_mat -#ifdef HAVE_OPENCL -PERF_TEST(Perf_ColorTSDF_CPU, integrate_mat) -#else -PERF_TEST(Perf_ColorTSDF, integrate_mat) -#endif -{ - VolumeType volumeType = VolumeType::ColorTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) + for (size_t i = 0; i < (repeat1st ? 1 : poses.size()); i++) { Matx44f pose = poses[i].matrix; Mat depth = scene->depth(pose); Mat rgb = scene->rgb(pose); + UMat urgb, udepth; + depth.copyTo(udepth); + rgb.copyTo(urgb); + OdometryFrame odf(urgb, udepth); - startTimer(); - volume.integrate(depth, rgb, pose); - stopTimer(); + bool done = false; + while (repeat1st ? next() : !done) + { + startTimer(); + if (testSrcType == VolumeTestSrcType::MAT) + if (volumeType == VolumeType::ColorTSDF) + volume->integrate(udepth, urgb, pose); + else + volume->integrate(udepth, pose); + else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME) + volume->integrate(odf, pose); + stopTimer(); + // perf check makes sense only for identical states + if (repeat1st) + volume->reset(); + + done = true; + } } SANITY_CHECK_NOTHING(); } -// Perf_ColorTSDF_CPU.integrate_frame -#ifdef HAVE_OPENCL -PERF_TEST(Perf_ColorTSDF_CPU, integrate_frame) -#else -PERF_TEST(Perf_ColorTSDF, integrate_frame) -#endif + +PERF_TEST_P_(VolumePerfFixture, raycast) { - VolumeType volumeType = VolumeType::ColorTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - for (size_t i = 0; i < poses.size(); i++) + for (size_t i = 0; i < (repeat1st ? 1 : poses.size()); i++) { Matx44f pose = poses[i].matrix; Mat depth = scene->depth(pose); Mat rgb = scene->rgb(pose); - OdometryFrame odf(rgb, depth); + UMat urgb, udepth; + depth.copyTo(udepth); + rgb.copyTo(urgb); - startTimer(); - volume.integrate(odf, pose); - stopTimer(); + OdometryFrame odf(urgb, udepth); - } - SANITY_CHECK_NOTHING(); -} + if (testSrcType == VolumeTestSrcType::MAT) + if (volumeType == VolumeType::ColorTSDF) + volume->integrate(udepth, urgb, pose); + else + volume->integrate(udepth, pose); + else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME) + volume->integrate(odf, pose); -// Perf_ColorTSDF_CPU.raycast_mat -#ifdef HAVE_OPENCL -PERF_TEST(Perf_ColorTSDF_CPU, raycast_mat) -#else -PERF_TEST(Perf_ColorTSDF, raycast_mat) -#endif -{ - VolumeType volumeType = VolumeType::ColorTSDF; - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); + UMat upoints, unormals, ucolors; - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); + bool done = false; + while (repeat1st ? next() : !done) + { + startTimer(); + if (volumeType == VolumeType::ColorTSDF) + volume->raycast(pose, frameSize.height, frameSize.width, intrRaycast, upoints, unormals, ucolors); + else + volume->raycast(pose, frameSize.height, frameSize.width, intrRaycast, upoints, unormals); + stopTimer(); - for (size_t i = 0; i < poses.size(); i++) - { - Matx44f pose = poses[i].matrix; - Mat depth = scene->depth(pose); - Mat rgb = scene->rgb(pose); - Mat points, normals, colors; - - startTimer(); - volume.integrate(depth, rgb, pose); - - startTimer(); - volume.raycast(pose, frameSize.height, frameSize.width, intrRaycast, points, normals, colors); - stopTimer(); + done = true; + } if (display) - displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); + { + Mat points, normals, colors; + points = upoints.getMat(ACCESS_READ); + normals = unormals.getMat(ACCESS_READ); + colors = ucolors.getMat(ACCESS_READ); + + Vec3f lightPose = Vec3f::all(0.f); + if (volumeType == VolumeType::ColorTSDF) + displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); + else + displayImage(depth, points, normals, depthFactor, lightPose); + } } SANITY_CHECK_NOTHING(); } +//TODO: fix it when ColorTSDF gets GPU version +INSTANTIATE_TEST_CASE_P(Volume, VolumePerfFixture, /*::testing::Combine(PlatformTypeEnum::all(), VolumeTypeEnum::all())*/ + ::testing::Combine( + ::testing::Values(PlatformVolumeType {PlatformType::CPU, VolumeType::TSDF}, + PlatformVolumeType {PlatformType::CPU, VolumeType::HashTSDF}, + PlatformVolumeType {PlatformType::CPU, VolumeType::ColorTSDF}, + PlatformVolumeType {PlatformType::GPU, VolumeType::TSDF}, + PlatformVolumeType {PlatformType::GPU, VolumeType::HashTSDF}), + VolumeTestSrcTypeEnum::all(), SequenceEnum::all())); + }} // namespace diff --git a/modules/3d/src/rgbd/hash_tsdf_functions.cpp b/modules/3d/src/rgbd/hash_tsdf_functions.cpp index 7b2fefe788..5d30a79622 100644 --- a/modules/3d/src/rgbd/hash_tsdf_functions.cpp +++ b/modules/3d/src/rgbd/hash_tsdf_functions.cpp @@ -1243,16 +1243,15 @@ void fetchNormalsFromHashTsdfVolumeUnit( Matx44f _pose; settings.getVolumePose(_pose); - const Affine3f pose = Affine3f(_pose); + const Affine3f pose(_pose); auto HashPushNormals = [&](const ptype& point, const int* position) { - //Affine3f invPose(pose.inv()); + Affine3f invPose(pose.inv()); Point3f p = fromPtype(point); Point3f n = nan3; if (!isNaN(p)) { - //Point3f voxelPoint = invPose * p; - Point3f voxelPoint = p; + Point3f voxelPoint = invPose * p; n = pose.rotation() * getNormalVoxel(voxelPoint, voxelSizeInv, volumeUnitDegree, volDims, volUnitsData, volumeUnits); } normals(position[0], position[1]) = toPtype(n); @@ -1262,7 +1261,7 @@ void fetchNormalsFromHashTsdfVolumeUnit( } #ifdef HAVE_OPENCL -void olc_fetchNormalsFromHashTsdfVolumeUnit( +void ocl_fetchNormalsFromHashTsdfVolumeUnit( const VolumeSettings& settings, const int volumeUnitDegree, InputArray _volUnitsData, InputArray _volUnitsDataCopy, const CustomHashSet& hashTable, InputArray _points, OutputArray _normals) { @@ -1332,6 +1331,10 @@ void fetchPointsNormalsFromHashTsdfVolumeUnit( const Vec4i volDims; settings.getVolumeStrides(volDims); + Matx44f mpose; + settings.getVolumePose(mpose); + const Affine3f pose(mpose); + std::vector totalVolUnits; for (const auto& keyvalue : volumeUnits) { @@ -1343,6 +1346,7 @@ void fetchPointsNormalsFromHashTsdfVolumeUnit( bool needNormals(_normals.needed()); Mutex mutex; + //TODO: this is incorrect; a 0-surface should be captured instead of all non-zero voxels auto HashFetchPointsNormalsInvoker = [&](const Range& range) { std::vector points, normals; @@ -1363,14 +1367,15 @@ void fetchPointsNormalsFromHashTsdfVolumeUnit( cv::Vec3i voxelIdx(x, y, z); TsdfVoxel voxel = _at(volUnitsData, voxelIdx, it->second.index, volResolution.x, volDims); + // floatToTsdf(1.0) == -128 if (voxel.tsdf != -128 && voxel.weight != 0) { Point3f point = base_point + voxelCoordToVolume(voxelIdx, voxelSize); - localPoints.push_back(toPtype(point)); + localPoints.push_back(toPtype(pose * point)); if (needNormals) { Point3f normal = getNormalVoxel(point, voxelSizeInv, volumeUnitDegree, volDims, volUnitsData, volumeUnits); - localNormals.push_back(toPtype(normal)); + localNormals.push_back(toPtype(pose.rotation() * normal)); } } } @@ -1459,6 +1464,10 @@ void ocl_fetchPointsNormalsFromHashTsdfVolumeUnit( const Vec4i volDims; settings.getVolumeStrides(volDims); + Matx44f mpose; + settings.getVolumePose(mpose); + const Affine3f pose(mpose); + Range _fetchRange(0, hashTable.last); const int nstripes = -1; @@ -1466,6 +1475,7 @@ void ocl_fetchPointsNormalsFromHashTsdfVolumeUnit( bool needNormals(_normals.needed()); Mutex mutex; + //TODO: this is incorrect; a 0-surface should be captured instead of all non-zero voxels auto _HashFetchPointsNormalsInvoker = [&](const Range& range) { std::vector points, normals; @@ -1485,15 +1495,16 @@ void ocl_fetchPointsNormalsFromHashTsdfVolumeUnit( cv::Vec3i voxelIdx(x, y, z); TsdfVoxel voxel = new_at(volUnitsDataCopy, voxelIdx, row, volumeUnitResolution, volDims); + // floatToTsdf(1.0) == -128 if (voxel.tsdf != -128 && voxel.weight != 0) { Point3f point = base_point + voxelCoordToVolume(voxelIdx, voxelSize); - localPoints.push_back(toPtype(point)); + localPoints.push_back(toPtype(pose * point)); if (needNormals) { Point3f normal = ocl_getNormalVoxel(point, voxelSizeInv, volumeUnitDegree, volDims, volUnitsDataCopy, hashTable); - localNormals.push_back(toPtype(normal)); + localNormals.push_back(toPtype(pose.rotation() * normal)); } } } diff --git a/modules/3d/src/rgbd/hash_tsdf_functions.hpp b/modules/3d/src/rgbd/hash_tsdf_functions.hpp index 70826dbb94..253fdaddf8 100644 --- a/modules/3d/src/rgbd/hash_tsdf_functions.hpp +++ b/modules/3d/src/rgbd/hash_tsdf_functions.hpp @@ -310,7 +310,7 @@ void ocl_raycastHashTsdfVolumeUnit( const VolumeSettings& settings, const Matx44f& cameraPose, int height, int width, InputArray intr, const int volumeUnitDegree, const CustomHashSet& hashTable, InputArray _volUnitsData, OutputArray _points, OutputArray _normals); -void olc_fetchNormalsFromHashTsdfVolumeUnit( +void ocl_fetchNormalsFromHashTsdfVolumeUnit( const VolumeSettings& settings, const int volumeUnitDegree, InputArray _volUnitsData, InputArray _volUnitsDataCopy, const CustomHashSet& hashTable, InputArray _points, OutputArray _normals); diff --git a/modules/3d/src/rgbd/tsdf_functions.cpp b/modules/3d/src/rgbd/tsdf_functions.cpp index 2fdbc78e99..4aa1e37f93 100644 --- a/modules/3d/src/rgbd/tsdf_functions.cpp +++ b/modules/3d/src/rgbd/tsdf_functions.cpp @@ -1127,15 +1127,15 @@ void ocl_fetchNormalsFromTsdfVolumeUnit(const VolumeSettings& settings, InputArr Size frameSize = points.size(); k.args(ocl::KernelArg::ReadOnlyNoSize(points), - ocl::KernelArg::WriteOnlyNoSize(normals), - frameSize, - ocl::KernelArg::PtrReadOnly(volume), - ocl::KernelArg::PtrReadOnly(volPoseGpu), - ocl::KernelArg::PtrReadOnly(invPoseGpu), - voxelSizeInv, - volResGpu.val, - volDims.val, - neighbourCoords.val); + ocl::KernelArg::WriteOnlyNoSize(normals), + frameSize, + ocl::KernelArg::PtrReadOnly(volume), + ocl::KernelArg::PtrReadOnly(volPoseGpu), + ocl::KernelArg::PtrReadOnly(invPoseGpu), + voxelSizeInv, + volResGpu.val, + volDims.val, + neighbourCoords.val); size_t globalSize[2]; globalSize[0] = (size_t)points.cols; @@ -1148,8 +1148,8 @@ void ocl_fetchNormalsFromTsdfVolumeUnit(const VolumeSettings& settings, InputArr #endif inline void coord(const Mat& volume, const TsdfVoxel* volDataStart, std::vector& points, std::vector& normals, - const Point3i volResolution, const Vec4i volDims, const Vec8i neighbourCoords, const Affine3f pose, - const float voxelSize, const float voxelSizeInv, bool needNormals, int x, int y, int z, Point3f V, float v0, int axis) + const Point3i volResolution, const Vec4i volDims, const Vec8i neighbourCoords, const Affine3f pose, + const float voxelSize, const float voxelSizeInv, bool needNormals, int x, int y, int z, Point3f V, float v0, int axis) { // 0 for x, 1 for y, 2 for z bool limits = false; @@ -1176,9 +1176,9 @@ inline void coord(const Mat& volume, const TsdfVoxel* volDataStart, std::vector< if (limits) { - const TsdfVoxel& voxeld = volDataStart[(x + shift.x) * volDims[0] + - (y + shift.y) * volDims[1] + - (z + shift.z) * volDims[2]]; + const TsdfVoxel &voxeld = volDataStart[(x + shift.x) * volDims[0] + + (y + shift.y) * volDims[1] + + (z + shift.z) * volDims[2]]; float vd = tsdfToFloat(voxeld.tsdf); if (voxeld.weight != 0 && vd != 1.f) { @@ -1190,13 +1190,13 @@ inline void coord(const Mat& volume, const TsdfVoxel* volDataStart, std::vector< float inter = (Vc * abs(vd) + Vn * abs(v0)) * dinv; Point3f p(shift.x ? inter : V.x, - shift.y ? inter : V.y, - shift.z ? inter : V.z); + shift.y ? inter : V.y, + shift.z ? inter : V.z); { points.push_back(toPtype(pose * p)); if (needNormals) normals.push_back(toPtype(pose.rotation() * - getNormalVoxel(volume, volDims, neighbourCoords, volResolution, p * voxelSizeInv))); + getNormalVoxel(volume, volDims, neighbourCoords, volResolution, p * voxelSizeInv))); } } } @@ -1273,8 +1273,6 @@ void fetchPointsNormalsFromTsdfVolumeUnit(const VolumeSettings& settings, InputA parallel_for_(fetchRange, FetchPointsNormalsInvoker, nstripes); - - std::vector points, normals; for (size_t i = 0; i < pVecs.size(); i++) { diff --git a/modules/3d/src/rgbd/volume_impl.cpp b/modules/3d/src/rgbd/volume_impl.cpp index 5c62abb6f7..82a46158d3 100644 --- a/modules/3d/src/rgbd/volume_impl.cpp +++ b/modules/3d/src/rgbd/volume_impl.cpp @@ -324,7 +324,7 @@ void HashTsdfVolume::fetchNormals(InputArray points, OutputArray normals) const fetchNormalsFromHashTsdfVolumeUnit(settings, volUnitsData, volumeUnits, volumeUnitDegree, points, normals); #else if (useGPU) - olc_fetchNormalsFromHashTsdfVolumeUnit(settings, volumeUnitDegree, gpu_volUnitsData, volUnitsDataCopy, hashTable, points, normals); + ocl_fetchNormalsFromHashTsdfVolumeUnit(settings, volumeUnitDegree, gpu_volUnitsData, volUnitsDataCopy, hashTable, points, normals); else fetchNormalsFromHashTsdfVolumeUnit(settings, cpu_volUnitsData, cpu_volumeUnits, volumeUnitDegree, points, normals); diff --git a/modules/3d/test/ocl/test_tsdf.cpp b/modules/3d/test/ocl/test_tsdf.cpp deleted file mode 100644 index 1e32af5b77..0000000000 --- a/modules/3d/test/ocl/test_tsdf.cpp +++ /dev/null @@ -1,682 +0,0 @@ -// This file is part of OpenCV project. -// It is subject to the license terms in the LICENSE file found in the top-level directory -// of this distribution and at http://opencv.org/license.html - -#include "../test_precomp.hpp" -#include "opencv2/ts/ocl_test.hpp" - -#ifdef HAVE_OPENCL - -namespace opencv_test { -namespace { - -using namespace cv; - -/** Reprojects screen point to camera space given z coord. */ -struct Reprojector -{ - Reprojector() {} - inline Reprojector(Matx33f intr) - { - fxinv = 1.f / intr(0, 0), fyinv = 1.f / intr(1, 1); - cx = intr(0, 2), cy = intr(1, 2); - } - template - inline cv::Point3_ operator()(cv::Point3_ p) const - { - T x = p.z * (p.x - cx) * fxinv; - T y = p.z * (p.y - cy) * fyinv; - return cv::Point3_(x, y, p.z); - } - - float fxinv, fyinv, cx, cy; -}; - -template -struct RenderInvoker : ParallelLoopBody -{ - RenderInvoker(Mat_& _frame, Affine3f _pose, - Reprojector _reproj, float _depthFactor, bool _onlySemisphere) - : ParallelLoopBody(), - frame(_frame), - pose(_pose), - reproj(_reproj), - depthFactor(_depthFactor), - onlySemisphere(_onlySemisphere) - { } - - virtual void operator ()(const cv::Range& r) const - { - for (int y = r.start; y < r.end; y++) - { - float* frameRow = frame[y]; - for (int x = 0; x < frame.cols; x++) - { - float pix = 0; - - Point3f orig = pose.translation(); - // direction through pixel - Point3f screenVec = reproj(Point3f((float)x, (float)y, 1.f)); - float xyt = 1.f / (screenVec.x * screenVec.x + - screenVec.y * screenVec.y + 1.f); - Point3f dir = normalize(Vec3f(pose.rotation() * screenVec)); - // screen space axis - dir.y = -dir.y; - - const float maxDepth = 20.f; - const float maxSteps = 256; - float t = 0.f; - for (int step = 0; step < maxSteps && t < maxDepth; step++) - { - Point3f p = orig + dir * t; - float d = Scene::map(p, onlySemisphere); - if (d < 0.000001f) - { - float depth = std::sqrt(t * t * xyt); - pix = depth * depthFactor; - break; - } - t += d; - } - - frameRow[x] = pix; - } - } - } - - Mat_& frame; - Affine3f pose; - Reprojector reproj; - float depthFactor; - bool onlySemisphere; -}; - -struct Scene -{ - virtual ~Scene() {} - static Ptr create(Size sz, Matx33f _intr, float _depthFactor, bool onlySemisphere); - virtual Mat depth(Affine3f pose) = 0; - virtual std::vector getPoses() = 0; -}; - -struct SemisphereScene : Scene -{ - const int framesPerCycle = 72; - const float nCycles = 0.25f; - const Affine3f startPose = Affine3f(Vec3f(0.f, 0.f, 0.f), Vec3f(1.5f, 0.3f, -2.1f)); - - Size frameSize; - Matx33f intr; - float depthFactor; - bool onlySemisphere; - - SemisphereScene(Size sz, Matx33f _intr, float _depthFactor, bool _onlySemisphere) : - frameSize(sz), intr(_intr), depthFactor(_depthFactor), onlySemisphere(_onlySemisphere) - { } - - static float map(Point3f p, bool onlySemisphere) - { - float plane = p.y + 0.5f; - Point3f spherePose = p - Point3f(-0.0f, 0.3f, 1.1f); - float sphereRadius = 0.5f; - float sphere = (float)cv::norm(spherePose) - sphereRadius; - float sphereMinusBox = sphere; - - float subSphereRadius = 0.05f; - Point3f subSpherePose = p - Point3f(0.3f, -0.1f, -0.3f); - float subSphere = (float)cv::norm(subSpherePose) - subSphereRadius; - - float res; - if (!onlySemisphere) - res = min({ sphereMinusBox, subSphere, plane }); - else - res = sphereMinusBox; - - return res; - } - - Mat depth(Affine3f pose) override - { - Mat_ frame(frameSize); - Reprojector reproj(intr); - - Range range(0, frame.rows); - parallel_for_(range, RenderInvoker(frame, pose, reproj, depthFactor, onlySemisphere)); - - return std::move(frame); - } - - std::vector getPoses() override - { - std::vector poses; - for (int i = 0; i < framesPerCycle * nCycles; i++) - { - float angle = (float)(CV_2PI * i / framesPerCycle); - Affine3f pose; - pose = pose.rotate(startPose.rotation()); - pose = pose.rotate(Vec3f(0.f, -0.5f, 0.f) * angle); - pose = pose.translate(Vec3f(startPose.translation()[0] * sin(angle), - startPose.translation()[1], - startPose.translation()[2] * cos(angle))); - poses.push_back(pose); - } - - return poses; - } - -}; - -Ptr Scene::create(Size sz, Matx33f _intr, float _depthFactor, bool _onlySemisphere) -{ - return makePtr(sz, _intr, _depthFactor, _onlySemisphere); -} - -// this is a temporary solution -// ---------------------------- - -typedef cv::Vec4f ptype; -typedef cv::Mat_< ptype > Points; -typedef Points Normals; -typedef Size2i Size; - -template -inline float specPow(float x) -{ - if (p % 2 == 0) - { - float v = specPow

(x); - return v * v; - } - else - { - float v = specPow<(p - 1) / 2>(x); - return v * v * x; - } -} - -template<> -inline float specPow<0>(float /*x*/) -{ - return 1.f; -} - -template<> -inline float specPow<1>(float x) -{ - return x; -} - -inline cv::Vec3f fromPtype(const ptype& x) -{ - return cv::Vec3f(x[0], x[1], x[2]); -} - -inline Point3f normalize(const Vec3f& v) -{ - double nv = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - return v * (nv ? 1. / nv : 0.); -} - -void renderPointsNormals(InputArray _points, InputArray _normals, OutputArray image, Affine3f lightPose) -{ - Size sz = _points.size(); - image.create(sz, CV_8UC4); - - Points points = _points.getMat(); - Normals normals = _normals.getMat(); - - Mat_ img = image.getMat(); - - Range range(0, sz.height); - const int nstripes = -1; - parallel_for_(range, [&](const Range&) - { - for (int y = range.start; y < range.end; y++) - { - Vec4b* imgRow = img[y]; - const ptype* ptsRow = points[y]; - const ptype* nrmRow = normals[y]; - - for (int x = 0; x < sz.width; x++) - { - Point3f p = fromPtype(ptsRow[x]); - Point3f n = fromPtype(nrmRow[x]); - - Vec4b color; - - if (cvIsNaN(p.x) || cvIsNaN(p.y) || cvIsNaN(p.z)) - { - color = Vec4b(0, 32, 0, 0); - } - else - { - const float Ka = 0.3f; //ambient coeff - const float Kd = 0.5f; //diffuse coeff - const float Ks = 0.2f; //specular coeff - const int sp = 20; //specular power - - const float Ax = 1.f; //ambient color, can be RGB - const float Dx = 1.f; //diffuse color, can be RGB - const float Sx = 1.f; //specular color, can be RGB - const float Lx = 1.f; //light color - - Point3f l = normalize(lightPose.translation() - Vec3f(p)); - Point3f v = normalize(-Vec3f(p)); - Point3f r = normalize(Vec3f(2.f * n * n.dot(l) - l)); - - uchar ix = (uchar)((Ax * Ka * Dx + Lx * Kd * Dx * max(0.f, n.dot(l)) + - Lx * Ks * Sx * specPow(max(0.f, r.dot(v)))) * 255.f); - color = Vec4b(ix, ix, ix, 0); - } - - imgRow[x] = color; - } - } - }, nstripes); -} -// ---------------------------- - -void displayImage(Mat depth, Mat points, Mat normals, float depthFactor, Vec3f lightPose) -{ - Mat image; - patchNaNs(points); - imshow("depth", depth * (1.f / depthFactor / 4.f)); - renderPointsNormals(points, normals, image, lightPose); - imshow("render", image); - waitKey(2000); - destroyAllWindows(); -} - -void normalsCheck(Mat normals) -{ - Vec4f vector; - for (auto pvector = normals.begin(); pvector < normals.end(); pvector++) - { - vector = *pvector; - if (!cvIsNaN(vector[0])) - { - float length = vector[0] * vector[0] + - vector[1] * vector[1] + - vector[2] * vector[2]; - ASSERT_LT(abs(1 - length), 0.0001f) << "There is normal with length != 1"; - } - } -} - -int counterOfValid(Mat points) -{ - Vec4f* v; - int i, j; - int count = 0; - for (i = 0; i < points.rows; ++i) - { - v = (points.ptr(i)); - for (j = 0; j < points.cols; ++j) - { - if ((v[j])[0] != 0 || - (v[j])[1] != 0 || - (v[j])[2] != 0) - { - count++; - } - } - } - return count; -} - -enum class VolumeTestFunction -{ - RAYCAST = 0, - FETCH_NORMALS = 1, - FETCH_POINTS_NORMALS = 2 -}; - -enum class VolumeTestSrcType -{ - MAT = 0, - ODOMETRY_FRAME = 1 -}; - -void normal_test_custom_framesize(VolumeType volumeType, VolumeTestFunction testFunction, VolumeTestSrcType testSrcType) -{ - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = true; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - UMat udepth; - depth.copyTo(udepth); - UMat upoints, unormals, utmpnormals; - Mat points, normals; - AccessFlag af = ACCESS_READ; - - OdometryFrame odf(noArray(), udepth); - - if (testSrcType == VolumeTestSrcType::MAT) - volume.integrate(depth, poses[0].matrix); - else - volume.integrate(odf, poses[0].matrix); - - if (testFunction == VolumeTestFunction::RAYCAST) - { - volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, 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, intrRaycast, upoints, utmpnormals); - // volume.fetchPointsNormals(upoints, utmpnormals); - volume.fetchNormals(upoints, unormals); - } - } - else if (testFunction == VolumeTestFunction::FETCH_POINTS_NORMALS) - { - if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats - { - volume.fetchPointsNormals(upoints, unormals); - } - } - - normals = unormals.getMat(af); - points = upoints.getMat(af); - - if (testFunction == VolumeTestFunction::RAYCAST && cvtest::debugLevel > 0) - displayImage(depth, points, normals, depthFactor, lightPose); - - normalsCheck(normals); -} - -void normal_test_common_framesize(VolumeType volumeType, VolumeTestFunction testFunction, VolumeTestSrcType testSrcType) -{ - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = true; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - UMat udepth; - depth.copyTo(udepth); - UMat upoints, unormals, utmpnormals; - Mat points, normals; - AccessFlag af = ACCESS_READ; - - OdometryFrame odf(noArray(), udepth); - - if (testSrcType == VolumeTestSrcType::MAT) - volume.integrate(depth, poses[0].matrix); - else - volume.integrate(odf, poses[0].matrix); - - if (testFunction == VolumeTestFunction::RAYCAST) - { - volume.raycast(poses[0].matrix, 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, upoints, utmpnormals); - //volume.fetchPointsNormals(upoints, utmpnormals); - volume.fetchNormals(upoints, unormals); - } - } - else if (testFunction == VolumeTestFunction::FETCH_POINTS_NORMALS) - { - if (testSrcType == VolumeTestSrcType::MAT) // Odometry frame or Mats - { - volume.fetchPointsNormals(upoints, unormals); - } - } - - normals = unormals.getMat(af); - points = upoints.getMat(af); - - if (testFunction == VolumeTestFunction::RAYCAST && cvtest::debugLevel > 0) - displayImage(depth, points, normals, depthFactor, lightPose); - - normalsCheck(normals); -} - -void valid_points_test_custom_framesize(VolumeType volumeType, VolumeTestSrcType testSrcType) -{ - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = true; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - UMat udepth; - depth.copyTo(udepth); - UMat upoints, unormals; - UMat upoints1, unormals1; - Mat points, normals; - AccessFlag af = ACCESS_READ; - int anfas, profile; - - OdometryFrame odf(noArray(), udepth); - - if (testSrcType == VolumeTestSrcType::MAT) - volume.integrate(depth, poses[0].matrix); - else - volume.integrate(odf, poses[0].matrix); - - volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, unormals); - - normals = unormals.getMat(af); - points = upoints.getMat(af); - patchNaNs(points); - anfas = counterOfValid(points); - - if (cvtest::debugLevel > 0) - displayImage(depth, points, normals, depthFactor, lightPose); - - volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, intrRaycast, upoints1, unormals1); - - normals = unormals1.getMat(af); - points = upoints1.getMat(af); - patchNaNs(points); - profile = counterOfValid(points); - - if (cvtest::debugLevel > 0) - displayImage(depth, points, normals, depthFactor, lightPose); - - // TODO: why profile == 2*anfas ? - float percentValidity = float(anfas) / float(profile); - - ASSERT_NE(profile, 0) << "There is no points in profile"; - ASSERT_NE(anfas, 0) << "There is no points in anfas"; - ASSERT_LT(abs(0.5 - percentValidity), 0.3) << "percentValidity out of [0.3; 0.7] (percentValidity=" << percentValidity << ")"; -} - -void valid_points_test_common_framesize(VolumeType volumeType, VolumeTestSrcType testSrcType) -{ - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = true; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - UMat udepth; - depth.copyTo(udepth); - UMat upoints, unormals; - UMat upoints1, unormals1; - Mat points, normals; - AccessFlag af = ACCESS_READ; - int anfas, profile; - - OdometryFrame odf(noArray(), udepth); - - if (testSrcType == VolumeTestSrcType::MAT) - volume.integrate(depth, poses[0].matrix); - else - volume.integrate(odf, poses[0].matrix); - - volume.raycast(poses[0].matrix, upoints, unormals); - - normals = unormals.getMat(af); - points = upoints.getMat(af); - patchNaNs(points); - anfas = counterOfValid(points); - - if (cvtest::debugLevel > 0) - displayImage(depth, points, normals, depthFactor, lightPose); - - volume.raycast(poses[17].matrix, upoints1, unormals1); - - normals = unormals1.getMat(af); - points = upoints1.getMat(af); - patchNaNs(points); - profile = counterOfValid(points); - - if (cvtest::debugLevel > 0) - displayImage(depth, points, normals, depthFactor, lightPose); - - // TODO: why profile == 2*anfas ? - float percentValidity = float(anfas) / float(profile); - - ASSERT_NE(profile, 0) << "There is no points in profile"; - ASSERT_NE(anfas, 0) << "There is no points in anfas"; - ASSERT_LT(abs(0.5 - percentValidity), 0.3) << "percentValidity out of [0.3; 0.7] (percentValidity=" << percentValidity << ")"; -} - - -TEST(TSDF_GPU, raycast_custom_framesize_normals_mat) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(TSDF_GPU, raycast_custom_framesize_normals_frame) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF_GPU, raycast_common_framesize_normals_mat) -{ - normal_test_common_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(TSDF_GPU, raycast_common_framesize_normals_frame) -{ - normal_test_common_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF_GPU, fetch_points_normals) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(TSDF_GPU, fetch_normals) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(TSDF_GPU, valid_points_custom_framesize_mat) -{ - valid_points_test_custom_framesize(VolumeType::TSDF, VolumeTestSrcType::MAT); -} - -TEST(TSDF_GPU, valid_points_custom_framesize_frame) -{ - valid_points_test_custom_framesize(VolumeType::TSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF_GPU, valid_points_common_framesize_mat) -{ - valid_points_test_common_framesize(VolumeType::TSDF, VolumeTestSrcType::MAT); -} - -TEST(TSDF_GPU, valid_points_common_framesize_frame) -{ - valid_points_test_common_framesize(VolumeType::TSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_GPU, raycast_custom_framesize_normals_mat) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_GPU, raycast_custom_framesize_normals_frame) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_GPU, raycast_common_framesize_normals_mat) -{ - normal_test_common_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_GPU, raycast_common_framesize_normals_frame) -{ - normal_test_common_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_GPU, fetch_points_normals) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_GPU, fetch_normals) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_GPU, valid_points_custom_framesize_mat) -{ - valid_points_test_custom_framesize(VolumeType::HashTSDF, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_GPU, valid_points_custom_framesize_frame) -{ - valid_points_test_custom_framesize(VolumeType::HashTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_GPU, valid_points_common_framesize_mat) -{ - valid_points_test_common_framesize(VolumeType::HashTSDF, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_GPU, valid_points_common_framesize_frame) -{ - valid_points_test_common_framesize(VolumeType::HashTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -} -} // namespace - -#endif diff --git a/modules/3d/test/test_tsdf.cpp b/modules/3d/test/test_tsdf.cpp index e6cd091b86..1564da7837 100644 --- a/modules/3d/test/test_tsdf.cpp +++ b/modules/3d/test/test_tsdf.cpp @@ -56,7 +56,7 @@ struct RenderInvoker : ParallelLoopBody Point3f screenVec = reproj(Point3f((float)x, (float)y, 1.f)); float xyt = 1.f / (screenVec.x * screenVec.x + screenVec.y * screenVec.y + 1.f); - Point3f dir = normalize(Vec3f(pose.rotation() * screenVec)); + Point3f dir = cv::normalize(Vec3f(pose.rotation() * screenVec)); // screen space axis dir.y = -dir.y; @@ -113,7 +113,7 @@ struct RenderColorInvoker : ParallelLoopBody Point3f orig = pose.translation(); // direction through pixel Point3f screenVec = reproj(Point3f((float)x, (float)y, 1.f)); - Point3f dir = normalize(Vec3f(pose.rotation() * screenVec)); + Point3f dir = cv::normalize(Vec3f(pose.rotation() * screenVec)); // screen space axis dir.y = -dir.y; @@ -287,12 +287,6 @@ inline cv::Vec3f fromPtype(const ptype& x) return cv::Vec3f(x[0], x[1], x[2]); } -inline Point3f normalize(const Vec3f& v) -{ - double nv = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - return v * (nv ? 1. / nv : 0.); -} - void renderPointsNormals(InputArray _points, InputArray _normals, OutputArray image, Affine3f lightPose) { Size sz = _points.size(); @@ -336,9 +330,9 @@ void renderPointsNormals(InputArray _points, InputArray _normals, OutputArray im const float Sx = 1.f; //specular color, can be RGB const float Lx = 1.f; //light color - Point3f l = normalize(lightPose.translation() - Vec3f(p)); - Point3f v = normalize(-Vec3f(p)); - Point3f r = normalize(Vec3f(2.f * n * n.dot(l) - l)); + Point3f l = cv::normalize(lightPose.translation() - Vec3f(p)); + Point3f v = cv::normalize(-Vec3f(p)); + Point3f r = cv::normalize(Vec3f(2.f * n * n.dot(l) - l)); uchar ix = (uchar)((Ax * Ka * Dx + Lx * Kd * Dx * max(0.f, n.dot(l)) + Lx * Ks * Sx * specPow(max(0.f, r.dot(v)))) * 255.f); @@ -433,7 +427,7 @@ void normalsCheck(Mat normals) ASSERT_LT(abs(1.f - l2), 0.0001f) << "There is normal with length != 1"; } } - ASSERT_GT(counter, 0) << "There are not normals"; + ASSERT_GT(counter, 0) << "There are no normals"; } int counterOfValid(Mat points) @@ -471,305 +465,11 @@ enum class VolumeTestSrcType ODOMETRY_FRAME = 1 }; -void normal_test_custom_framesize(VolumeType volumeType, VolumeTestFunction testFunction, VolumeTestSrcType testSrcType) +enum class FrameSizeType { - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; //TODO: check both - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - Mat rgb = scene->rgb(poses[0]); - //TODO: check this utmpnormals, it looks redundant - UMat upoints, unormals, utmpnormals, ucolors; - UMat udepth, urgb; - depth.copyTo(udepth); - rgb.copyTo(urgb); - - OdometryFrame odf(urgb, udepth); - - if (testSrcType == VolumeTestSrcType::MAT) - { - if (volumeType == VolumeType::ColorTSDF) - volume.integrate(udepth, urgb, poses[0].matrix); - else - volume.integrate(udepth, poses[0].matrix); - } - else - { - volume.integrate(odf, poses[0].matrix); - } - - if (testFunction == VolumeTestFunction::RAYCAST) - { - if (volumeType == VolumeType::ColorTSDF) - volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, unormals, ucolors); - else - volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, unormals); - } - else if (testFunction == VolumeTestFunction::FETCH_NORMALS) - { - if (volumeType == VolumeType::ColorTSDF) - volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, utmpnormals, ucolors); - else - // hash_tsdf cpu doesn't work with raycast normals - //volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, utmpnormals); - volume.fetchPointsNormals(upoints, utmpnormals); - - volume.fetchNormals(upoints, unormals); - } - else if (testFunction == VolumeTestFunction::FETCH_POINTS_NORMALS) - { - volume.fetchPointsNormals(upoints, unormals); - } - - Mat points, normals, colors; - points = upoints.getMat(ACCESS_READ); - normals = unormals.getMat(ACCESS_READ); - colors = ucolors.getMat(ACCESS_READ); - - if (testFunction == VolumeTestFunction::RAYCAST && cvtest::debugLevel > 0) - { - if (volumeType == VolumeType::ColorTSDF) - displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); - else - displayImage(depth, points, normals, depthFactor, lightPose); - } - - normalsCheck(normals); -} - - -void normal_test_common_framesize(VolumeType volumeType, VolumeTestFunction testFunction, VolumeTestSrcType testSrcType) -{ - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = false; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - Mat rgb = scene->rgb(poses[0]); - Mat points, normals, tmpnormals, colors; - - OdometryFrame odf(rgb, depth); - - if (testSrcType == VolumeTestSrcType::MAT) - { - if (volumeType == VolumeType::ColorTSDF) - volume.integrate(depth, rgb, poses[0].matrix); - else - volume.integrate(depth, poses[0].matrix); - } - else - { - volume.integrate(odf, poses[0].matrix); - } - - if (testFunction == VolumeTestFunction::RAYCAST) - { - 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) - { - if (volumeType == VolumeType::ColorTSDF) - volume.raycast(poses[0].matrix, points, tmpnormals, colors); - else - // hash_tsdf cpu don't works with raycast normals - //volume.raycast(poses[0].matrix, points, tmpnormals); - volume.fetchPointsNormals(points, tmpnormals); - - volume.fetchNormals(points, normals); - } - else if (testFunction == VolumeTestFunction::FETCH_POINTS_NORMALS) - { - volume.fetchPointsNormals(points, normals); - } - - if (testFunction == VolumeTestFunction::RAYCAST && cvtest::debugLevel > 0) - { - if (volumeType == VolumeType::ColorTSDF) - displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); - else - displayImage(depth, points, normals, depthFactor, lightPose); - } - - normalsCheck(normals); -} - - -void valid_points_test_custom_framesize(VolumeType volumeType, VolumeTestSrcType testSrcType) -{ - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = true; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - Mat rgb = scene->rgb(poses[0]); - Mat points, normals, colors, newPoints, newNormals; - int anfas, profile; - - OdometryFrame odf(rgb, depth); - - if (testSrcType == VolumeTestSrcType::MAT) - { - if (volumeType == VolumeType::ColorTSDF) - volume.integrate(depth, rgb, poses[0].matrix); - else - volume.integrate(depth, poses[0].matrix); - } - else - { - volume.integrate(odf, poses[0].matrix); - } - - if (volumeType == VolumeType::ColorTSDF) - volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, points, normals, colors); - else - volume.raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, points, normals); - - patchNaNs(points); - anfas = counterOfValid(points); - - if (cvtest::debugLevel > 0) - { - if (volumeType == VolumeType::ColorTSDF) - displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); - else - displayImage(depth, points, normals, depthFactor, lightPose); - } - - points.release(); - normals.release(); - - if (volumeType == VolumeType::ColorTSDF) - volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, intrRaycast, points, normals, colors); - else - volume.raycast(poses[17].matrix, frameSize.height, frameSize.width, intrRaycast, points, normals); - - patchNaNs(points); - profile = counterOfValid(points); - - if (cvtest::debugLevel > 0) - { - if (volumeType == VolumeType::ColorTSDF) - displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); - else - displayImage(depth, points, normals, depthFactor, lightPose); - } - - // TODO: why profile == 2*anfas ? - float percentValidity = float(anfas) / float(profile); - - ASSERT_NE(profile, 0) << "There is no points in profile"; - ASSERT_NE(anfas, 0) << "There is no points in anfas"; - ASSERT_LT(abs(0.5 - percentValidity), 0.3) << "percentValidity out of [0.3; 0.7] (percentValidity=" << percentValidity << ")"; -} - - -void valid_points_test_common_framesize(VolumeType volumeType, VolumeTestSrcType testSrcType) -{ - VolumeSettings vs(volumeType); - Volume volume(volumeType, vs); - - Size frameSize(vs.getRaycastWidth(), vs.getRaycastHeight()); - Matx33f intrIntegrate, intrRaycast; - vs.getCameraIntegrateIntrinsics(intrIntegrate); - vs.getCameraRaycastIntrinsics(intrRaycast); - bool onlySemisphere = true; - float depthFactor = vs.getDepthFactor(); - Vec3f lightPose = Vec3f::all(0.f); - Ptr scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); - std::vector poses = scene->getPoses(); - - Mat depth = scene->depth(poses[0]); - Mat rgb = scene->rgb(poses[0]); - Mat points, normals, colors, newPoints, newNormals; - int anfas, profile; - - OdometryFrame odf(rgb, depth); - - if (testSrcType == VolumeTestSrcType::MAT) - { - if (volumeType == VolumeType::ColorTSDF) - volume.integrate(depth, rgb, poses[0].matrix); - else - volume.integrate(depth, poses[0].matrix); - } - else - { - volume.integrate(odf, poses[0].matrix); - } - - 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); - - if (cvtest::debugLevel > 0) - { - if (volumeType == VolumeType::ColorTSDF) - displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); - else - displayImage(depth, points, normals, depthFactor, lightPose); - } - - points.release(); - normals.release(); - - 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); - - if (cvtest::debugLevel > 0) - { - if (volumeType == VolumeType::ColorTSDF) - displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); - else - displayImage(depth, points, normals, depthFactor, lightPose); - } - - // TODO: why profile == 2*anfas ? - float percentValidity = float(anfas) / float(profile); - - ASSERT_NE(profile, 0) << "There is no points in profile"; - ASSERT_NE(anfas, 0) << "There is no points in anfas"; - ASSERT_LT(abs(0.5 - percentValidity), 0.3) << "percentValidity out of [0.3; 0.7] (percentValidity=" << percentValidity << ")"; -} + DEFAULT = 0, + CUSTOM = 1 +}; void debugVolumeDraw(const Volume &volume, Affine3f pose, Mat depth, float depthFactor, std::string objFname) @@ -1040,185 +740,7 @@ void regressionVolPoseRot() EXPECT_LE(normNrm, 73.08); } - -#ifndef HAVE_OPENCL -TEST(TSDF, raycast_custom_framesize_normals_mat) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(TSDF, raycast_custom_framesize_normals_frame) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF, raycast_common_framesize_normals_mat) -{ - normal_test_common_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(TSDF, raycast_common_framesize_normals_frame) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF, fetch_points_normals) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(TSDF, fetch_normals) -{ - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(TSDF, valid_points_custom_framesize_mat) -{ - valid_points_test_custom_framesize(VolumeType::TSDF, VolumeTestSrcType::MAT); -} - -TEST(TSDF, valid_points_custom_framesize_frame) -{ - valid_points_test_custom_framesize(VolumeType::TSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF, valid_points_common_framesize_mat) -{ - valid_points_test_common_framesize(VolumeType::TSDF, VolumeTestSrcType::MAT); -} - -TEST(TSDF, valid_points_common_framesize_frame) -{ - valid_points_test_common_framesize(VolumeType::TSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF, raycast_custom_framesize_normals_mat) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF, raycast_custom_framesize_normals_frame) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF, raycast_common_framesize_normals_mat) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF, raycast_common_framesize_normals_frame) -{ - normal_test_common_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF, fetch_points_normals) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF, fetch_normals) -{ - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF, valid_points_custom_framesize_mat) -{ - valid_points_test_custom_framesize(VolumeType::HashTSDF, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF, valid_points_custom_framesize_frame) -{ - valid_points_test_custom_framesize(VolumeType::HashTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF, valid_points_common_framesize_mat) -{ - valid_points_test_common_framesize(VolumeType::HashTSDF, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF, valid_points_common_framesize_frame) -{ - valid_points_test_common_framesize(VolumeType::HashTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -class BoundingBoxEnableGrowthTest : public ::testing::TestWithParam -{ }; - -TEST_P(BoundingBoxEnableGrowthTest, boundingBoxEnableGrowth) -{ - boundingBoxGrowthTest(GetParam()); -} - -INSTANTIATE_TEST_CASE_P(TSDF, BoundingBoxEnableGrowthTest, ::testing::Bool()); - - -TEST(HashTSDF, reproduce_volPoseRot) -{ - regressionVolPoseRot(); -} - -TEST(ColorTSDF, raycast_custom_framesize_normals_mat) -{ - normal_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF, raycast_custom_framesize_normals_frame) -{ - normal_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(ColorTSDF, raycast_common_framesize_normals_mat) -{ - normal_test_common_framesize(VolumeType::ColorTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF, raycast_common_framesize_normals_frame) -{ - normal_test_common_framesize(VolumeType::ColorTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(ColorTSDF, fetch_normals) -{ - normal_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF, fetch_points_normals) -{ - normal_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF, valid_points_custom_framesize_mat) -{ - valid_points_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF, valid_points_custom_framesize_fetch) -{ - valid_points_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(ColorTSDF, valid_points_common_framesize_mat) -{ - valid_points_test_common_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF, valid_points_common_framesize_fetch) -{ - valid_points_test_common_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -class StaticVolumeBoundingBox : public ::testing::TestWithParam -{ }; - -TEST_P(StaticVolumeBoundingBox, boundingBox) -{ - staticBoundingBoxTest(GetParam()); -} - -INSTANTIATE_TEST_CASE_P(TSDF, StaticVolumeBoundingBox, ::testing::Values(VolumeType::TSDF, VolumeType::ColorTSDF)); - -#endif +///////// Parametrized tests enum PlatformType { @@ -1284,241 +806,348 @@ namespace const std::array VolumeTypeEnum::svals{std::string("TSDF"), std::string("HashTSDF"), std::string("ColorTSDF")}; static inline void PrintTo(const VolumeTypeEnum &t, std::ostream *os) { t.PrintTo(os); } + + + struct VolumeTestSrcTypeEnum + { + static const std::array vals; + static const std::array svals; + + VolumeTestSrcTypeEnum(VolumeTestSrcType v = VolumeTestSrcType::MAT) : val(v) {} + operator VolumeTestSrcType() const { return val; } + void PrintTo(std::ostream *os) const + { + int v = int(val); + if (v >= 0 && v < 3) + { + *os << svals[v]; + } + else + { + *os << "UNKNOWN"; + } + } + static ::testing::internal::ParamGenerator all() + { + return ::testing::Values(VolumeTestSrcTypeEnum(vals[0]), VolumeTestSrcTypeEnum(vals[1])); + } + + private: + VolumeTestSrcType val; + }; + const std::array VolumeTestSrcTypeEnum::vals{VolumeTestSrcType::MAT, VolumeTestSrcType::ODOMETRY_FRAME}; + const std::array VolumeTestSrcTypeEnum::svals{std::string("UMat"), std::string("OdometryFrame")}; + + static inline void PrintTo(const VolumeTestSrcTypeEnum &t, std::ostream *os) { t.PrintTo(os); } + + + struct FrameSizeTypeEnum + { + static const std::array vals; + static const std::array svals; + + FrameSizeTypeEnum(FrameSizeType v = FrameSizeType::DEFAULT) : val(v) {} + operator FrameSizeType() const { return val; } + void PrintTo(std::ostream *os) const + { + int v = int(val); + if (v >= 0 && v < 3) + { + *os << svals[v]; + } + else + { + *os << "UNKNOWN"; + } + } + static ::testing::internal::ParamGenerator all() + { + return ::testing::Values(FrameSizeTypeEnum(vals[0]), FrameSizeTypeEnum(vals[1])); + } + + private: + FrameSizeType val; + }; + const std::array FrameSizeTypeEnum::vals{FrameSizeType::DEFAULT, FrameSizeType::CUSTOM}; + const std::array FrameSizeTypeEnum::svals{std::string("DefaultSize"), std::string("CustomSize")}; + + static inline void PrintTo(const FrameSizeTypeEnum &t, std::ostream *os) { t.PrintTo(os); } } + typedef std::tuple PlatformVolumeType; -struct VolumeTestFixture : public ::testing::TestWithParam +struct VolumeTestFixture : public ::testing::TestWithParam> { protected: void SetUp() override { auto p = GetParam(); - gpu = std::get<0>(p); - volumeType = std::get<1>(p); + gpu = std::get<0>(std::get<0>(p)); + volumeType = std::get<1>(std::get<0>(p)); + + testSrcType = std::get<1>(p); + frameSizeSpecified = std::get<2>(p); if (!gpu) oclStatus.off(); + + vs = makePtr(volumeType); + volume = makePtr(volumeType, *vs); + + frameSize = Size(vs->getRaycastWidth(), vs->getRaycastHeight()); + vs->getCameraIntegrateIntrinsics(intrIntegrate); + vs->getCameraRaycastIntrinsics(intrRaycast); + bool onlySemisphere = true; //TODO: check both + depthFactor = vs->getDepthFactor(); + lightPose = Vec3f::all(0.f); + scene = Scene::create(frameSize, intrIntegrate, depthFactor, onlySemisphere); + poses = scene->getPoses(); + + depth = scene->depth(poses[0]); + rgb = scene->rgb(poses[0]); + UMat udepth, urgb; + depth.copyTo(udepth); + rgb.copyTo(urgb); + + OdometryFrame odf(urgb, udepth); + + if (testSrcType == VolumeTestSrcType::MAT) + { + if (volumeType == VolumeType::ColorTSDF) + volume->integrate(udepth, urgb, poses[0].matrix); + else + volume->integrate(udepth, poses[0].matrix); + } + else if (testSrcType == VolumeTestSrcType::ODOMETRY_FRAME) + { + volume->integrate(odf, poses[0].matrix); + } } + void saveObj(std::string funcName, Mat points, Mat normals); + void raycast_test(); + void fetch_points_normals_test(); + void fetch_normals_test(); + void valid_points_test(); + bool gpu; VolumeType volumeType; + VolumeTestSrcType testSrcType; + FrameSizeType frameSizeSpecified; + OpenCLStatusRevert oclStatus; + + Ptr volume; + Ptr vs; + Size frameSize; + Matx33f intrIntegrate, intrRaycast; + Ptr scene; + std::vector poses; + float depthFactor; + Vec3f lightPose; + + Mat depth, rgb; }; -TEST_P(VolumeTestFixture, raycast_custom_framesize_normals_mat) +void VolumeTestFixture::saveObj(std::string funcName, Mat points, Mat normals) { - normal_test_custom_framesize(volumeType, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); + Mat pts3, nrm3; + cvtColor(points, pts3, COLOR_RGBA2RGB); + cvtColor(normals, nrm3, COLOR_RGBA2RGB); + string platformString = gpu ? "GPU" : "CPU"; + string volumeTypeString = volumeType == VolumeType::TSDF ? "TSDF" : + volumeType == VolumeType::HashTSDF ? "HashTSDF" : + volumeType == VolumeType::ColorTSDF ? "ColorTSDF" : ""; + string testSrcTypeString = testSrcType == VolumeTestSrcType::MAT ? "MAT" : + testSrcType == VolumeTestSrcType::ODOMETRY_FRAME ? "OFRAME" : ""; + string frameSizeSpecifiedString = frameSizeSpecified == FrameSizeType::DEFAULT ? "DefaultSize" : + frameSizeSpecified == FrameSizeType::CUSTOM ? "CustomSize" : ""; + savePointCloud(cv::format("pts_%s_%s_%s_%s_%s.obj", funcName.c_str(), platformString.c_str(), volumeTypeString.c_str(), + testSrcTypeString.c_str(), frameSizeSpecifiedString.c_str()), + pts3.reshape(3, 1), nrm3.reshape(3, 1)); } -//TODO: uncomment it when ColorTSDF gets GPU version -INSTANTIATE_TEST_CASE_P(VolumeCPU, VolumeTestFixture, /*::testing::Combine(PlatformTypeEnum::all(), VolumeTypeEnum::all())*/ +void VolumeTestFixture::raycast_test() +{ + UMat upoints, unormals, ucolors; + if (frameSizeSpecified == FrameSizeType::CUSTOM) + { + if (volumeType == VolumeType::ColorTSDF) + volume->raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, unormals, ucolors); + else + volume->raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, unormals); + } + else if (frameSizeSpecified == FrameSizeType::DEFAULT) + { + if (volumeType == VolumeType::ColorTSDF) + volume->raycast(poses[0].matrix, upoints, unormals, ucolors); + else + volume->raycast(poses[0].matrix, upoints, unormals); + } + + Mat points, normals, colors; + points = upoints.getMat(ACCESS_READ); + normals = unormals.getMat(ACCESS_READ); + colors = ucolors.getMat(ACCESS_READ); + + if (cvtest::debugLevel > 0) + { + if (volumeType == VolumeType::ColorTSDF) + displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); + else + displayImage(depth, points, normals, depthFactor, lightPose); + + saveObj("raycast", points, normals); + } + + normalsCheck(normals); +} + + +void VolumeTestFixture::fetch_normals_test() +{ + UMat upoints, unormals; + volume->fetchPointsNormals(upoints, noArray()); + + volume->fetchNormals(upoints, unormals); + + Mat points, normals; + points = upoints.getMat(ACCESS_READ); + normals = unormals.getMat(ACCESS_READ); + + if (cvtest::debugLevel > 0) + { + saveObj("fetch_normals", points, normals); + } + + normalsCheck(normals); +} + + +void VolumeTestFixture::fetch_points_normals_test() +{ + UMat upoints, unormals; + volume->fetchPointsNormals(upoints, unormals); + + Mat points, normals; + points = upoints.getMat(ACCESS_READ); + normals = unormals.getMat(ACCESS_READ); + + if (cvtest::debugLevel > 0) + { + saveObj("fetch_points_normals", points, normals); + } + + normalsCheck(normals); +} + + +void VolumeTestFixture::valid_points_test() +{ + UMat upoints, unormals, ucolors; + if (frameSizeSpecified == FrameSizeType::CUSTOM) + { + if (volumeType == VolumeType::ColorTSDF) + volume->raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, unormals, ucolors); + else + volume->raycast(poses[0].matrix, frameSize.height, frameSize.width, intrRaycast, upoints, unormals); + } + else if (frameSizeSpecified == FrameSizeType::DEFAULT) + { + if (volumeType == VolumeType::ColorTSDF) + volume->raycast(poses[0].matrix, upoints, unormals, ucolors); + else + volume->raycast(poses[0].matrix, upoints, unormals); + } + + Mat points, normals, colors; + points = upoints.getMat(ACCESS_READ); + normals = unormals.getMat(ACCESS_READ); + colors = ucolors.getMat(ACCESS_READ); + + patchNaNs(points); + int enface = counterOfValid(points); + + if (cvtest::debugLevel > 0) + { + if (volumeType == VolumeType::ColorTSDF) + displayColorImage(depth, rgb, points, normals, colors, depthFactor, lightPose); + else + displayImage(depth, points, normals, depthFactor, lightPose); + } + + UMat upoints2, unormals2, ucolors2; + Mat points2, normals2, colors2; + + if (frameSizeSpecified == FrameSizeType::CUSTOM) + { + if (volumeType == VolumeType::ColorTSDF) + volume->raycast(poses[17].matrix, frameSize.height, frameSize.width, intrRaycast, upoints2, unormals2, ucolors2); + else + volume->raycast(poses[17].matrix, frameSize.height, frameSize.width, intrRaycast, upoints2, unormals2); + } + else + { + if (volumeType == VolumeType::ColorTSDF) + volume->raycast(poses[17].matrix, upoints2, unormals2, ucolors2); + else + volume->raycast(poses[17].matrix, upoints2, unormals2); + } + + points2 = upoints2.getMat(ACCESS_READ); + normals2 = unormals2.getMat(ACCESS_READ); + colors2 = ucolors2.getMat(ACCESS_READ); + + patchNaNs(points2); + int profile = counterOfValid(points2); + + if (cvtest::debugLevel > 0) + { + if (volumeType == VolumeType::ColorTSDF) + displayColorImage(depth, rgb, points2, normals2, colors2, depthFactor, lightPose); + else + displayImage(depth, points2, normals2, depthFactor, lightPose); + } + + // TODO: why profile == 2*enface ? + float percentValidity = float(enface) / float(profile); + + ASSERT_GT(profile, 0) << "There are no points in profile"; + ASSERT_GT(enface, 0) << "There are no points in enface"; + ASSERT_LT(abs(0.5 - percentValidity), 0.05) << "percentValidity should be in range 45-55%, but it's " << percentValidity*100.f << "%"; +} + +TEST_P(VolumeTestFixture, valid_points) +{ + valid_points_test(); +} + +TEST_P(VolumeTestFixture, raycast_normals) +{ + raycast_test(); +} + +//TODO: this test should run just 1 time, not 4 +TEST_P(VolumeTestFixture, fetch_points_normals) +{ + fetch_points_normals_test(); +} +//TODO: this test should run just 1 time, not 4 +TEST_P(VolumeTestFixture, fetch_normals) +{ + fetch_normals_test(); +} + +//TODO: fix it when ColorTSDF gets GPU version +INSTANTIATE_TEST_CASE_P(Volume, VolumeTestFixture, /*::testing::Combine(PlatformTypeEnum::all(), VolumeTypeEnum::all())*/ + ::testing::Combine( ::testing::Values(PlatformVolumeType {PlatformType::CPU, VolumeType::TSDF}, PlatformVolumeType {PlatformType::CPU, VolumeType::HashTSDF}, PlatformVolumeType {PlatformType::CPU, VolumeType::ColorTSDF}, PlatformVolumeType {PlatformType::GPU, VolumeType::TSDF}, - PlatformVolumeType {PlatformType::GPU, VolumeType::HashTSDF})); - - -#ifdef HAVE_OPENCL -TEST(TSDF_CPU, raycast_custom_framesize_normals_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF_CPU, raycast_common_framesize_normals_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_common_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(TSDF_CPU, raycast_common_framesize_normals_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF_CPU, fetch_points_normals) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(TSDF_CPU, fetch_normals) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::TSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(TSDF_CPU, valid_points_custom_framesize_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_custom_framesize(VolumeType::TSDF, VolumeTestSrcType::MAT); -} - -TEST(TSDF_CPU, valid_points_custom_framesize_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_custom_framesize(VolumeType::TSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(TSDF_CPU, valid_points_common_framesize_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_common_framesize(VolumeType::TSDF, VolumeTestSrcType::MAT); -} - -TEST(TSDF_CPU, valid_points_common_framesize_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_common_framesize(VolumeType::TSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - - -TEST(HashTSDF_CPU, raycast_custom_framesize_normals_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_CPU, raycast_common_framesize_normals_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_CPU, raycast_common_framesize_normals_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_common_framesize(VolumeType::HashTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_CPU, fetch_points_normals) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_CPU, fetch_normals) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::HashTSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_CPU, valid_points_custom_framesize_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_custom_framesize(VolumeType::HashTSDF, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_CPU, valid_points_custom_framesize_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_custom_framesize(VolumeType::HashTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_CPU, valid_points_common_framesize_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_common_framesize(VolumeType::HashTSDF, VolumeTestSrcType::MAT); -} - -TEST(HashTSDF_CPU, valid_points_common_framesize_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_common_framesize(VolumeType::HashTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(HashTSDF_CPU, reproduce_volPoseRot) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - regressionVolPoseRot(); -} - - - -TEST(ColorTSDF_CPU, raycast_custom_framesize_normals_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(ColorTSDF_CPU, raycast_common_framesize_normals_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_common_framesize(VolumeType::ColorTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF_CPU, raycast_common_framesize_normals_frame) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_common_framesize(VolumeType::ColorTSDF, VolumeTestFunction::RAYCAST, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(ColorTSDF_CPU, fetch_normals) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestFunction::FETCH_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF_CPU, fetch_points_normals) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - normal_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestFunction::FETCH_POINTS_NORMALS, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF_CPU, valid_points_custom_framesize_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF_CPU, valid_points_custom_framesize_fetch) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_custom_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} - -TEST(ColorTSDF_CPU, valid_points_common_framesize_mat) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_common_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::MAT); -} - -TEST(ColorTSDF_CPU, valid_points_common_framesize_fetch) -{ - OpenCLStatusRevert oclStatus; - oclStatus.off(); - valid_points_test_common_framesize(VolumeType::ColorTSDF, VolumeTestSrcType::ODOMETRY_FRAME); -} + PlatformVolumeType {PlatformType::GPU, VolumeType::HashTSDF}), + VolumeTestSrcTypeEnum::all(), FrameSizeTypeEnum::all())); class StaticVolumeBoundingBox : public ::testing::TestWithParam @@ -1538,18 +1167,29 @@ TEST_P(StaticVolumeBoundingBox, staticBoundingBox) } //TODO: edit this list when ColorTSDF gets GPU support -INSTANTIATE_TEST_CASE_P(TSDF, StaticVolumeBoundingBox, ::testing::Values( +INSTANTIATE_TEST_CASE_P(Volume, StaticVolumeBoundingBox, ::testing::Values( PlatformVolumeType {PlatformType::CPU, VolumeType::TSDF}, PlatformVolumeType {PlatformType::CPU, VolumeType::ColorTSDF}, PlatformVolumeType {PlatformType::GPU, VolumeType::TSDF})); -// OpenCL tests -TEST(HashTSDF_GPU, reproduce_volPoseRot) +class ReproduceVolPoseRotTest : public ::testing::TestWithParam +{ }; + +TEST_P(ReproduceVolPoseRotTest, reproduce_volPoseRot) { + bool gpu = bool(GetParam()); + + OpenCLStatusRevert oclStatus; + + if (!gpu) + oclStatus.off(); + regressionVolPoseRot(); } +INSTANTIATE_TEST_CASE_P(Volume, ReproduceVolPoseRotTest, PlatformTypeEnum::all()); + enum Growth { @@ -1574,8 +1214,7 @@ TEST_P(BoundingBoxEnableGrowthTest, boundingBoxEnableGrowth) boundingBoxGrowthTest(enableGrowth); } -INSTANTIATE_TEST_CASE_P(TSDF, BoundingBoxEnableGrowthTest, ::testing::Combine(PlatformTypeEnum::all(), GrowthEnum::all())); +INSTANTIATE_TEST_CASE_P(Volume, BoundingBoxEnableGrowthTest, ::testing::Combine(PlatformTypeEnum::all(), GrowthEnum::all())); -#endif } } // namespace