Skip to content

Commit

Permalink
Merge pull request #980 from alicevision/dev/crossMatching
Browse files Browse the repository at this point in the history
[matching] implement cross check for feature matching
  • Loading branch information
fabiencastan authored Feb 19, 2021
2 parents 90e4053 + c1dc5d8 commit 819608d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 8 deletions.
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;
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

0 comments on commit 819608d

Please sign in to comment.