#include #include #include "gtest/gtest.h" #include "test_utils.h" void setImageData(uint16_t *imageArray, int size) { double norm = RAND_MAX; norm /= (double)std::numeric_limits::max(); for (int i = 0; i < size; i++) { imageArray[i] = (unsigned char)(rand() / norm); } } TEST(Pattern, ImageInterp) { Eigen::Vector2d offset(231.234242, 123.23424); basalt::ManagedImage img(640, 480); setImageData(img.ptr, img.size()); Eigen::Vector3d vg = img.interpGrad(offset); Eigen::Matrix J = vg.tail<2>(); // std::cerr << "vg\n" << vg << std::endl; test_jacobian("d_val_d_p", J, [&](const Eigen::Vector2d &x) { Eigen::Matrix res; Eigen::Vector2d p1 = offset + x; res[0] = img.interpGrad(p1)[0]; return res; }, Eigen::Vector2d::Zero(), 1.0); } TEST(Image, ImageInterpolate) { Eigen::Vector2i offset(231, 123); basalt::ManagedImage img(640, 480); setImageData(img.ptr, img.size()); double eps = 1e-12; double threshold = 1e-8; { Eigen::Vector2i pi = offset; Eigen::Vector2d pd = pi.cast() + Eigen::Vector2d(eps, eps); uint16_t val1 = img(pi); double val2 = img.interp(pd); double val3 = img.interpGrad(pd)[0]; EXPECT_LE(std::abs(val2 - val1), threshold); EXPECT_FLOAT_EQ(val2, val3); } { Eigen::Vector2i pi = offset; Eigen::Vector2d pd = pi.cast() + Eigen::Vector2d(eps, eps); uint16_t val1 = img(pi); double val2 = img.interp(pd); double val3 = img.interpGrad(pd)[0]; EXPECT_LE(std::abs(val2 - val1), threshold); EXPECT_FLOAT_EQ(val2, val3); } { Eigen::Vector2i pi = offset + Eigen::Vector2i(1, 0); Eigen::Vector2d pd = pi.cast() + Eigen::Vector2d(-eps, eps); uint16_t val1 = img(pi); double val2 = img.interp(pd); double val3 = img.interpGrad(pd)[0]; EXPECT_LE(std::abs(val2 - val1), threshold); EXPECT_FLOAT_EQ(val2, val3); } { Eigen::Vector2i pi = offset + Eigen::Vector2i(0, 1); Eigen::Vector2d pd = pi.cast() + Eigen::Vector2d(eps, -eps); uint16_t val1 = img(pi); double val2 = img.interp(pd); double val3 = img.interpGrad(pd)[0]; EXPECT_LE(std::abs(val2 - val1), threshold); EXPECT_FLOAT_EQ(val2, val3); } { Eigen::Vector2i pi = offset + Eigen::Vector2i(1, 1); Eigen::Vector2d pd = pi.cast() + Eigen::Vector2d(-eps, -eps); uint16_t val1 = img(pi); double val2 = img.interp(pd); double val3 = img.interpGrad(pd)[0]; EXPECT_LE(std::abs(val2 - val1), threshold); EXPECT_FLOAT_EQ(val2, val3); } } TEST(Image, ImageInterpolateGrad) { Eigen::Vector2i offset(231, 123); basalt::ManagedImage img(640, 480); setImageData(img.ptr, img.size()); Eigen::Vector2d pd = offset.cast() + Eigen::Vector2d(0.4, 0.34345); Eigen::Vector3d valGrad = img.interpGrad(pd); Eigen::Matrix J = valGrad.tail<2>(); test_jacobian( "d_res_d_x", J, [&](const Eigen::Vector2d &x) { return Eigen::Matrix(img.interp(pd + x)); }, Eigen::Vector2d::Zero(), 1); }