mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-07 02:27:47 +08:00
fixing octave scaling when decimating image in Memory
This commit is contained in:
@@ -5660,7 +5660,11 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
if(_imagePreDecimation > 1 || useProvided3dPoints)
|
||||
{
|
||||
float decimationRatio = 1.0f / float(_imagePreDecimation);
|
||||
double log2value = log(double(_imagePreDecimation))/log(2.0);
|
||||
// The octave a feature was found at moves with the image it is
|
||||
// expressed in, by the same ratio as its position: a decimated
|
||||
// image is already that many pyramid levels down, so scaling the
|
||||
// keypoints into it lowers their octave.
|
||||
double log2value = log(double(decimationRatio))/log(2.0);
|
||||
for(unsigned int i=0; i < keypoints.size(); ++i)
|
||||
{
|
||||
cv::KeyPoint & kpt = keypoints[i];
|
||||
@@ -6246,7 +6250,10 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
UASSERT(keypoints3D.size() == 0 || keypoints3D.size() == wordIds.size());
|
||||
unsigned int i=0;
|
||||
float decimationRatio = float(preDecimation) / float(_imagePostDecimation);
|
||||
double log2value = log(double(preDecimation))/log(2.0);
|
||||
// Same ratio the positions are remapped by, which is what keeps a keypoint at
|
||||
// the scale it was found at: log2(pre/post), and not log2(pre), those two
|
||||
// agreeing only when the final image is not decimated at all.
|
||||
double log2value = log(double(decimationRatio))/log(2.0);
|
||||
for(std::list<int>::iterator iter=wordIds.begin(); iter!=wordIds.end() && i < keypoints.size(); ++iter, ++i)
|
||||
{
|
||||
cv::KeyPoint kpt = keypoints[i];
|
||||
|
||||
@@ -2844,6 +2844,53 @@ TEST_F(MemoryFixture, CreateSignatureAutoIncrementsIdWhenGenerateIdsOn)
|
||||
EXPECT_EQ(memory_->getLastSignatureId(), id1 + 1);
|
||||
}
|
||||
|
||||
TEST(MemoryTest, PreDecimationGivesBackProvidedKeypointsAsTheyCameIn)
|
||||
{
|
||||
// Keypoints provided with the frame are found in the full size image, so
|
||||
// createSignature scales them into the pre-decimated one it describes them in, and
|
||||
// scales them back to the final image size afterwards. With no post-decimation the
|
||||
// two undo each other, which is the whole of what this test knows: what comes out is
|
||||
// what went in, the octave included -- it moves down with the image and back up
|
||||
// again, a decimated image being that many pyramid levels down already.
|
||||
ParametersMap params = defaultMemoryParams();
|
||||
params[Parameters::kKpMaxFeatures()] = "100"; // let descriptors be extracted
|
||||
params[Parameters::kMemUseOdomFeatures()] = "true";
|
||||
params[Parameters::kMemImagePreDecimation()] = "2";
|
||||
params[Parameters::kMemImagePostDecimation()] = "1";
|
||||
params[Parameters::kRtabmapImagesAlreadyRectified()] = "true"; // skip rectification
|
||||
Memory memory(params);
|
||||
|
||||
// Big enough that the keypoint stays far from the border of the decimated image,
|
||||
// where a descriptor cannot be computed and the keypoint would be dropped.
|
||||
cv::Mat image(256, 256, CV_8UC1);
|
||||
cv::RNG rng(7);
|
||||
rng.fill(image, cv::RNG::UNIFORM, 0, 255);
|
||||
const cv::Mat covariance = cv::Mat::eye(6, 6, CV_64FC1) * 0.01;
|
||||
const CameraModel model(100.0, 100.0, 128.0, 128.0,
|
||||
CameraModel::opticalRotation(), 0.0, cv::Size(256, 256));
|
||||
|
||||
SensorData data;
|
||||
data.setRGBDImage(image, cv::Mat(), std::vector<CameraModel>{model});
|
||||
data.setId(0);
|
||||
|
||||
// No descriptors: that is what sends createSignature down the branch where the
|
||||
// provided keypoints are described from the image rather than taken wholesale.
|
||||
cv::KeyPoint kpt(128.0f, 120.0f, 8.0f);
|
||||
kpt.octave = 2;
|
||||
data.setFeatures(std::vector<cv::KeyPoint>(1, kpt),
|
||||
std::vector<cv::Point3f>(1, cv::Point3f(0.0f, 0.0f, 1.0f)),
|
||||
cv::Mat());
|
||||
|
||||
ASSERT_TRUE(memory.update(data, Transform(0, 0, 0, 0, 0, 0), covariance));
|
||||
const Signature * s = memory.getSignature(memory.getLastSignatureId());
|
||||
ASSERT_NE(s, nullptr);
|
||||
ASSERT_EQ(s->getWordsKpts().size(), 1u);
|
||||
EXPECT_FLOAT_EQ(s->getWordsKpts()[0].pt.x, kpt.pt.x);
|
||||
EXPECT_FLOAT_EQ(s->getWordsKpts()[0].pt.y, kpt.pt.y);
|
||||
EXPECT_FLOAT_EQ(s->getWordsKpts()[0].size, kpt.size);
|
||||
EXPECT_EQ(s->getWordsKpts()[0].octave, kpt.octave);
|
||||
}
|
||||
|
||||
TEST(MemoryTest, CreateSignaturePostDecimatesImageWhenPostDecimationGreaterThanOne)
|
||||
{
|
||||
// kMemImagePostDecimation > 1 causes createSignature to downsample the RGB image
|
||||
|
||||
Reference in New Issue
Block a user