Hugin trunk 0.1
Loading...
Searching...
No Matches
cpclean.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
2
15/* This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public
17 * License as published by the Free Software Foundation; either
18 * version 2 of the License, or (at your option) any later version.
19 *
20 * This software is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this software. If not, see
27 * <http://www.gnu.org/licenses/>.
28 *
29 */
30
31#include <fstream>
32#include <sstream>
33#include <getopt.h>
34
39
40static void usage(const char* name)
41{
42 std::cout << name << ": remove wrong control points by statistic method" << std::endl
43 << "cpclean version " << hugin_utils::GetHuginVersion() << std::endl
44 << std::endl
45 << "Usage: " << name << " [options] input.pto" << std::endl
46 << std::endl
47 << "CPClean uses statistical methods to remove wrong control points" << std::endl << std::endl
48 << "Step 1 optimises all images pairs, calculates for each pair mean " << std::endl
49 << " and standard deviation and removes all control points " << std::endl
50 << " with error bigger than mean+n*sigma" << std::endl
51 << "Step 2 optimises the whole panorama, calculates mean and standard deviation" << std::endl
52 << " for all control points and removes all control points with error" << std::endl
53 << " bigger than mean+n*sigma" << std::endl << std::endl
54 << " Options:" << std::endl
55 << " --output|-o file.pto Output Hugin PTO file." << std::endl
56 << " Default: '<filename>_clean.pto'." << std::endl
57 << " --max-distance|-n num distance factor for checking (default: 2)" << std::endl
58 << " (cps with an error > mean + this factor*sigma" << std::endl
59 << " will be removed)" << std::endl
60 << " --pairwise-checking|-p do only images pairs cp checking (skip step 2)" << std::endl
61 << " --whole-pano-checking|-w do only whole panorama cp checking (skip step 1)" << std::endl
62 << " --dont-optimize|-s skip optimisation step when checking the" << std::endl
63 << " whole panorama (only step 2)" << std::endl
64 << " --check-line-cp|-l also include line control points for calculation" << std::endl
65 << " and filtering in step 2" << std::endl
66 << " --verbose|-v verbose output during optimisation"<<std::endl
67 << " --help|-h shows help" << std::endl
68 << std::endl;
69}
70
71// dummy panotools progress functions
72static int ptProgress(int command, char* argument)
73{
74 return 1;
75}
76
77static int ptinfoDlg(int command, char* argument)
78{
79 return 1;
80}
81
82int main(int argc, char* argv[])
83{
84 // parse arguments
85 const char* optstring = "o:hn:pwslv";
86 static struct option longOptions[] =
87 {
88 { "output", required_argument, NULL, 'o'},
89 { "max-distance", required_argument, NULL, 'n'},
90 { "pairwise-checking", no_argument, NULL, 'p'},
91 { "whole-pano-checking", no_argument, NULL, 'w'},
92 { "dont-optimize", no_argument, NULL, 's'},
93 { "check-line-cp", no_argument, NULL, 'l' },
94 { "verbose", no_argument, NULL, 'v'},
95 { "help", no_argument, NULL, 'h' },
96 0
97 };
98 int c;
99 std::string output;
100 bool onlyPair = false;
101 bool wholePano = false;
102 bool skipOptimisation = false;
103 bool includeLineCp = false;
104 bool verbose = false;
105 double n = 2.0;
106 while ((c = getopt_long(argc, argv, optstring, longOptions, nullptr)) != -1)
107 {
108 switch (c)
109 {
110 case 'o':
111 output = optarg;
112 break;
113 case 'h':
115 return 0;
116 case 'n':
117 n = atof(optarg);
118 if(n==0)
119 {
120 std::cerr << hugin_utils::stripPath(argv[0]) << ": Invalid parameter: " << optarg << " is not valid real number" << std::endl;
121 return 1;
122 };
123 if (n<1.0)
124 {
125 std::cerr << hugin_utils::stripPath(argv[0]) << ": Invalid parameter: n must be at least 1" << std::endl;
126 return 1;
127 };
128 break;
129 case 'p':
130 onlyPair= true;
131 break;
132 case 'w':
133 wholePano = true;
134 break;
135 case 's':
136 skipOptimisation = true;
137 break;
138 case 'l':
139 includeLineCp = true;
140 break;
141 case 'v':
142 verbose = true;
143 break;
144 case ':':
145 case '?':
146 // missing argument or invalid switch
147 return 1;
148 break;
149 default:
150 // this should not happen
151 abort ();
152 }
153 }
154
155 if (argc - optind != 1)
156 {
157 if (argc - optind < 1)
158 {
159 std::cerr << hugin_utils::stripPath(argv[0]) << ": No project file given." << std::endl;
160 }
161 else
162 {
163 std::cerr << hugin_utils::stripPath(argv[0]) << ": Only one project file expected." << std::endl;
164 };
165 return 1;
166 };
167
168 if (onlyPair && wholePano)
169 {
170 std::cerr << hugin_utils::stripPath(argv[0]) << ": Options -p and -w can't used together" << std::endl;
171 return 1;
172 };
173
174 std::string input=argv[optind];
175
178 {
179 return 1;
180 };
181
182 const size_t nrImg=pano.getNrOfImages();
183 if (nrImg < 2)
184 {
185 std::cerr << "Panorama should consist of at least two images" << std::endl;
186 return 1;
187 }
188
189 if (pano.getNrOfCtrlPoints() < 3)
190 {
191 std::cerr << "Panorama should contain at least 3 control point" << std::endl;
192 };
193
194 if (!verbose)
195 {
198 };
199
200 size_t cpremoved1 = 0;
202 // step 1 with pairwise optimisation
203 if(!wholePano)
204 {
206 std::cout << "Step 1: Do image pair control point checking..." << std::endl;
207 CPtoRemove=getCPoutsideLimit_pair(pano, dummy, n);
208 if (!CPtoRemove.empty())
209 for (HuginBase::UIntSet::reverse_iterator it = CPtoRemove.rbegin(); it != CPtoRemove.rend(); ++it)
210 {
211 pano.removeCtrlPoint(*it);
212 }
213 cpremoved1=CPtoRemove.size();
214 };
215
216 // step 2 with optimisation of whole panorama
217 bool unconnected=false;
218 if(!onlyPair)
219 {
220 //check for unconnected images
222 unconnected = !graph.IsConnected();
223 if (!unconnected)
224 {
225 CPtoRemove.clear();
226 std::cout << "Step 2: Do whole panorama control point checking..." << std::endl;
228 {
229 std::cout << " Skipping optimisation, current image positions will be used." << std::endl;
230 };
231 CPtoRemove=getCPoutsideLimit(pano, n, skipOptimisation, includeLineCp);
232 if (!CPtoRemove.empty())
233 for (HuginBase::UIntSet::reverse_iterator it = CPtoRemove.rbegin(); it != CPtoRemove.rend(); ++it)
234 {
235 pano.removeCtrlPoint(*it);
236 }
237 }
238 else
239 {
240 std::cout << "Skipping whole panorama checking because of unconnected image groups" << std::endl;
241 };
242 };
243
244 std::cout << std::endl;
245 if(!wholePano)
246 {
247 std::cout << "Removed " << cpremoved1 << " control points in step 1" << std::endl;
248 }
249 if (!onlyPair)
250 {
251 if (unconnected)
252 {
253 std::cout << "Skipped step 2 because of unconnected image pairs" << std::endl;
254 }
255 else
256 {
257 std::cout << "Removed " << CPtoRemove.size() << " control points in step 2" << std::endl;
258 };
259 };
260
261 //write output
262 // Set output .pto filename if not given
265 {
266 std::cout << std::endl << "Written output to " << output << std::endl;
267 };
268 return 0;
269}
algorithms for remove control points by statistic method
static void usage()
Definition Main.cpp:32
!! from PTOptimise.h 1951
Dummy progress display, without output.
Model for a panorama.
Definition Panorama.h:153
bool ReadPTOFile(const std::string &filename, const std::string &prefix="")
read pto file from the given filename into Panorama object it does some checks on the file and issues...
std::size_t getNrOfCtrlPoints() const
number of control points
Definition Panorama.h:306
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
void removeCtrlPoint(unsigned int pNr)
remove a control point.
Definition Panorama.cpp:391
std::size_t getNrOfImages() const
number of images.
Definition Panorama.h:205
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
Definition ImageGraph.h:45
static int ptProgress(int command, char *argument)
Definition cpclean.cpp:72
int main(int argc, char *argv[])
Definition cpclean.cpp:82
static int ptinfoDlg(int command, char *argument)
Definition cpclean.cpp:77
std::set< unsigned int > UIntSet
std::string GetHuginVersion()
return a string with version numbers
Definition utils.cpp:907
std::string GetOutputFilename(const std::string &out, const std::string &in, const std::string &suffix)
construct output filename, if ouput is known return this value otherwise use the input filename and a...
Definition utils.cpp:420
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::string getPathPrefix(const std::string &filename)
Get the path to a filename.
Definition utils.cpp:184
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