Hugin trunk 0.1
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 ; tab-width: 4 -*-
2/*
3* Copyright (C) 2007-2008 Anael Orlinski
4*
5* This file is part of Panomatic.
6*
7* Panomatic is free software; you can redistribute it and/or modify
8* it under the terms of the GNU General Public License as published by
9* the Free Software Foundation; either version 2 of the License, or
10* (at your option) any later version.
11*
12* Panomatic is distributed in the hope that it will be useful,
13* but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15* GNU General Public License for more details.
16*
17* You should have received a copy of the GNU General Public License
18* along with Panomatic; if not, write to the Free Software
19* <http://www.gnu.org/licenses/>.
20*/
21
22#include <iostream>
23#include <vector>
24#include <string>
25#include "Utils.h"
26#include <getopt.h>
28
29#include "PanoDetector.h"
30
32{
33 std::cout << "Hugin's cpfind " << hugin_utils::GetHuginVersion() << std::endl;
34 std::cout << "based on Pan-o-matic by Anael Orlinski" << std::endl;
35};
36
38{
40 std::cout << std::endl
41 << "Basic usage: " << std::endl
42 << " cpfind -o output_project project.pto" << std::endl
43 << " cpfind -k i0 -k i1 ... -k in project.pto" << std::endl
44 << " cpfind --kall project.pto" << std::endl
45 << std::endl << "The input project file is required." << std::endl
46 << std::endl << "General options" << std::endl
47 << " -q|--quiet Do not output progress" << std::endl
48 << " -v|--verbose Verbose output" << std::endl
49 << " -h|--help Shows this help screen" << std::endl
50 << " --version Prints the version number and exits then" << std::endl
51 << " -o|--output=<string> Sets the filename of the output file" << std::endl
52 << " (default: default.pto)" << std::endl
53 << std::endl << "Matching strategy (these options are mutually exclusive)" << std::endl
54 << " --linearmatch Enable linear images matching" << std::endl
55 << " Can be fine tuned with" << std::endl
56 << " --linearmatchlen=<int> Number of images to match (default: 1)" << std::endl
57 << " --multirow Enable heuristic multi row matching" << std::endl
58 << " default matching strategy, keep for backward reason" << std::endl
59 << " --prealigned Match only overlapping images," << std::endl
60 << " requires a rough aligned panorama" << std::endl
61 << " --allpairs Match all image pairs (slow)" << std::endl
62 << std::endl << "Feature description options" << std::endl
63 << " --sieve1width=<int> Sieve 1: Number of buckets on width (default: 10)" << std::endl
64 << " --sieve1height=<int> Sieve 1: Number of buckets on height (default: 10)" << std::endl
65 << " --sieve1size=<int> Sieve 1: Max points per bucket (default: 100)" << std::endl
66 << " --kdtreesteps=<int> KDTree: search steps (default: 200)" << std::endl
67 << " --kdtreeseconddist=<double> KDTree: distance of 2nd match (default: 0.25)" << std::endl
68 << std::endl << "Feature matching options" << std::endl
69 << " --ransaciter=<int> Ransac: iterations (default: 1000)" << std::endl
70 << " --ransacdist=<int> Ransac: homography estimation distance threshold" << std::endl
71 << " (in pixels) (default: 50)" << std::endl
72 << " --ransacmode=<string> Ransac: Select the mode used in the ransac step." << std::endl
73 << " Possible values: auto, hom, rpy, rpyv, rpyb" << std::endl
74 << " (default: auto)" << std::endl
75 << " --minmatches=<int> Minimum matches (default: 6)" << std::endl
76 << " --sieve2width=<int> Sieve 2: Number of buckets on width (default: 5)" << std::endl
77 << " --sieve2height=<int> Sieve 2: Number of buckets on height (default: 5)" << std::endl
78 << " --sieve2size=<int> Sieve 2: Max points per bucket (default: 1)" << std::endl
79 << std::endl << "Caching options" << std::endl
80 << " -c|--cache Caches keypoints to external file" << std::endl
81 << " --clean Clean up cached keyfiles" << std::endl
82 << " -p|--keypath=<string> Store keyfiles in given path" << std::endl
83 << " -k|--writekeyfile=<int> Write a keyfile for this image number" << std::endl
84 << " --kall Write keyfiles for all images in the project" << std::endl
85 << std::endl << "Advanced options" << std::endl
86 << " --celeste Masks area with clouds before running feature descriptor" << std::endl
87 << " Celeste can be fine tuned with the following parameters" << std::endl
88 << " --celestethreshold=<int> Threshold for celeste (default 0.5)" << std::endl
89 << " --celesteradius=<int> Radius for celeste (in pixels, default 20)" << std::endl
90 << " --ncores=<int> Number of threads to use (default: autodetect number of cores)" << std::endl;
91};
92
94{
95 enum
96 {
97 SIEVE1WIDTH=256,
102 MULTIROW,
103 PREALIGNED,
104 ALLPAIRS,
114 KALL,
115 CLEAN,
116 CELESTE,
120 };
121 const char* optstring = "qvftn:o:k:cp:h";
122 static struct option longOptions[] =
123 {
124 {"quiet", no_argument, NULL, 'q' },
125 {"verbose", no_argument, NULL, 'v'},
126 {"fullscale", no_argument, NULL, 'f'},
127 {"sieve1width", required_argument, NULL, SIEVE1WIDTH},
128 {"sieve1height", required_argument, NULL, SIEVE1HEIGHT},
129 {"sieve1size", required_argument, NULL, SIEVE1SIZE},
130 {"linearmatch", no_argument, NULL, LINEARMATCH},
131 {"linearmatchlen", required_argument, NULL, LINEARMATCHLEN},
132 {"multirow", no_argument, NULL, MULTIROW},
133 {"prealigned", no_argument, NULL, PREALIGNED},
134 { "allpairs", no_argument, NULL, ALLPAIRS},
135 {"kdtreesteps", required_argument, NULL, KDTREESTEPS},
136 {"kdtreeseconddist", required_argument, NULL, KDTREESECONDDIST},
137 {"minmatches", required_argument, NULL, MINMATCHES},
138 {"ransacmode", required_argument, NULL, RANSACMODE},
139 {"ransaciter", required_argument, NULL, RANSACITER},
140 {"ransacdist", required_argument, NULL, RANSACDIST},
141 {"sieve2width", required_argument, NULL, SIEVE2WIDTH},
142 {"sieve2height", required_argument, NULL, SIEVE2HEIGHT},
143 {"sieve2size", required_argument, NULL, SIEVE2SIZE},
144 {"test", no_argument, NULL, 't'},
145 {"ncores", required_argument, NULL, 'n'},
146 {"output", required_argument, NULL, 'o'},
147 {"writekeyfile", required_argument, NULL, 'k'},
148 {"kall", no_argument, NULL, KALL},
149 {"cache", no_argument, NULL, 'c'},
150 {"clean", no_argument, NULL, CLEAN},
151 {"keypath", required_argument, NULL, 'p'},
152 {"celeste", no_argument, NULL, CELESTE},
153 {"celestethreshold", required_argument, NULL, CELESTETHRESHOLD},
154 {"celesteradius", required_argument, NULL, CELESTERADIUS},
155 {"version", no_argument, NULL, CPFINDVERSION},
156 {"help", no_argument, NULL, 'h'},
157 0
158 };
159
160 int c;
161 int number;
162 double floatNumber;
163 std::string ransacMode;
164 std::vector<int> keyfilesIndex;
165 int doLinearMatch=0;
166 int doMultirow=0;
167 int doPrealign=0;
168 int doAllParis = 0;
169 while ((c = getopt_long (argc, argv, optstring, longOptions,nullptr)) != -1)
170 {
171 switch (c)
172 {
173 case 'q':
174 ioPanoDetector.setVerbose(0);
175 break;
176 case 'v':
177 ioPanoDetector.setVerbose(2);
178 break;
179 case 'f':
180 ioPanoDetector.setDownscale(false);
181 break;
182 case SIEVE1WIDTH:
184 if(number>0)
185 {
186 ioPanoDetector.setSieve1Width(number);
187 };
188 break;
189 case SIEVE1HEIGHT:
191 if(number>0)
192 {
193 ioPanoDetector.setSieve1Height(number);
194 };
195 break;
196 case SIEVE1SIZE:
198 if(number>0)
199 {
200 ioPanoDetector.setSieve1Size(number);
201 };
202 break;
203 case LINEARMATCH:
205 break;
206 case LINEARMATCHLEN:
208 if(number>0)
209 {
210 ioPanoDetector.setLinearMatchLen(number);
211 };
212 break;
213 case MULTIROW:
214 doMultirow=1;
215 break;
216 case PREALIGNED:
217 doPrealign=1;
218 break;
219 case ALLPAIRS:
220 doAllParis = 1;
221 break;
222 case KDTREESTEPS:
224 if(number>0)
225 {
226 ioPanoDetector.setKDTreeSearchSteps(number);
227 };
228 break;
229 case KDTREESECONDDIST:
231 if(floatNumber>0)
232 {
233 ioPanoDetector.setKDTreeSecondDistance(floatNumber);
234 };
235 break;
236 case MINMATCHES:
238 if(number>0)
239 {
240 ioPanoDetector.setMinimumMatches(number);
241 };
242 break;
243 case RANSACMODE:
245 std::cout << "Ransac: " << ransacMode << std::endl;
247 std::cout << "Ransac: " << ransacMode << std::endl;
248 if(ransacMode=="auto")
249 {
251 }
252 else
253 {
254 if(ransacMode=="hom")
255 {
257 }
258 else
259 {
260 if(ransacMode=="rpy")
261 {
263 }
264 else
265 {
266 if(ransacMode=="rpyv")
267 {
269 }
270 else
271 {
272 if(ransacMode=="rpyvb")
273 {
275 }
276 else
277 {
278 std::cout << "Warning: Invalid parameter in --ransacmode." << std::endl;
279 };
280 };
281 };
282 };
283 };
284 break;
285 case RANSACITER:
287 if(number>0)
288 {
289 ioPanoDetector.setRansacIterations(number);
290 };
291 break;
292 case RANSACDIST:
294 if(number>0)
295 {
296 ioPanoDetector.setRansacDistanceThreshold(number);
297 };
298 break;
299 case SIEVE2WIDTH:
301 if(number>0)
302 {
303 ioPanoDetector.setSieve2Width(number);
304 };
305 break;
306 case SIEVE2HEIGHT:
308 if(number>0)
309 {
310 ioPanoDetector.setSieve2Height(number);
311 };
312 break;
313 case SIEVE2SIZE:
315 if(number>0)
316 {
317 ioPanoDetector.setSieve2Size(number);
318 };
319 break;
320 case 't':
321 ioPanoDetector.setTest(true);
322 break;
323 case 'n':
325 if(number>0)
326 {
327 ioPanoDetector.setCores(number);
328 };
329 break;
330 case 'o':
331 ioPanoDetector.setOutputFile(optarg);
332 break;
333 case 'k':
335 if((number==0) && (strcmp(optarg,"0")!=0))
336 {
337 std::cout << "Warning: " << optarg << " is not a valid image number of writekeyfile." << std::endl;
338 }
339 else
340 {
341 keyfilesIndex.push_back(number);
342 };
343 break;
344 case KALL:
345 ioPanoDetector.setWriteAllKeyPoints();
346 break;
347 case 'c':
348 ioPanoDetector.setCached(true);
349 break;
350 case CLEAN:
351 ioPanoDetector.setCleanup(true);
352 break;
353 case 'p':
354 ioPanoDetector.setKeyfilesPath(optarg);
355 break;
356 case CELESTE:
357 ioPanoDetector.setCeleste(true);
358 break;
359 case CELESTETHRESHOLD:
361 if(floatNumber>0.0)
362 {
363 ioPanoDetector.setCelesteThreshold(floatNumber);
364 };
365 break;
366 case CELESTERADIUS:
368 if(number>0)
369 {
370 ioPanoDetector.setCelesteRadius(number);
371 };
372 break;
373 case CPFINDVERSION:
374 printVersion();
375 return false;
376 break;
377 case 'h':
378 printUsage();
379 return false;
380 break;
381 case ':':
382 case '?':
383 // missing argument or invalid switch
384 return false;
385 break;
386 default:
387 // this should not happen
388 abort();
389 };
390 };
391
392 if (argc - optind != 1)
393 {
394 if (argc - optind < 1)
395 {
396 std::cerr << hugin_utils::stripPath(argv[0]) << ": No project file given." << std::endl;
397 }
398 else
399 {
400 std::cerr << hugin_utils::stripPath(argv[0]) << ": Only one project file expected." << std::endl;
401 };
402 return false;
403 };
404 ioPanoDetector.setInputFile(argv[optind]);
406 {
407 std::cerr << hugin_utils::stripPath(argv[0]) << ": The arguments --linearmatch, --multirow, --prealigned and --allpairs" << std::endl
408 << " are mutually exclusive. Use only one of them." << std::endl;
409 return false;
410 };
411 if(doLinearMatch)
412 {
413 ioPanoDetector.setMatchingStrategy(PanoDetector::LINEAR);
414 };
415 if(doMultirow)
416 {
417 ioPanoDetector.setMatchingStrategy(PanoDetector::MULTIROW);
418 };
419 if(doPrealign)
420 {
421 ioPanoDetector.setMatchingStrategy(PanoDetector::PREALIGNED);
422 };
423 if (doAllParis)
424 {
425 ioPanoDetector.setMatchingStrategy(PanoDetector::ALLPAIRS);
426 };
427 if(!keyfilesIndex.empty())
428 {
429 ioPanoDetector.setKeyPointsIdx(keyfilesIndex);
430 };
431 return true;
432};
433
434int main(int argc, char** argv)
435{
436 // create a panodetector object
438 if(!parseOptions(argc, argv, aPanoDetector))
439 {
440 return 0;
441 }
442
443 if (!aPanoDetector.checkData())
444 {
445 return 0;
446 }
447
448 printVersion();
449 if (aPanoDetector.getVerbose() > 1)
450 {
451 aPanoDetector.printDetails();
452 }
453
454 TIMETRACE("Detection",aPanoDetector.run());
455
456 return 0;
457
458}
#define TIMETRACE(TEXT, CODE)
Definition Utils.h:32
int main(int argc, char **argv)
Definition main.cpp:434
void printVersion()
Definition main.cpp:31
bool parseOptions(int argc, char **argv, PanoDetector &ioPanoDetector)
Definition main.cpp:93
void printUsage()
Definition main.cpp:37
std::string tolower(const std::string &s)
convert a string to lowercase
Definition stl_utils.h:49
std::string GetHuginVersion()
return a string with version numbers
Definition utils.cpp:907
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
Definition utils.cpp:160
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41