Skip to content

Commit 6a93873

Browse files
author
Fabien Servant
committed
filter exported matches
1 parent 91e0769 commit 6a93873

File tree

1 file changed

+108
-38
lines changed

1 file changed

+108
-38
lines changed

src/software/export/main_exportMatches.cpp

Lines changed: 108 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ int aliceVision_main(int argc, char** argv)
8787
std::string outputFolder;
8888
std::vector<std::string> featuresFolders;
8989
std::vector<std::string> matchesFolders;
90+
std::string filterA = "";
91+
std::string filterB = "";
9092

9193
// user optional parameters
9294

@@ -107,7 +109,9 @@ int aliceVision_main(int argc, char** argv)
107109
po::options_description optionalParams("Optional parameters");
108110
optionalParams.add_options()
109111
("describerTypes,d", po::value<std::string>(&describerTypesName)->default_value(describerTypesName),
110-
EImageDescriberType_informations().c_str());
112+
EImageDescriberType_informations().c_str())
113+
("filterA", po::value<std::string>(&filterA)->default_value(filterA), "Restrict one of the two views to be this.")
114+
("filterB", po::value<std::string>(&filterB)->default_value(filterB), "Restrict one of the two views to be this.");
111115
// clang-format on
112116

113117
CmdLine cmdline("AliceVision exportMatches");
@@ -118,6 +122,7 @@ int aliceVision_main(int argc, char** argv)
118122
return EXIT_FAILURE;
119123
}
120124

125+
//Make sure we have somewhere to write images
121126
if (outputFolder.empty())
122127
{
123128
ALICEVISION_LOG_ERROR("It is an invalid output folder");
@@ -131,9 +136,35 @@ int aliceVision_main(int argc, char** argv)
131136
ALICEVISION_LOG_ERROR("The input SfMData file '" << sfmDataFilename << "' cannot be read.");
132137
return EXIT_FAILURE;
133138
}
139+
140+
//Create filters from input parameters
141+
IndexT indexFilterA = UndefinedIndexT;
142+
IndexT indexFilterB = UndefinedIndexT;
134143

135-
// load SfM Scene regions
144+
if (!filterA.empty() || !filterB.empty())
145+
{
146+
if (!filterA.empty())
147+
{
148+
indexFilterA = sfmData.findView(filterA);
149+
if (indexFilterA == UndefinedIndexT)
150+
{
151+
ALICEVISION_LOG_ERROR("Could not find corresponding view for : " + filterA);
152+
return EXIT_FAILURE;
153+
}
154+
}
155+
156+
if (!filterB.empty())
157+
{
158+
indexFilterB = sfmData.findView(filterB);
159+
if (indexFilterB == UndefinedIndexT)
160+
{
161+
ALICEVISION_LOG_ERROR("Could not find corresponding view for : " + filterB);
162+
return EXIT_FAILURE;
163+
}
164+
}
165+
}
136166

167+
// load SfM Scene regions
137168
// get imageDescriberMethodType
138169
std::vector<EImageDescriberType> describerMethodTypes = EImageDescriberType_stringToEnums(describerTypesName);
139170

@@ -164,87 +195,126 @@ int aliceVision_main(int argc, char** argv)
164195
const std::size_t I = iter->first;
165196
const std::size_t J = iter->second;
166197

167-
const View* viewI = sfmData.getViews().at(I).get();
168-
const View* viewJ = sfmData.getViews().at(J).get();
169198

170-
const std::string viewImagePathI = viewI->getImage().getImagePath();
171-
const std::string viewImagePathJ = viewJ->getImage().getImagePath();
199+
//Apply filter A
200+
if (indexFilterA != UndefinedIndexT)
201+
{
202+
if (I != indexFilterA && J != indexFilterA)
203+
{
204+
continue;
205+
}
206+
}
207+
208+
//Apply filter B
209+
if (indexFilterB != UndefinedIndexT)
210+
{
211+
if (I != indexFilterB && J != indexFilterB)
212+
{
213+
continue;
214+
}
215+
}
216+
217+
const View & viewI = sfmData.getView(I);
218+
const View & viewJ = sfmData.getView(J);
219+
220+
const std::string viewImagePathI = viewI.getImage().getImagePath();
221+
const std::string viewImagePathJ = viewJ.getImage().getImagePath();
172222

