Extend BruteForce search to non-XYZ point types - #6457
Conversation
Signed-off-by: jeevan6996 <jeevanpawar5890@gmail.com>
|
The CI linker failures were caused by Updated |
| if constexpr (!pcl::traits::has_xyz_v<PointT> && has_descriptor_size<PointT>::value) | ||
| return (pcl::make_shared<DefaultFeatureRepresentation<PointT>> ()); | ||
| else | ||
| return (pcl::make_shared<DefaultPointRepresentation<PointT>> ()); |
There was a problem hiding this comment.
Thanks for this pull request. Could you please explain why you did this condition, since none of the other search methods do it like this?
|
Thanks. I checked the other search implementations and they default to This condition is intentional for BruteForce’s new non-XYZ descriptor support: types with |
| template <typename PointT> bool | ||
| pcl::search::BruteForce<PointT>::isValidPoint (const PointT& point) const | ||
| { | ||
| if constexpr (pcl::traits::has_xyz_v<PointT>) |
There was a problem hiding this comment.
The new custom-representation path is not used by isValidPoint() for point types with XYZ traits:
if constexpr (pcl::traits::has_xyz_v<PointT>)
return (pcl::isFinite (point));This still validates x/y/z even when setPointRepresentation() installs a representation that intentionally uses a different subset of fields. For example, a representation that uses only x/y should be able to search a point whose z is NaN, but this causes the query assertion to fail (and causes sparse searches to skip the point). This also differs from the representation-based validity behavior used by the other search implementations.
Could this use point_representation_->isValid(point) consistently, with a regression test using a custom representation that ignores an invalid XYZ field?
There was a problem hiding this comment.
Sounds good to me, then there is even no point in having the isValidPoint function, instead point_representation_->isValid(point) can be checked inline.
I just checked all types for which specializations of But I have also identified four types which are missing a specialization of template <>
class DefaultPointRepresentation<GRSDSignature21> : public DefaultFeatureRepresentation <GRSDSignature21>
{};
template <>
class DefaultPointRepresentation<BRISKSignature512> : public DefaultFeatureRepresentation <BRISKSignature512>
{};
template <>
class DefaultPointRepresentation<ESFSignature640> : public DefaultFeatureRepresentation <ESFSignature640>
{};
template <>
class DefaultPointRepresentation<GFPFHSignature16> : public DefaultFeatureRepresentation <GFPFHSignature16>
{};Can you do that? Thanks. |
|
Please also change 512 to 66 here, then the tests should pass: pcl/common/include/pcl/impl/point_types.hpp Line 169 in 4dd5652 Seems like there has been a mistake when |
| public: | ||
| BruteForce (bool sorted_results = false) | ||
| : Search<PointT> ("BruteForce", sorted_results) | ||
| , point_representation_ (detail::makeDefaultPointRepresentation<PointT> ()) |
There was a problem hiding this comment.
| , point_representation_ (detail::makeDefaultPointRepresentation<PointT> ()) | |
| , point_representation_ (new DefaultPointRepresentation<PointT>) |
I think there is not really a point in having the makeDefaultPointRepresentation function any more, so I would suggest removing it.
| template<> struct descriptorSize<VFHSignature308> { static constexpr const int value = 308; }; | ||
| template<> struct descriptorSize<GRSDSignature21> { static constexpr const int value = 21; }; | ||
| template<> struct descriptorSize<BRISKSignature512> { static constexpr const int value = 512; }; | ||
| template<> struct descriptorSize<BRISKSignature512> { static constexpr const int value = 66; }; |
There was a problem hiding this comment.
Shouldn't it be [64] ?(
pcl/common/include/pcl/impl/point_types.hpp
Line 1446 in 4dd5652
There was a problem hiding this comment.
Yes, originally it was 64 (before it was mistakenly changed to 512). But in addition to the descriptor, BRISKSignature512 also has two floats scale and orientation. I am not familiar enough with BRISK to say for sure, whether scale and orientation should be considered or not when searching for similar descriptors. But if we say they should not be included, we cannot simply inherit from DefaultFeatureRepresentation but have to write a custom DefaultPointRepresentation specialization for BRISKSignature512 (similar to DefaultPointRepresentation <Narf36>, for example).
There was a problem hiding this comment.
When I look at the other features, there are also some which has additional fields beyond the array descriptors, which most of these sizes represents?
But keeping it at 66 for BRISKSignature512 in this PR - would lead to out-of-bounds reads, if one iterates over the array with the size given from descriptorSize?
There was a problem hiding this comment.
Okay, then let's use 64, and the following in point_representation.h:
template <>
class DefaultPointRepresentation <BRISKSignature512> : public PointRepresentation <BRISKSignature512>
{
public:
static constexpr const std::int32_t NR_DIMS = 64;
DefaultPointRepresentation ()
{
nr_dimensions_ = NR_DIMS;
trivial_ = false;
}
void
copyToFloatArray (const BRISKSignature512 &p, float * out) const override
{
for (int i = 0; i < nr_dimensions_; ++i)
out[i] = p.descriptor[i];
}
};
Summary
Fixes #6421.
Validation
cmake --build /private/tmp/pcl-bruteforce-build-6 --target test_brute_force_searchctest --test-dir /private/tmp/pcl-bruteforce-build-6/test -R brute_force_search --output-on-failuregit diff --check