Hugin trunk 0.1
Loading...
Searching...
No Matches
deghosting_mask.cpp
Go to the documentation of this file.
1
21#include <iostream>
22#include <string>
23#include <cstring>
24#include <cstdio>
25
26#include <hugin_config.h>
27// for stripExtension
28#include <hugin_utils/utils.h>
29// for exportImage
30#include <vigra/impex.hxx>
31
32#include "deghosting.h"
33#include "support.h"
34#include "threshold.h"
35#include "denoise.h"
36
37// deghosting algorithms
38#include "khan.h"
39
40#include <getopt.h>
41#ifdef _WIN32
42 #define snprintf _snprintf
43#endif
44
45// options for otherFlags
46static const uint16_t SAVE_GENWEIGHTS = 1;
47static const uint16_t OTHER_GRAY = 2;
48
49// globals containing settings
50static int iterations = 4;
51static double sigma = 30;
57static int verbosity = 0;
58static double thresholdLim = 150;
59static double contrast = 1.3;
60
64 for(char *c = optarg; *c; c++) {
65 switch(*c) {
66 case 'f':
68 break;
69 case 'g':
71 break;
72 case 'm':
74 break;
75 case 't':
77 break;
78 case 'w':
80 break;
81 default:
82 std::cerr<< "Error: unknown option" << std::endl;
83 exit(1);
84 }
85 }
86}
87
91 for(char *c = optarg; *c; c++) {
92 switch(*c) {
93 case 'i':
95 break;
96 case 'w':
98 break;
99 default:
100 std::cerr<< "Error: unknown option" << std::endl;
101 exit(1);
102 }
103 }
104}
105
106static void usage()
107{
108 std::cout << "deghosting_mask: creates mask for removing ghosting in images" << std::endl
109 << "deghosting_mask version " << hugin_utils::GetHuginVersion() << std::endl
110 << std::endl
111 << "Usage: deghosting_mask [options] inputfile(s) " << std::endl
112 << " option are: " << std::endl
113 << " -o, --output=PREFIX prefix for output masks" << std::endl
114 << " -i, --iterations=ITER number of iterations, default is (ITER > 0)" << std::endl
115 << " default: " << iterations << std::endl
116 << " -s, --sigma=SIGMA standard deviation of Gaussian weighting" << std::endl
117 << " function (SIGMA > 0); default: " << sigma << std::endl
118 //<< " -r, --response=E:M:o:R use camera response specified in EMoR format" << std::endl
119 << " -t, --threshold=THRESH threshold; default: " << thresholdLim << std::endl
120 << " -c, --contrast=CONTR change contrast before applying threshold;" << std::endl
121 << " default: " << contrast << std::endl
122 << " -a, --advanced=SET advanced settings. Possible options are:" << std::endl
123 << " f use gray images for computation. It's about two times faster" << std::endl
124 << " but it usually returns worse results." << std::endl
125 << " You also have to change threshold to smaller value (around 100)" << std::endl
126 << " g use gamma 2.2 correction instead of logarithm if input images are HDR" << std::endl
127 << " m do not scale image, NOTE: slows down process" << std::endl
128 << " t use simple threshold, may result in holes in images" << std::endl
129 << " w compute \"complete\" weights, not only probabilities" << std::endl
130 << " -w, --save=SET advanced save settings" << std::endl
131 << " i save initial weights" << std::endl
132 << " w save generated weights" << std::endl
133 << " -h, --help display this help" << std::endl
134 << " -v, --verbose verbose, repeat for more verbose output" << std::endl;
135}
136
137int main(int argc, char *argv[]) {
138 try
139 {
140 const char * optstring = "o:i:s:r:t:c:a:w:hv";
141 int c;
142
143 std::string outputPrefix = "weight";
144
145 enum optionArgumentKind {
151 };
152
153 enum optionId {
154 outputID,
156 sigmaID,
161 saveID,
162 helpID,
164 };
165
166 static struct option longOptions[] = {
167 { "output", 1, 0, StringArgument },
168 { "iterations", 1, 0, IntegerArgument },
169 { "sigma", 1, 0, DoubleArgument },
170 { "response", 1, 0, ArrayArgument },
171 { "threshold", 1, 0, DoubleArgument },
172 { "contrast", 1, 0, DoubleArgument },
173 { "advanced", 1, 0, StringArgument },
174 { "save", 1, 0, StringArgument },
175 { "help", 0, 0, NoArgument },
176 { "verbose", 0, 0, NoArgument },
177 { 0, 0, 0, 0 }
178 };
179
180 // TEST
181 // response for testing
182 response.resize(5);
183 response[0] = -3.59f;
184 response[1] = -0.93f;
185 response[2] = 0.11f;
186 response[3] = -0.22f;
187 response[4] = 0.34f;
188
189 int optionIndex = 0;
190
191 while ((c = getopt_long(argc, argv, optstring, longOptions, &optionIndex)) != -1) {
192 switch (c) {
193 case NoArgument: {
194 if (longOptions[optionIndex].flag != 0) break;
195 switch (optionIndex) {
196 case helpID:
197 usage();
198 return 0;
199 case verboseID:
200 verbosity++;
201 break;
202 default:
203 std::cerr << "There's a problem with parsing options" << std::endl;
204 return 1;
205 }
206 break;
207 }
208
209 case StringArgument: {
210 if (longOptions[optionIndex].flag != 0) break;
211 switch (optionIndex) {
212 case outputID:
214 break;
215 case advancedID:
217 break;
218 case saveID:
220 break;
221 default:
222 std::cerr << "There's a problem with parsing options" << std::endl;
223 return 1;
224 }
225 break;
226 }
227
228 case IntegerArgument: {
229 if (longOptions[optionIndex].flag != 0) break;
230 switch (optionIndex) {
231 case iterationsID:
233 break;
234 default:
235 std::cerr << "There's a problem with parsing options" << std::endl;
236 return 1;
237 }
238 break;
239 }
240
241 case DoubleArgument: {
242 if (longOptions[optionIndex].flag != 0) break;
243 switch (optionIndex) {
244 case sigmaID:
245 sigma = atof(optarg);
246 break;
247 case thresholdID:
249 break;
250 case contrastID:
252 break;
253 }
254 break;
255 }
256
257 case ArrayArgument: {
258 if (longOptions[optionIndex].flag != 0) break;
259 switch (optionIndex) {
260 case responseID:
261 // TODO
262 break;
263 }
264 break;
265 }
266
267 case 'o':
269 break;
270 case 'i':
272 break;
273 case 's':
274 sigma = atof(optarg);
275 break;
276 case 'r':
277 // TODO
278 break;
279 case 't':
281 break;
282 case 'c':
284 break;
285 case 'a':
287 break;
288 case 'w':
290 break;
291 case 'h':
292 usage();
293 return 0;
294 case 'v':
295 verbosity++;
296 break;
297 case ':':
298 case '?':
299 // missing argument or invalid switch
300 return 1;
301 break;
302 default:
303 // this should not happen
304 abort();
305 }
306 }
307
308 std::cout << std::endl;
309
310 unsigned nFiles = argc - optind;
311 if (nFiles < 3)
312 {
313 std::cerr << hugin_utils::stripPath(argv[0]) << ": at least three input images needed" << std::endl;
314 return 1;
315 };
316
317 // load all images
318 std::vector<std::string> inputFiles;
319 for (size_t i = optind; i < (size_t)argc; i++)
320 {
321 inputFiles.push_back(argv[i]);
322 }
323
324 std::vector<deghosting::FImagePtr> weights;
325 std::vector<vigra::Rect2D> inputROI;
326 vigra::Rect2D outputROI;
328 {
330 weights = deghoster.createWeightMasks();
331 inputROI = deghoster.getInputROIs();
332 outputROI = deghoster.getOutputROI();
333 }
334 else
335 {
337 weights = deghoster.createWeightMasks();
338 inputROI = deghoster.getInputROIs();
339 outputROI = deghoster.getOutputROI();
340 }
341
342 //deghoster->setCameraResponse(response);
343
344 // save weights
346 {
347 for (unsigned int i = 0; i<weights.size(); ++i)
348 {
349 char tmpfn[100];
350 snprintf(tmpfn, 99, "%s_%u.tif", outputPrefix.c_str(), i);
351 vigra::ImageExportInfo exWeights(tmpfn);
352 exWeights.setPixelType("UINT8");
353 exWeights.setPosition(inputROI[i].upperLeft());
354 exWeights.setCanvasSize(vigra::Size2D(inputROI[i].lowerRight().x, inputROI[i].lowerRight().y));
355 vigra::Rect2D roi(inputROI[i]);
356 roi.moveBy(-outputROI.upperLeft());
357 vigra::exportImage(srcImageRange(*weights[i], roi), exWeights);
358 }
359 }
360
361 // apply contrast functor
362 for (unsigned int i = 0; i < weights.size(); ++i)
363 {
364 vigra::transformImage(vigra::srcImageRange(*(weights[i])), vigra::destImage(*(weights[i])), vigra::BrightnessContrastFunctor<vigra::FImage::PixelType>(1, contrast, 0, 255));
365 }
366
367 std::vector<deghosting::BImagePtr> thresholded = threshold(weights, thresholdLim, otherThresholdFlags);
368
369 // save masks with treshold applied
370 for (unsigned int i = 0; i<weights.size(); ++i)
371 {
372 char tmpfn[100];
373 std::string fileName = hugin_utils::stripExtension(inputFiles[i]);
375 snprintf(tmpfn, 99, "%s_mask.tif", fileName.c_str());
376 vigra::ImageExportInfo exWeights(tmpfn);
377 exWeights.setPixelType("UINT8");
378 exWeights.setPosition(inputROI[i].upperLeft());
379 exWeights.setCanvasSize(vigra::Size2D(inputROI[i].lowerRight().x, inputROI[i].lowerRight().y));
380 vigra::Rect2D roi(inputROI[i]);
381 roi.moveBy(-outputROI.upperLeft());
382 vigra::BImage outImg = vigra::BImage((*thresholded[i]).size());
383 simpleDenoise(vigra::srcImageRange(*thresholded[i]), destImage(outImg));
384 vigra::exportImage(vigra::srcImageRange(outImg, roi), exWeights);
385 }
386 }
387 catch (const std::exception & e)
388 {
389 std::cerr << "caught exception: " << e.what() << std::endl;
390 return 1;
391 } catch (...)
392 {
393 std::cerr << "caught unknown exception" << std::endl;
394 return 1;
395 }
396 return 0;
397}
static uint16_t debugFlags
int main(int argc, char *argv[])
static double contrast
static int verbosity
static int iterations
static uint16_t flags
void parseOptions_advanced(char *optarg)
function handling advanced options
static uint16_t otherThresholdFlags
static double thresholdLim
void parseOptions_save(char *optarg)
function handling save options
static double sigma
static void usage()
static const uint16_t OTHER_GRAY
static deghosting::EMoR response(0.0f)
static uint16_t otherFlags
static const uint16_t SAVE_GENWEIGHTS
Tool for creating b/w alpha masks to eliminate ghosting artifacts Copyright (C) 2009 Lukáš Jirkovský ...
void simpleDenoise(SrcIterator sy, SrcIterator send, SrcAccessor sa, DestIterator dy, DestAccessor da)
Simple denoising algorithm Copyright (C) 2009 Lukáš Jirkovský l.jirkovsky@gmail.com
Definition denoise.h:26
std::vector< float > EMoR
Definition deghosting.h:48
const uint16_t ADV_ONLYP
Definition deghosting.h:52
const uint16_t ADV_MULTIRES
Definition deghosting.h:53
const uint16_t ADV_GAMMA
Definition deghosting.h:51
const uint16_t SAVE_INITWEIGHTS
Definition deghosting.h:56
std::string stripExtension(const std::string &basename2)
remove extension of a filename
Definition utils.cpp:130
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
const uint16_t THRESHOLD_DONTCARE
Definition threshold.h:29
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