173-
std::string destFilename_I;
174-
std::string destFilename_J;
223+
std::string destFilenameI;
224+
std::string destFilenameJ;
175225
{
176226
fs::path origImgPath(viewImagePathI);
177227
std::string origFilename = origImgPath.stem().string();
178228
image::Image<image::RGBfColor> originalImage;
179229
image::readImage(viewImagePathI, originalImage, image::EImageColorSpace::LINEAR);
180-
destFilename_I = (fs::path(outputFolder) / (origFilename + ".png")).string();
181-
image::writeImage(destFilename_I, originalImage, image::ImageWriteOptions().toColorSpace(image::EImageColorSpace::SRGB));
230+
destFilenameI = (fs::path(outputFolder) / (origFilename + ".png")).string();
231+
image::writeImage(destFilenameI, originalImage, image::ImageWriteOptions().toColorSpace(image::EImageColorSpace::SRGB));
182232
}
183233

184234
{
185235
fs::path origImgPath(viewImagePathJ);
186236
std::string origFilename = origImgPath.stem().string();
187237
image::Image<image::RGBfColor> originalImage;
188238
image::readImage(viewImagePathJ, originalImage, image::EImageColorSpace::LINEAR);
189-
destFilename_J = (fs::path(outputFolder) / (origFilename + ".png")).string();
190-
image::writeImage(destFilename_J, originalImage, image::ImageWriteOptions().toColorSpace(image::EImageColorSpace::SRGB));
239+
destFilenameJ = (fs::path(outputFolder) / (origFilename + ".png")).string();
240+
image::writeImage(destFilenameJ, originalImage, image::ImageWriteOptions().toColorSpace(image::EImageColorSpace::SRGB));
191241
}
192242

193-
const std::pair<size_t, size_t> dimImageI = std::make_pair(viewI->getImage().getWidth(), viewI->getImage().getHeight());
194-
const std::pair<size_t, size_t> dimImageJ = std::make_pair(viewJ->getImage().getWidth(), viewJ->getImage().getHeight());
243+
const std::pair<size_t, size_t> dimImageI = std::make_pair(viewI.getImage().getWidth(), viewI.getImage().getHeight());
244+
const std::pair<size_t, size_t> dimImageJ = std::make_pair(viewJ.getImage().getWidth(), viewJ.getImage().getHeight());
195245

196246
svgDrawer svgStream(dimImageI.first + dimImageJ.first, std::max(dimImageI.second, dimImageJ.second));
197247

198-
svgStream.drawImage(destFilename_I, dimImageI.first, dimImageI.second);
199-
svgStream.drawImage(destFilename_J, dimImageJ.first, dimImageJ.second, dimImageI.first);
248+
svgStream.drawImage(destFilenameI, dimImageI.first, dimImageI.second);
249+
svgStream.drawImage(destFilenameJ, dimImageJ.first, dimImageJ.second, dimImageI.first);
250+
251+
struct PairInfo
252+
{
253+
Vec2 first;
254+
Vec2 second;
255+
feature::EImageDescriberType descType;
256+
};
200257

258+
std::vector<PairInfo> pairs;
201259
const matching::MatchesPerDescType& filteredMatches = pairwiseMatches.at(*iter);
202260

203261
ALICEVISION_LOG_INFO("nb describer: " << filteredMatches.size());
204262

