cv::Feature2D::compute called with empty std::vector<cv::KeyPoint> [closed]

I have a visual odometry routine that computes matches between the current frame and the previous frame. If keypoints are detected, a call to compute returns a descriptor cv::Mat of size (WxH)=(64xNumKeyPoints). This is expected. However, if called with an empty vector of keypoints, instead of returning an empty cv::Mat (with size (WxH)=(0x0)), the descriptor cv::Mat has size (WxH)=(64x1). This means that passing this to a matcher yields a match where the indices of cv::DMatch are invalid as using these indices results in an out-of-bounds access into the empty vector of keypoints.

Obviously, I can work around this, but for code simplicity with minimal conditionals and branching, this behavior is undesirable. When called with zero cv::KeyPoints, compute should set the passed in cv::Mat to be empty, such that when passed to a matcher, zero matches are found.

I am reusing objects (current frame data are assigned/swapped/copied to previous frame data). If I find that no features/keypoints are detected, what would be the best way to signify this to the matcher? How do I best unset the size of the descriptor cv::Mat or set it to empty? Is "releasing" the descriptor cv::Mat the proper way to "empty" it?

To summarize, I want a constant uninterrupted pipeline: detect->extract->match to yield zero matches when zero keypoints are detected.

My descriptor extractor is cv::xfeatures2d::FREAK. My matcher is cv::BFMatcher.

edit retag reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by Der Luftmensch close date 2016-11-13 18:12:38.233675

Sort by » oldest newest most voted

Cannot reproduce. Can you provide more details? Did you build it yourself, which version, x64/x86, platform, compiler ect. ect.

Mat img(1000, 1000, CV_8UC3);
vector<KeyPoint> kps;
auto pFREAK = xfeatures2d::FREAK::create();
Mat desc;
pFREAK->compute(img, kps, desc);
std::cout << desc.rows << "  " << desc.cols << "\n";


result: 0 0

more

1

Thanks for your response. I see this when the descriptor cv::Mat passed into the function has data already. So, not a new/uninitialized, cv::Mat, but one with "old" data. This old data is not removed when there are zero keypoints. Perhaps this isn't really a bug, it's on the user (me) to check for these conditions and probably the real solution is not to reuse the objects, but to create new descriptor matrices every time a frame is processed as there is no benefit to reuse.

( 2016-11-13 18:12:05 -0500 )edit