Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[matching] implement cross check for feature matching #980

Merged
merged 1 commit into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ using namespace aliceVision::matching;
using namespace aliceVision::feature;

ImageCollectionMatcher_generic::ImageCollectionMatcher_generic(
float distRatio, EMatcherType matcherType)
float distRatio, bool crossMatching, EMatcherType matcherType)
: IImageCollectionMatcher()
, _f_dist_ratio(distRatio)
, _useCrossMatching(crossMatching)
, _matcherType(matcherType)
{
}
Expand Down Expand Up @@ -85,6 +86,37 @@ void ImageCollectionMatcher_generic::Match(

IndMatches vec_putatives_matches;
matcher.Match(_f_dist_ratio, regionsJ, vec_putatives_matches);

if (_useCrossMatching)
{
// Initialize the matching interface
matching::RegionsDatabaseMatcher matcherCross(randomNumberGenerator, _matcherType, regionsJ);

IndMatches vec_putatives_matches_cross;
matcherCross.Match(_f_dist_ratio, regionsI, vec_putatives_matches_cross);

//Create a dictionnary of matches indexed by their pair of indexes
std::map<std::pair<int, int>, IndMatch> check_matches;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use existing code for this. See here https://github.com/alicevision/AliceVision/blob/develop/src/aliceVision/matching/filters.hpp. Symmetric matches filtering

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • This function requires multiple conversions before input, and after output.
  • It requires to build 3 vectors the size of the features sets even if the amount of matches is very low

Copy link
Member

@fabiencastan fabiencastan Feb 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not look into the details but the ability to use nndistanceratio or symmetric or combine both may be interesting to expose.

for (IndMatch & m : vec_putatives_matches_cross)
{
std::pair<int, int> key = std::make_pair(m._i, m._j);
check_matches[key] = m;
}

IndMatches vec_putatives_matches_checked;
for (IndMatch & m : vec_putatives_matches)
{
//Check with reversed key (images are swapped)
std::pair<int, int> key = std::make_pair(m._j, m._i);
if (check_matches.find(key) != check_matches.end())
{
vec_putatives_matches_checked.push_back(m);
}
}

std::swap(vec_putatives_matches, vec_putatives_matches_checked);
}

#pragma omp critical
{
++my_progress_bar;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ImageCollectionMatcher_generic : public IImageCollectionMatcher
public:
ImageCollectionMatcher_generic(
float dist_ratio,
bool crossMatching,
matching::EMatcherType matcherType
);

Expand All @@ -40,6 +41,8 @@ class ImageCollectionMatcher_generic : public IImageCollectionMatcher
private:
// Distance ratio used to discard spurious correspondence
float _f_dist_ratio;
// Do we use cross matching (Symmetric matching test) ?
bool _useCrossMatching;
// Matcher Type
matching::EMatcherType _matcherType;
};
Expand Down
10 changes: 5 additions & 5 deletions src/aliceVision/matchingImageCollection/matchingCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ namespace aliceVision {
namespace matchingImageCollection {


std::unique_ptr<IImageCollectionMatcher> createImageCollectionMatcher(matching::EMatcherType matcherType, float distRatio)
std::unique_ptr<IImageCollectionMatcher> createImageCollectionMatcher(matching::EMatcherType matcherType, float distRatio, bool crossMatching)
{
std::unique_ptr<IImageCollectionMatcher> matcherPtr;

switch(matcherType)
{
case matching::BRUTE_FORCE_L2: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, matching::BRUTE_FORCE_L2)); break;
case matching::ANN_L2: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, matching::ANN_L2)); break;
case matching::CASCADE_HASHING_L2: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, matching::CASCADE_HASHING_L2)); break;
case matching::BRUTE_FORCE_L2: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, crossMatching, matching::BRUTE_FORCE_L2)); break;
case matching::ANN_L2: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, crossMatching, matching::ANN_L2)); break;
case matching::CASCADE_HASHING_L2: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, crossMatching, matching::CASCADE_HASHING_L2)); break;
case matching::FAST_CASCADE_HASHING_L2: matcherPtr.reset(new ImageCollectionMatcher_cascadeHashing(distRatio)); break;
case matching::BRUTE_FORCE_HAMMING: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, matching::BRUTE_FORCE_HAMMING)); break;
case matching::BRUTE_FORCE_HAMMING: matcherPtr.reset(new ImageCollectionMatcher_generic(distRatio, crossMatching, matching::BRUTE_FORCE_HAMMING)); break;

default: throw std::out_of_range("Invalid matcherType enum");
}
Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/matchingImageCollection/matchingCommon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace matchingImageCollection {
* @param matcherType
* @return
*/
std::unique_ptr<IImageCollectionMatcher> createImageCollectionMatcher(matching::EMatcherType matcherType, float distRatio);
std::unique_ptr<IImageCollectionMatcher> createImageCollectionMatcher(matching::EMatcherType matcherType, float distRatio, bool crossMatching);


} // namespace matching
Expand Down
7 changes: 6 additions & 1 deletion src/software/pipeline/main_featureMatching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ int aliceVision_main(int argc, char **argv)
double knownPosesGeometricErrorMax = 4.0;
bool savePutativeMatches = false;
bool guidedMatching = false;
bool crossMatching = false;
int maxIteration = 2048;
bool matchFilePerImage = false;
size_t numMatchesToKeep = 0;
Expand Down Expand Up @@ -170,6 +171,8 @@ int aliceVision_main(int argc, char **argv)
"Save putative matches.")
("guidedMatching", po::value<bool>(&guidedMatching)->default_value(guidedMatching),
"Use the found model to improve the pairwise correspondences.")
("crossMatching", po::value<bool>(&crossMatching)->default_value(crossMatching),
"Make sure that the matching process is symmetric (same matches for I->J than fo J->I).")
("matchFilePerImage", po::value<bool>(&matchFilePerImage)->default_value(matchFilePerImage),
"Save matches in a separate file per image.")
("distanceRatio", po::value<float>(&distRatio)->default_value(distRatio),
Expand Down Expand Up @@ -273,6 +276,8 @@ int aliceVision_main(int argc, char **argv)
PairSet pairs;
std::set<IndexT> filter;


// We assume that there is only one pair for (I,J) and (J,I)
if(predefinedPairList.empty())
{
pairs = exhaustivePairs(sfmData.getViews(), rangeStart, rangeSize);
Expand Down Expand Up @@ -307,7 +312,7 @@ int aliceVision_main(int argc, char **argv)

// allocate the right Matcher according the Matching requested method
EMatcherType collectionMatcherType = EMatcherType_stringToEnum(nearestMatchingMethod);
std::unique_ptr<IImageCollectionMatcher> imageCollectionMatcher = createImageCollectionMatcher(collectionMatcherType, distRatio);
std::unique_ptr<IImageCollectionMatcher> imageCollectionMatcher = createImageCollectionMatcher(collectionMatcherType, distRatio, crossMatching);

const std::vector<feature::EImageDescriberType> describerTypes = feature::EImageDescriberType_stringToEnums(describerTypesName);

Expand Down