205-
if (filteredMatches.empty())
206-
continue;
207-
208263
for (const auto& matchesIt : filteredMatches)
209264
{
210265
const feature::EImageDescriberType descType = matchesIt.first;
211266
assert(descType != feature::EImageDescriberType::UNINITIALIZED);
212267
const matching::IndMatches& matches = matchesIt.second;
213268
ALICEVISION_LOG_INFO(EImageDescriberType_enumToString(matchesIt.first) << ": " << matches.size() << " matches");
214269

215-
const PointFeatures& featuresI = featuresPerView.getFeatures(viewI->getViewId(), descType);
216-
const PointFeatures& featuresJ = featuresPerView.getFeatures(viewJ->getViewId(), descType);
270+
const PointFeatures& featuresI = featuresPerView.getFeatures(I, descType);
271+
const PointFeatures& featuresJ = featuresPerView.getFeatures(J, descType);
217272

218273
// draw link between features :
219274
for (std::size_t i = 0; i < matches.size(); ++i)
220275
{
221276
const PointFeature& imaA = featuresI[matches[i]._i];
222277
const PointFeature& imaB = featuresJ[matches[i]._j];
223278

224-
// compute a flashy colour for the correspondence
225-
unsigned char r, g, b;
226-
hslToRgb((rand() % 360) / 360., 1.0, .5, r, g, b);
227-
std::ostringstream osCol;
228-
osCol << "rgb(" << (int)r << ',' << (int)g << ',' << (int)b << ")";
229-
svgStream.drawLine(imaA.x(), imaA.y(), imaB.x() + dimImageI.first, imaB.y(), svgStyle().stroke(osCol.str(), 2.0));
230-
}
279+
PairInfo pi;
231280

232-
const std::string featColor = describerTypeColor(descType);
233-
// draw features (in two loop, in order to have the features upper the link, svg layer order):
234-
for (std::size_t i = 0; i < matches.size(); ++i)
235-
{
236-
const PointFeature& imaA = featuresI[matches[i]._i];
237-
const PointFeature& imaB = featuresJ[matches[i]._j];
238-
svgStream.drawCircle(imaA.x(), imaA.y(), 5.0, svgStyle().stroke(featColor, 2.0));
239-
svgStream.drawCircle(imaB.x() + dimImageI.first, imaB.y(), 5.0, svgStyle().stroke(featColor, 2.0));
281+
pi.first = imaA.coords().cast<double>();
282+
pi.second = imaB.coords().cast<double>();
283+
pi.descType = descType;
284+
285+
pairs.push_back(pi);
240286
}
241287
}
242288

243-
fs::path outputFilename = fs::path(outputFolder) / std::string(std::to_string(iter->first) + "_" + std::to_string(iter->second) + "_" +
244-
std::to_string(filteredMatches.getNbAllMatches()) + ".svg");
289+
if (pairs.empty())
290+
{
291+
continue;
292+
}
293+
294+
for (const auto & pi : pairs)
295+
{
296+
// compute a flashy colour for the correspondence
297+
unsigned char r, g, b;
298+
hslToRgb((rand() % 360) / 360., 1.0, .5, r, g, b);
299+
std::ostringstream osCol;
300+
osCol << "rgb(" << (int)r << ',' << (int)g << ',' << (int)b << ")";
301+
svgStream.drawLine(pi.first.x(), pi.first.y(), pi.second.x() + dimImageI.first, pi.second.y(), svgStyle().stroke(osCol.str(), 2.0));
302+
}
303+
304+
// draw features (in two loop, in order to have the features upper the link, svg layer order):
305+
for (const auto & pi : pairs)
306+
{
307+
const std::string featColor = describerTypeColor(pi.descType);
308+
svgStream.drawCircle(pi.first.x(), pi.first.y(), 5.0, svgStyle().stroke(featColor, 2.0));
309+
svgStream.drawCircle(pi.second.x() + dimImageI.first, pi.second.y(), 5.0, svgStyle().stroke(featColor, 2.0));
310+
}
311+
312+
fs::path outputFilename = fs::path(outputFolder) / std::string(std::to_string(iter->first) + "_" + std::to_string(iter->second) + "_" +std::to_string(filteredMatches.getNbAllMatches()) + ".svg");
245313
std::ofstream svgFile(outputFilename.string());
246314
svgFile << svgStream.closeSvgFile().str();
247315
svgFile.close();
248316
}
317+
318+
249319
return EXIT_SUCCESS;
250320
}

0 commit comments

Comments
 (0)