Skip to content

Commit 18599f4

Browse files
authored
Merge pull request #1730 from alicevision/dev/sfmMatching
Multiple shots: Align and merge multiple SfM from feature matches
2 parents c4e2916 + 9ea4685 commit 18599f4

File tree

5 files changed

+449
-39
lines changed

5 files changed

+449
-39
lines changed

src/aliceVision/sfm/utils/alignment.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,75 @@ bool computeSimilarityFromCommonMarkers(const sfmData::SfMData& sfmDataA,
541541
return true;
542542
}
543543

544+
bool computeSimilarityFromCommonLandmarks(const sfmData::SfMData& sfmDataA,
545+
const sfmData::SfMData& sfmDataB,
546+
std::mt19937& randomNumberGenerator,
547+
double* out_S,
548+
Mat3* out_R,
549+
Vec3* out_t)
550+
{
551+
//create map featureId, landmarkId
552+
std::map<IndexT, IndexT> mapFeatureIdToLandmarkId;
553+
for (const auto & plandmark : sfmDataA.getLandmarks())
554+
{
555+
for (const auto & pobs : plandmark.second.getObservations())
556+
{
557+
IndexT featureId = pobs.second.getFeatureId();
558+
mapFeatureIdToLandmarkId[featureId] = plandmark.first;
559+
}
560+
}
561+
562+
std::map<IndexT, IndexT> mapLandmarkAtoLandmarkB;
563+
for (const auto & plandmark : sfmDataB.getLandmarks())
564+
{
565+
for (const auto & pobs : plandmark.second.getObservations())
566+
{
567+
IndexT featureId = pobs.second.getFeatureId();
568+
569+
auto found = mapFeatureIdToLandmarkId.find(featureId);
570+
if (found == mapFeatureIdToLandmarkId.end())
571+
{
572+
continue;
573+
}
574+
575+
mapLandmarkAtoLandmarkB[found->second] = plandmark.first;
576+
}
577+
}
578+
579+
// Move input point in appropriate container
580+
Mat xA(3, mapLandmarkAtoLandmarkB.size());
581+
Mat xB(3, mapLandmarkAtoLandmarkB.size());
582+
583+
int count = 0;
584+
for (auto & pair : mapLandmarkAtoLandmarkB)
585+
{
586+
xA.col(count) = sfmDataA.getLandmarks().at(pair.first).X;
587+
xB.col(count) = sfmDataB.getLandmarks().at(pair.second).X;
588+
count++;
589+
}
590+
591+
// Compute rigid transformation p'i = S R pi + t
592+
double S;
593+
Vec3 t;
594+
Mat3 R;
595+
std::vector<std::size_t> inliers;
596+
597+
if (!aliceVision::geometry::ACRansac_FindRTS(xA, xB, randomNumberGenerator, S, t, R, inliers, true))
598+
{
599+
std::cout << "merde" << std::endl;
600+
return false;
601+
}
602+
603+
ALICEVISION_LOG_DEBUG("There are " << mapLandmarkAtoLandmarkB.size() << " common markers and " << inliers.size()
604+
<< " were used to compute the similarity transform.");
605+
606+
*out_S = S;
607+
*out_R = R;
608+
*out_t = t;
609+
610+
return true;
611+
}
612+
544613
/**
545614
* Image orientation CCW
546615
*/

src/aliceVision/sfm/utils/alignment.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ bool computeSimilarityFromCommonMarkers(const sfmData::SfMData& sfmDataA,
120120
Mat3* out_R,
121121
Vec3* out_t);
122122

123+
bool computeSimilarityFromCommonLandmarks(const sfmData::SfMData& sfmDataA,
124+
const sfmData::SfMData& sfmDataB,
125+
std::mt19937& randomNumberGenerator,
126+
double* out_S,
127+
Mat3* out_R,
128+
Vec3* out_t);
129+
123130
/**
124131
* @brief Apply a transformation the given SfMData
125132
*

src/software/utils/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ if(ALICEVISION_BUILD_SFM)
211211
aliceVision_cmdline
212212
aliceVision_sfmData
213213
aliceVision_sfmDataIO
214+
aliceVision_sfm
215+
aliceVision_matching
214216
Boost::program_options
215217
)
216218

src/software/utils/main_sfmAlignment.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ enum class EAlignmentMethod : unsigned char
3838
FROM_CAMERAS_POSEID,
3939
FROM_CAMERAS_FILEPATH,
4040
FROM_CAMERAS_METADATA,
41-
FROM_MARKERS
41+
FROM_MARKERS,
42+
FROM_LANDMARKS,
4243
};
4344

4445
/**
@@ -60,6 +61,8 @@ std::string EAlignmentMethod_enumToString(EAlignmentMethod alignmentMethod)
6061
return "from_cameras_metadata";
6162
case EAlignmentMethod::FROM_MARKERS:
6263
return "from_markers";
64+
case EAlignmentMethod::FROM_LANDMARKS:
65+
return "from_landmarks";
6366
}
6467
throw std::out_of_range("Invalid EAlignmentMethod enum");
6568
}
@@ -84,6 +87,8 @@ EAlignmentMethod EAlignmentMethod_stringToEnum(const std::string& alignmentMetho
8487
return EAlignmentMethod::FROM_CAMERAS_METADATA;
8588
if (method == "from_markers")
8689
return EAlignmentMethod::FROM_MARKERS;
90+
if (method == "from_landmarks")
91+
return EAlignmentMethod::FROM_LANDMARKS;
8792
throw std::out_of_range("Invalid SfM alignment method : " + alignmentMethod);
8893
}
8994

@@ -130,6 +135,7 @@ int aliceVision_main(int argc, char** argv)
130135
"\t- from_cameras_poseid: Align cameras with same pose ID.\n"
131136
"\t- from_cameras_filepath: Align cameras with a filepath matching, using --fileMatchingPattern.\n"
132137
"\t- from_cameras_metadata: Align cameras with matching metadata, using --metadataMatchingList.\n"
138+
"\t- from_landmarks: Alilgn using landmarks sharing features.\n"
133139
"\t- from_markers: Align from markers with the same ID.\n")
134140
("fileMatchingPattern", po::value<std::string>(&fileMatchingPattern)->default_value(fileMatchingPattern),
135141
"Matching pattern for the from_cameras_filepath method.\n")
@@ -207,6 +213,11 @@ int aliceVision_main(int argc, char** argv)
207213
hasValidSimilarity = sfm::computeSimilarityFromCommonMarkers(sfmData, sfmDataInRef, randomNumberGenerator, &S, &R, &t);
208214
break;
209215
}
216+
case EAlignmentMethod::FROM_LANDMARKS:
217+
{
218+
hasValidSimilarity = sfm::computeSimilarityFromCommonLandmarks(sfmData, sfmDataInRef, randomNumberGenerator, &S, &R, &t);
219+
break;
220+
}
210221
}
211222

212223
if (!hasValidSimilarity)

0 commit comments

Comments
 (0)