Line 0
Link Here
|
|
|
1 |
--- src/camera/pfshdrcalibrate.cpp.orig 2018-01-19 06:59:44 UTC |
2 |
+++ src/camera/pfshdrcalibrate.cpp |
3 |
@@ -42,6 +42,7 @@ |
4 |
|
5 |
#include <responses.h> |
6 |
#include <robertson02.h> |
7 |
+#include <robertson02old.h> |
8 |
#include <mitsunaga99.h> |
9 |
|
10 |
using namespace std; |
11 |
@@ -58,9 +59,12 @@ inline float max3( float a, float b, flo |
12 |
inline float min3( float a, float b, float c ) |
13 |
{ |
14 |
// ignore zero values |
15 |
- if( int(a)==0 ) a=1e8; |
16 |
- if( int(b)==0 ) b=1e8; |
17 |
- if( int(c)==0 ) c=1e8; |
18 |
+ if (a <= std::numeric_limits<float>::epsilon()) |
19 |
+ a = std::numeric_limits<float>::max(); |
20 |
+ if (b <= std::numeric_limits<float>::epsilon()) |
21 |
+ b = std::numeric_limits<float>::max(); |
22 |
+ if (c <= std::numeric_limits<float>::epsilon()) |
23 |
+ c = std::numeric_limits<float>::max(); |
24 |
|
25 |
float min = (a<b) ? a : b; |
26 |
return (c<min) ? c : min; |
27 |
@@ -78,11 +82,12 @@ class QuietException |
28 |
void printHelp() |
29 |
{ |
30 |
fprintf( stderr, PROG_NAME ": \n" |
31 |
- "\t[--calibration <type>] [--luminance]\n" |
32 |
- "\t[--response <type>] [--response-file <filename.m>] \n" |
33 |
- "\t[--save-response <filename.m>] \n" |
34 |
+ "\t[--method <type>] [--no-calibration]\n" |
35 |
+ "\t[--response <type>] [--weights <type>]\n" |
36 |
+ "\t[--response-file <filename.m>] [--save-response <filename.m>]\n" |
37 |
"\t[--multiplier <val>] \n" |
38 |
"\t[--bpp <val>] \n" |
39 |
+ "\t[--luminance] [--deghosting]\n" |
40 |
"\t[--verbose] [--help]\n" |
41 |
"See man page for more information.\n" ); |
42 |
} |
43 |
@@ -103,20 +108,22 @@ void pfshdrcalibrate( int argc, char* ar |
44 |
enum TCalibration |
45 |
{ NONE, CALIBRATE } opt_calibration = CALIBRATE; |
46 |
enum TResponse |
47 |
- { FROM_FILE, LINEAR, GAMMA, LOG10 } opt_response = LINEAR; |
48 |
+ { FROM_FILE_RESP, LINEAR_RESP, GAMMA_RESP, LOG10_RESP } opt_response = LINEAR_RESP; |
49 |
+ enum TWeight |
50 |
+ { FROM_FILE_WEIGHT, GAUSS_WEIGHT, COMPOSITE_WEIGHT } opt_weight = COMPOSITE_WEIGHT; |
51 |
enum TMethod |
52 |
- { ROBERTSON_METHOD, MITSUNAGA_METHOD } opt_method = ROBERTSON_METHOD; |
53 |
+ { ROBERTSON_METHOD, MITSUNAGA_METHOD, ROBERTSON_OLD_METHOD } opt_method = ROBERTSON_METHOD; |
54 |
|
55 |
/* defaults */ |
56 |
- float input_multiplier = 1.0f; |
57 |
+ float input_multiplier = -1.0f; |
58 |
FILE *responseFile = NULL; |
59 |
FILE *responseSaveFile = NULL; |
60 |
int opt_bpp = 8; |
61 |
bool opt_fillgaps = false; /* todo remove */ |
62 |
bool opt_luminance = false; |
63 |
float opt_gauss = 0.2; |
64 |
- int opt_maxresponse = -1; |
65 |
- int opt_minresponse = -1; |
66 |
+ float opt_maxresponse = -1.0f; |
67 |
+ float opt_minresponse = -1.0f; |
68 |
unsigned long mitsunaga_sample_no = MITSUNAGA_SAMPLES_NO; |
69 |
bool opt_deghosting = false; |
70 |
|
71 |
@@ -128,10 +135,12 @@ void pfshdrcalibrate( int argc, char* ar |
72 |
{ "verbose", no_argument, NULL, 'v' }, |
73 |
{ "luminance", no_argument, NULL, 'Y' }, |
74 |
{ "method", required_argument, NULL, 'c' }, |
75 |
+ { "no-calibrate", no_argument, NULL, 'C' }, |
76 |
{ "gauss", required_argument, NULL, 'g' }, |
77 |
{ "max-response", required_argument, NULL, 'A' }, |
78 |
{ "min-response", required_argument, NULL, 'S' }, |
79 |
{ "response", required_argument, NULL, 'r' }, |
80 |
+ { "weights", required_argument, NULL, 'w' }, |
81 |
{ "response-file", required_argument, NULL, 'f' }, |
82 |
{ "save-response", required_argument, NULL, 's' }, |
83 |
{ "multiplier", required_argument, NULL, 'm' }, |
84 |
@@ -144,7 +153,7 @@ void pfshdrcalibrate( int argc, char* ar |
85 |
int optionIndex = 0; |
86 |
while( ( c = getopt_long( argc, |
87 |
argv, |
88 |
- "hvYc:g:r:f:s:m:b:p:xd", |
89 |
+ "hvYc:g:r:f:s:m:b:p:xdA:S:w:C", |
90 |
cmdLineOptions, |
91 |
&optionIndex) ) |
92 |
!= -1 ) |
93 |
@@ -172,27 +181,22 @@ void pfshdrcalibrate( int argc, char* ar |
94 |
opt_fillgaps = true; |
95 |
break; |
96 |
|
97 |
+ /* disable calibration, apply or save responce only */ |
98 |
+ case 'C': |
99 |
+ opt_calibration = NONE; |
100 |
+ break; |
101 |
+ |
102 |
/* calibration method */ |
103 |
case 'c': |
104 |
- if( strcmp( optarg, "mitsunaga" ) == 0 ) |
105 |
- { |
106 |
- opt_calibration = CALIBRATE; |
107 |
- opt_method = MITSUNAGA_METHOD; |
108 |
- } |
109 |
- else |
110 |
- if( strcmp( optarg, "robertson" ) == 0 ) |
111 |
- { |
112 |
- opt_calibration = CALIBRATE; |
113 |
- opt_method = ROBERTSON_METHOD; |
114 |
- } |
115 |
- else |
116 |
- if( strcmp( optarg, "none" ) == 0 ) |
117 |
- { |
118 |
- opt_calibration = NONE; |
119 |
- opt_method = ROBERTSON_METHOD; |
120 |
- } |
121 |
- else |
122 |
- throw pfs::Exception("unsupported automatic self-calibration method"); |
123 |
+ if( strcmp( optarg, "mitsunaga" ) == 0 ) { |
124 |
+ opt_method = MITSUNAGA_METHOD; |
125 |
+ } else if( strcmp( optarg, "robertson" ) == 0 ) { |
126 |
+ opt_method = ROBERTSON_METHOD; |
127 |
+ } else if( strcmp( optarg, "robertson-old" ) == 0 ) { |
128 |
+ opt_method = ROBERTSON_OLD_METHOD; |
129 |
+ } else { |
130 |
+ throw pfs::Exception("unsupported automatic self-calibration method"); |
131 |
+ } |
132 |
break; |
133 |
|
134 |
/* support of Gaussian weighting curve */ |
135 |
@@ -206,22 +210,32 @@ void pfshdrcalibrate( int argc, char* ar |
136 |
/* predefined response curve */ |
137 |
case 'r': |
138 |
if( strcmp( optarg, "linear" ) == 0 ) { |
139 |
- opt_response = LINEAR; |
140 |
+ opt_response = LINEAR_RESP; |
141 |
} else if( strcmp( optarg, "gamma" ) == 0 ) { |
142 |
- opt_response = GAMMA; |
143 |
+ opt_response = GAMMA_RESP; |
144 |
} else if( strcmp( optarg, "log" ) == 0 ) { |
145 |
- opt_response = LOG10; |
146 |
+ opt_response = LOG10_RESP; |
147 |
} else { |
148 |
- throw pfs::Exception("unknown standard response (check the manpage or use default)"); |
149 |
+ throw pfs::Exception("unknown standard response (check the manpage or use default)"); |
150 |
+ } |
151 |
+ break; |
152 |
+ |
153 |
+ /* predefined weighting function */ |
154 |
+ case 'w': |
155 |
+ if( strcmp( optarg, "gauss" ) == 0 ) { |
156 |
+ opt_weight = GAUSS_WEIGHT; |
157 |
+ } else if( strcmp( optarg, "composite" ) == 0 ) { |
158 |
+ opt_weight = COMPOSITE_WEIGHT; |
159 |
+ } else { |
160 |
+ throw pfs::Exception("unknown standard weight (check the manpage or use default)"); |
161 |
} |
162 |
- opt_calibration = NONE; |
163 |
break; |
164 |
|
165 |
|
166 |
/* response curve from file */ |
167 |
case 'f': |
168 |
- opt_response = FROM_FILE; |
169 |
- opt_calibration = NONE; |
170 |
+ opt_response = FROM_FILE_RESP; |
171 |
+ opt_weight = FROM_FILE_WEIGHT; |
172 |
responseFile = fopen(optarg, "r"); |
173 |
if( !responseFile ) |
174 |
throw pfs::Exception("could not open file with response curve"); |
175 |
@@ -257,15 +271,15 @@ void pfshdrcalibrate( int argc, char* ar |
176 |
|
177 |
|
178 |
case 'A': // max response |
179 |
- opt_maxresponse = atoi(optarg); |
180 |
- if( opt_maxresponse<=opt_minresponse ) |
181 |
- throw pfs::Exception("max response should be higher than min response"); |
182 |
+ opt_maxresponse = atof(optarg); |
183 |
+ if( opt_maxresponse<0.0f || opt_maxresponse>1.0f ) |
184 |
+ throw pfs::Exception("max response is out of range: 0..1"); |
185 |
break; |
186 |
|
187 |
case 'S': // min response |
188 |
- opt_minresponse = atoi(optarg); |
189 |
- if( opt_minresponse<0 ) |
190 |
- throw pfs::Exception("min response should be >0"); |
191 |
+ opt_minresponse = atof(optarg); |
192 |
+ if( opt_minresponse<0.0f || opt_minresponse>1.0f ) |
193 |
+ throw pfs::Exception("min response is out of range: 0..1"); |
194 |
break; |
195 |
|
196 |
case 'd': |
197 |
@@ -293,39 +307,35 @@ void pfshdrcalibrate( int argc, char* ar |
198 |
// input_multiplier = 255; |
199 |
//Ivo end |
200 |
|
201 |
- if( opt_method == ROBERTSON_METHOD ) |
202 |
- { |
203 |
- input_multiplier = float( 1 << opt_bpp ) - 1; |
204 |
- opt_gauss *= input_multiplier; |
205 |
- } |
206 |
- |
207 |
- |
208 |
- if( opt_method == MITSUNAGA_METHOD ) |
209 |
+ if( input_multiplier == -1.0f ) |
210 |
+ { |
211 |
input_multiplier = 1.0f; |
212 |
+ } |
213 |
|
214 |
|
215 |
//--- verbose information and load initialization data |
216 |
- VERBOSE_STR << "Assuming " << opt_bpp << " Bits per pixel in the LDR images (use --bpp to change this)" << endl; |
217 |
+ //VERBOSE_STR << "Assuming " << opt_bpp << " Bits per pixel in the LDR images (use --bpp to change this)" << endl; |
218 |
|
219 |
- VERBOSE_STR << "calibrating channels: " |
220 |
+ VERBOSE_STR << (opt_calibration == CALIBRATE ? "calibrating and " : "") |
221 |
+ << "recovering channels: " |
222 |
<< (opt_luminance ? "LUMINANCE" : "RGB") << endl; |
223 |
|
224 |
switch( opt_response ) |
225 |
{ |
226 |
|
227 |
- case FROM_FILE: |
228 |
+ case FROM_FILE_RESP: |
229 |
VERBOSE_STR << "response curve from file" << endl; |
230 |
break; |
231 |
|
232 |
- case LINEAR: |
233 |
+ case LINEAR_RESP: |
234 |
VERBOSE_STR << "initial response: linear" << endl; |
235 |
break; |
236 |
|
237 |
- case GAMMA: |
238 |
+ case GAMMA_RESP: |
239 |
VERBOSE_STR << "initial response: gamma" << endl; |
240 |
break; |
241 |
|
242 |
- case LOG10: |
243 |
+ case LOG10_RESP: |
244 |
VERBOSE_STR << "initial response: logarithmic" << endl; |
245 |
break; |
246 |
|
247 |
@@ -344,8 +354,8 @@ void pfshdrcalibrate( int argc, char* ar |
248 |
|
249 |
|
250 |
// number of input levels |
251 |
- int M = (int) powf( 2.0f, opt_bpp ); |
252 |
- VERBOSE_STR << "number of input levels: " << M << endl; |
253 |
+ int M = 1 << opt_bpp; |
254 |
+ VERBOSE_STR << "input levels from bpp: " << M << " (" << opt_bpp << "bpp)" << endl; |
255 |
VERBOSE_STR << "input multiplier: " << input_multiplier << endl; |
256 |
|
257 |
|
258 |
@@ -363,7 +373,7 @@ void pfshdrcalibrate( int argc, char* ar |
259 |
int height = 0; |
260 |
int size = 0; |
261 |
|
262 |
- float minResponse = M; |
263 |
+ float minResponse = 1.0f; |
264 |
float maxResponse = 0.0f; |
265 |
|
266 |
// collected exposures |
267 |
@@ -451,15 +461,15 @@ void pfshdrcalibrate( int argc, char* ar |
268 |
|
269 |
for( int i=0 ; i < size ; i++ ) |
270 |
{ |
271 |
- (*eY.yi)( i ) = (*Y)( i ) * input_multiplier; |
272 |
- |
273 |
- float val = (*eY.yi)( i ); |
274 |
- |
275 |
- if( val>0.0f ) // discard zero values |
276 |
+ float val = (*Y)( i ) * input_multiplier; |
277 |
+ if (val < std::numeric_limits<float>::epsilon()) |
278 |
+ val = std::numeric_limits<float>::epsilon(); |
279 |
+ else // discard zero values |
280 |
{ |
281 |
maxResponse = (maxResponse > val) ? maxResponse : val; |
282 |
minResponse = (minResponse < val) ? minResponse : val; |
283 |
} |
284 |
+ (*eY.yi)( i ) = val; |
285 |
} |
286 |
|
287 |
imgsY.push_back( eY ); |
288 |
@@ -489,21 +499,26 @@ void pfshdrcalibrate( int argc, char* ar |
289 |
for( int i = 0 ; i < size ; i++ ) |
290 |
{ |
291 |
|
292 |
- (*eR.yi)( i ) = (*X)( i ) * input_multiplier; |
293 |
- (*eG.yi)( i ) = (*Y)( i ) * input_multiplier; |
294 |
- (*eB.yi)( i ) = (*Z)( i ) * input_multiplier; |
295 |
- |
296 |
- float maxval = max3( (*eR.yi)( i ), |
297 |
- (*eG.yi)( i ), |
298 |
- (*eB.yi)( i ) ); |
299 |
+ float r = (*X)( i ) * input_multiplier; |
300 |
+ if (r < std::numeric_limits<float>::epsilon()) |
301 |
+ r = std::numeric_limits<float>::epsilon(); |
302 |
+ float g = (*Y)( i ) * input_multiplier; |
303 |
+ if (g < std::numeric_limits<float>::epsilon()) |
304 |
+ g = std::numeric_limits<float>::epsilon(); |
305 |
+ float b = (*Z)( i ) * input_multiplier; |
306 |
+ if (b < std::numeric_limits<float>::epsilon()) |
307 |
+ b = std::numeric_limits<float>::epsilon(); |
308 |
|
309 |
- float minval = min3( (*eR.yi)( i ), |
310 |
- (*eG.yi)( i ), |
311 |
- (*eB.yi)( i ) ); |
312 |
+ float maxval = max3( r, g, b ); |
313 |
+ float minval = min3( r, g, b ); |
314 |
|
315 |
maxResponse = (maxResponse > maxval) ? maxResponse : maxval; |
316 |
minResponse = (minResponse < minval) ? minResponse : minval; |
317 |
|
318 |
+ (*eR.yi)( i ) = r; |
319 |
+ (*eG.yi)( i ) = g; |
320 |
+ (*eB.yi)( i ) = b; |
321 |
+ |
322 |
} |
323 |
|
324 |
// add to exposures list |
325 |
@@ -523,21 +538,27 @@ void pfshdrcalibrate( int argc, char* ar |
326 |
|
327 |
|
328 |
// some more info on input frames |
329 |
- VERBOSE_STR << "registered values: min=" << (int) minResponse |
330 |
- << " max=" << (int) maxResponse << endl; |
331 |
+ VERBOSE_STR << "registered camera response range: min=" << minResponse |
332 |
+ << "; max=" << maxResponse << endl; |
333 |
+ |
334 |
+ if( minResponse < 0.0f ) |
335 |
+ throw pfs::Exception( "input min value < 0 (wrong input?)" ); |
336 |
+ if( maxResponse > 1.0f ) |
337 |
+ throw pfs::Exception( "input max value > 1 (use input multiplier to adjust range)" ); |
338 |
|
339 |
if( opt_minresponse == -1 ) |
340 |
- opt_minresponse = (int) minResponse; |
341 |
- |
342 |
+ opt_minresponse = minResponse; |
343 |
if( opt_maxresponse == -1 ) |
344 |
- opt_maxresponse = (int) maxResponse; |
345 |
+ opt_maxresponse = maxResponse; |
346 |
+ if (opt_maxresponse<=opt_minresponse) |
347 |
+ throw pfs::Exception("max response should be higher than min response"); |
348 |
|
349 |
- if( opt_response != FROM_FILE ) |
350 |
- VERBOSE_STR << "camera response range: min=" << opt_minresponse |
351 |
- << " max=" << opt_maxresponse << endl; |
352 |
- |
353 |
- if( maxResponse >= M ) |
354 |
- throw pfs::Exception( "input value higher than defined number of input levels (adjust the number of bits per pixel)" ); |
355 |
+ if( opt_response != FROM_FILE_RESP ) |
356 |
+ VERBOSE_STR << "using camera response range: min=" << opt_minresponse |
357 |
+ << "; max=" << opt_maxresponse << endl; |
358 |
+ |
359 |
+ int Mmin( (int) (M * (opt_minresponse + std::numeric_limits<float>::epsilon())) ); |
360 |
+ int Mmax( (int) (M * (opt_maxresponse - std::numeric_limits<float>::epsilon())) ); |
361 |
|
362 |
/* ------------------------------------------------------------------------------------------------ */ |
363 |
/* ---------------------------- preparation of images done ---------------------------------------- */ |
364 |
@@ -548,24 +569,35 @@ void pfshdrcalibrate( int argc, char* ar |
365 |
/* ------------------------------------------------------------------------------------------------ */ |
366 |
|
367 |
// weighting function representing confidence in accuracy of acquisition |
368 |
- float* w = new float [ M ]; |
369 |
+ int Mw(M); |
370 |
+ float* w = new float [ Mw ]; |
371 |
|
372 |
if( w == NULL ) |
373 |
throw pfs::Exception( "could not allocate memory for weighting function" ); |
374 |
|
375 |
/* 1.4: currently, weights are always Gaussian */ |
376 |
/* Composite function works better for extreme cases */ |
377 |
- weightsComposite ( w, M, opt_minresponse, opt_maxresponse, opt_gauss ); |
378 |
- |
379 |
-// weightsGauss( w, M, opt_minresponse, opt_maxresponse, opt_gauss ); |
380 |
+ switch (opt_weight) |
381 |
+ { |
382 |
+ case GAUSS_WEIGHT: |
383 |
+ weightsGauss( w, Mw, Mmin, Mmax, opt_gauss ); |
384 |
+ break; |
385 |
+ default: //case COMPOSITE_WEIGHT: |
386 |
+ weightsComposite ( w, Mw, Mmin, Mmax, opt_gauss ); |
387 |
+ break; |
388 |
+ } |
389 |
|
390 |
// camera response functions for each channel |
391 |
- float* Iy = new float [ M ]; |
392 |
- float* Ir = new float [ M ]; |
393 |
- float* Ig = new float [ M ]; |
394 |
- float* Ib = new float [ M ]; |
395 |
+ int Mr(M); |
396 |
+ float* Ir = new float [ Mr ]; |
397 |
+ int Mg(M); |
398 |
+ float* Ig = new float [ Mg ]; |
399 |
+ int Mb(M); |
400 |
+ float* Ib = new float [ Mb ]; |
401 |
+ int &My(Mg); |
402 |
+ float* &Iy(Ig); |
403 |
|
404 |
- if( Iy == NULL || Ib == NULL || Ig == NULL || Ib == NULL ) |
405 |
+ if( Ib == NULL || Ig == NULL || Ib == NULL ) |
406 |
throw pfs::Exception( "could not allocate memory for camera responses" ); |
407 |
|
408 |
// initial responses |
409 |
@@ -573,65 +605,79 @@ void pfshdrcalibrate( int argc, char* ar |
410 |
{ |
411 |
|
412 |
/* ------ Response function from file ------ */ |
413 |
- case FROM_FILE: |
414 |
+ case FROM_FILE_RESP: |
415 |
|
416 |
if( opt_luminance ) |
417 |
- { |
418 |
+ { |
419 |
|
420 |
- bool loadY_ok = responseLoad ( responseFile, Iy, M ); |
421 |
- bool loadW_ok = weightsLoad ( responseFile, w, M ); |
422 |
- fclose( responseFile ); |
423 |
- |
424 |
- if( !loadY_ok || !loadW_ok ) |
425 |
- throw pfs::Exception( "could not load response curve from file" ); |
426 |
+ bool load_ok = responseLoad( responseFile, &Iy, &My ); |
427 |
+ if (load_ok && opt_weight == FROM_FILE_WEIGHT) |
428 |
+ load_ok = weightsLoad( responseFile, &w, &Mw ); |
429 |
+ fclose( responseFile ); |
430 |
|
431 |
- } |
432 |
+ if( !load_ok ) |
433 |
+ throw pfs::Exception( "could not load response curve from file" ); |
434 |
|
435 |
- else |
436 |
+ if (M != My) |
437 |
+ VERBOSE_STR << "input levels from response: " << My << ", was " << M << endl; |
438 |
+ |
439 |
+ } |
440 |
+ else |
441 |
{ |
442 |
|
443 |
// read camera response from file (and also weights) |
444 |
- bool loadR_ok = responseLoad ( responseFile, Ir, M ); |
445 |
- bool loadG_ok = responseLoad ( responseFile, Ig, M ); |
446 |
- bool loadB_ok = responseLoad ( responseFile, Ib, M ); |
447 |
- bool loadW_ok = weightsLoad ( responseFile, w, M ); |
448 |
+ bool load_ok = responseLoad( responseFile, &Ir, &Mr ); |
449 |
+ if (load_ok) |
450 |
+ load_ok = responseLoad( responseFile, &Ig, &Mg ); |
451 |
+ if (load_ok) |
452 |
+ load_ok = responseLoad( responseFile, &Ib, &Mb ); |
453 |
+ if (load_ok && opt_weight == FROM_FILE_WEIGHT) |
454 |
+ load_ok = weightsLoad( responseFile, &w, &Mw ); |
455 |
fclose( responseFile ); |
456 |
|
457 |
- if( !loadR_ok || !loadG_ok || !loadB_ok || !loadW_ok ) |
458 |
+ if( !load_ok ) |
459 |
throw pfs::Exception( "could not load response curve from file" ); |
460 |
+ |
461 |
+ if (M != Mr || M != Mg || M != Mb) |
462 |
+ VERBOSE_STR << "input levels from response: (" << Mr << "," << Mg << "," << Mb << "), was " << M << endl; |
463 |
+ |
464 |
} |
465 |
|
466 |
- opt_calibration = NONE; |
467 |
+ //if (M != Mw) |
468 |
+ // weightsMinMax(w, Mw, Mmin, Mmax); |
469 |
+ |
470 |
break; |
471 |
|
472 |
/* ------ Response function linear ------ */ |
473 |
- case LINEAR: |
474 |
- responseLinear( Iy, M ); |
475 |
- responseLinear( Ir, M ); |
476 |
- responseLinear( Ig, M ); |
477 |
- responseLinear( Ib, M ); |
478 |
+ case LINEAR_RESP: |
479 |
+ //responseLinear( Iy, My ); |
480 |
+ responseLinear( Ir, Mr ); |
481 |
+ responseLinear( Ig, Mg ); |
482 |
+ responseLinear( Ib, Mb ); |
483 |
break; |
484 |
|
485 |
/* ------ Response function gamma ------ */ |
486 |
- case GAMMA: |
487 |
- responseGamma( Iy, M ); |
488 |
- responseGamma( Ir, M ); |
489 |
- responseGamma( Ig, M ); |
490 |
- responseGamma( Ib, M ); |
491 |
+ case GAMMA_RESP: |
492 |
+ //responseGamma( Iy, My ); |
493 |
+ responseGamma( Ir, Mr ); |
494 |
+ responseGamma( Ig, Mg ); |
495 |
+ responseGamma( Ib, Mb ); |
496 |
break; |
497 |
|
498 |
/* ------ Response function logarithmic ------ */ |
499 |
- case LOG10: |
500 |
- responseLog10( Iy, M ); |
501 |
- responseLog10( Ir, M ); |
502 |
- responseLog10( Ig, M ); |
503 |
- responseLog10( Ib, M ); |
504 |
+ case LOG10_RESP: |
505 |
+ //responseLog10( Iy, My ); |
506 |
+ responseLog10( Ir, Mr ); |
507 |
+ responseLog10( Ig, Mg ); |
508 |
+ responseLog10( Ib, Mb ); |
509 |
break; |
510 |
|
511 |
default: |
512 |
throw pfs::Exception( "camera response not initialized" ); |
513 |
break; |
514 |
- } |
515 |
+ } |
516 |
+ |
517 |
+ weightsMinMax(w, Mw, Mmin, Mmax); |
518 |
|
519 |
|
520 |
/* ------------------------------------------------------------------------------------------------ */ |
521 |
@@ -657,20 +703,20 @@ void pfshdrcalibrate( int argc, char* ar |
522 |
if( opt_luminance ) |
523 |
{ |
524 |
|
525 |
- int num = responseFillGaps( Iy, w, M ); |
526 |
+ int num = responseFillGaps( Iy, My, w, My ); |
527 |
|
528 |
- float perc = 100.0f * num / M; |
529 |
+ float perc = 100.0f * num / My; |
530 |
|
531 |
VERBOSE_STR << "interpolated " << perc << "% of the Y response curve..." << endl; |
532 |
} |
533 |
else |
534 |
{ |
535 |
|
536 |
- int numr = responseFillGaps ( Ir, w, M ); |
537 |
- int numg = responseFillGaps ( Ig, w, M ); |
538 |
- int numb = responseFillGaps ( Ib, w, M ); |
539 |
+ int numr = responseFillGaps ( Ir, Mr, w, Mr ); |
540 |
+ int numg = responseFillGaps ( Ig, Mg, w, Mg ); |
541 |
+ int numb = responseFillGaps ( Ib, Mb, w, Mb ); |
542 |
|
543 |
- float perc = 100.0f * ( numr + numb + numg) / ( 3 * M ); |
544 |
+ float perc = 100.0f * ( numr + numb + numg) / ( Mr + Mg + Mb ); |
545 |
|
546 |
VERBOSE_STR << "interpolated " << perc << "% of the RGB response curve..." << endl; |
547 |
} |
548 |
@@ -707,25 +753,34 @@ void pfshdrcalibrate( int argc, char* ar |
549 |
|
550 |
/* --------------------- Robertson Calibration --------------------- */ |
551 |
case ROBERTSON_METHOD: |
552 |
+ case ROBERTSON_OLD_METHOD: |
553 |
|
554 |
- VERBOSE_STR << "automatic self-calibration method: robertson" << endl; |
555 |
+ VERBOSE_STR << "automatic self-calibration method: robertson" << (opt_method == ROBERTSON_OLD_METHOD ? " (old)" : "") << endl; |
556 |
|
557 |
if( opt_luminance ) |
558 |
{ |
559 |
VERBOSE_STR << "recovering Y channel..." << endl; |
560 |
- sp = robertson02_getResponse( Yj, imgsY, Iy, w, M); |
561 |
+ sp = opt_method == ROBERTSON_OLD_METHOD |
562 |
+ ? robertson02old_getResponse( Yj, imgsY, Iy, My, w, Mw) |
563 |
+ : robertson02_getResponse( Yj, imgsY, Iy, My, w, Mw); |
564 |
} |
565 |
else |
566 |
{ |
567 |
|
568 |
VERBOSE_STR << "recovering R channel..." << endl; |
569 |
- sp = robertson02_getResponse( Xj, imgsR, Ir, w, M); |
570 |
+ sp = opt_method == ROBERTSON_OLD_METHOD |
571 |
+ ? robertson02old_getResponse( Xj, imgsR, Ir, Mr, w, Mw) |
572 |
+ : robertson02_getResponse( Xj, imgsR, Ir, Mr, w, Mw); |
573 |
|
574 |
VERBOSE_STR << "recovering G channel..." << endl; |
575 |
- sp += robertson02_getResponse( Yj, imgsG, Ig, w, M); |
576 |
+ sp += opt_method == ROBERTSON_OLD_METHOD |
577 |
+ ? robertson02old_getResponse( Yj, imgsG, Ig, Mg, w, Mw) |
578 |
+ : robertson02_getResponse( Yj, imgsG, Ig, Mg, w, Mw); |
579 |
|
580 |
VERBOSE_STR << "recovering B channel..." << endl; |
581 |
- sp += robertson02_getResponse( Zj, imgsB, Ib, w, M); |
582 |
+ sp += opt_method == ROBERTSON_OLD_METHOD |
583 |
+ ? robertson02old_getResponse( Zj, imgsB, Ib, Mb, w, Mw) |
584 |
+ : robertson02_getResponse( Zj, imgsB, Ib, Mb, w, Mw); |
585 |
|
586 |
sp /= 3; |
587 |
} |
588 |
@@ -742,12 +797,14 @@ void pfshdrcalibrate( int argc, char* ar |
589 |
else |
590 |
{ |
591 |
|
592 |
+ if (Mw!=Mr || Mw!=Mg || Mw!=Mb) |
593 |
+ throw pfs::Exception( "number of levels in functions (responce and weighting) must be the same for Mitsunaga & Nayar method"); |
594 |
VERBOSE_STR << "Mitsunaga & Nayar ( " << mitsunaga_sample_no << " samples)" << endl; |
595 |
|
596 |
HDRCaptureMitsunaga* mits_calibration = new HDRCaptureMitsunaga(); |
597 |
|
598 |
mits_calibration -> capture ( imgsR, imgsG, imgsB, |
599 |
- M, 3, |
600 |
+ Mw, 3, |
601 |
Xj, Yj, Zj, |
602 |
mitsunaga_sample_no, |
603 |
Ir, Ig, Ib, |
604 |
@@ -783,36 +840,37 @@ void pfshdrcalibrate( int argc, char* ar |
605 |
|
606 |
/* --------------------- Robertson Apply Curve --------------------- */ |
607 |
case ROBERTSON_METHOD: |
608 |
+ case ROBERTSON_OLD_METHOD: |
609 |
|
610 |
if( opt_luminance ) |
611 |
{ |
612 |
|
613 |
VERBOSE_STR << "applying response to Y channel..." << endl; |
614 |
- sp = robertson02_applyResponse( Yj, imgsY, Iy, w, M); |
615 |
+ sp = opt_method == ROBERTSON_OLD_METHOD |
616 |
+ ? robertson02old_applyResponse( Yj, imgsY, Iy, My, w, Mw) |
617 |
+ : robertson02_applyResponse( Yj, imgsY, Iy, My, w, Mw); |
618 |
|
619 |
} |
620 |
else |
621 |
{ |
622 |
|
623 |
- pfs::Array2D *RGB_out[3] = { Xj, Yj, Zj }; |
624 |
- const ExposureList *exposures[] = { &imgsR, &imgsG, &imgsB }; |
625 |
- const float *resp_curves[] = { Ir, Ig, Ib }; |
626 |
+ if (opt_method == ROBERTSON_METHOD) { |
627 |
+ pfs::Array2D *RGB_out[3] = { Xj, Yj, Zj }; |
628 |
+ const ExposureList *exposures[] = { &imgsR, &imgsG, &imgsB }; |
629 |
+ const float *resp_curves[] = { Ir, Ig, Ib }; |
630 |
+ const int resp_curve_sizes[] = { Mr, Mg, Mb }; |
631 |
|
632 |
- VERBOSE_STR << "applying response to RGB channels..." << endl; |
633 |
- sp = robertson02_applyResponseRGB( RGB_out, exposures, resp_curves, w, M, opt_deghosting ); |
634 |
- |
635 |
-/* |
636 |
- VERBOSE_STR << "applying response to R channel..." << endl; |
637 |
- sp = robertson02_applyResponse( Xj, imgsR, Ir, w, M); |
638 |
- |
639 |
- VERBOSE_STR << "applying response to G channel..." << endl; |
640 |
- sp += robertson02_applyResponse( Yj, imgsG, Ig, w, M); |
641 |
- |
642 |
- VERBOSE_STR << "applying response to B channel..." << endl; |
643 |
- sp += robertson02_applyResponse( Zj, imgsB, Ib, w, M); |
644 |
- |
645 |
- |
646 |
- sp /= 3;*/ |
647 |
+ VERBOSE_STR << "applying response to RGB channels..." << endl; |
648 |
+ sp = robertson02_applyResponseRGB( RGB_out, exposures, resp_curves, resp_curve_sizes, w, Mw, opt_deghosting ); |
649 |
+ } else { |
650 |
+ VERBOSE_STR << "applying response to R channel..." << endl; |
651 |
+ sp = robertson02old_applyResponse( Xj, imgsR, Ir, Mr, w, Mw); |
652 |
+ VERBOSE_STR << "applying response to G channel..." << endl; |
653 |
+ sp += robertson02old_applyResponse( Yj, imgsG, Ig, Mg, w, Mw); |
654 |
+ VERBOSE_STR << "applying response to B channel..." << endl; |
655 |
+ sp += robertson02old_applyResponse( Zj, imgsB, Ib, Mb, w, Mw); |
656 |
+ sp /= 3; |
657 |
+ } |
658 |
|
659 |
if( sp > 0 ) |
660 |
{ |
661 |
@@ -830,17 +888,19 @@ void pfshdrcalibrate( int argc, char* ar |
662 |
throw pfs::Exception( "recovering Y channel not implemented, use robertson calibration." ); |
663 |
else |
664 |
{ |
665 |
+ if (Mw!=Mr || Mw!=Mg || Mw!=Mb) |
666 |
+ throw pfs::Exception( "number of levels in functions (responce and weighting) must be the same for Mitsunaga & Nayar method"); |
667 |
HDRCaptureMitsunaga* mits_calibration = new HDRCaptureMitsunaga(); |
668 |
|
669 |
mits_calibration -> capture ( imgsR, imgsG, imgsB, |
670 |
- M, 3, |
671 |
+ Mw, 3, |
672 |
Xj, Yj, Zj, |
673 |
mitsunaga_sample_no, |
674 |
Ir, Ig, Ib, |
675 |
w, 0 ); |
676 |
|
677 |
|
678 |
- // normalization |
679 |
+ /*// normalization |
680 |
VERBOSE_STR << "Normalization" << endl; |
681 |
|
682 |
float mmax = -1e30; |
683 |
@@ -859,7 +919,7 @@ void pfshdrcalibrate( int argc, char* ar |
684 |
(*Xj)( j ) /= mmax; |
685 |
(*Yj)( j ) /= mmax; |
686 |
(*Zj)( j ) /= mmax; |
687 |
- } |
688 |
+ }*/ |
689 |
|
690 |
} |
691 |
break; |
692 |
@@ -883,16 +943,16 @@ void pfshdrcalibrate( int argc, char* ar |
693 |
{ |
694 |
if( opt_luminance ) |
695 |
{ |
696 |
- responseSave( responseSaveFile, Iy, M, "IY" ); |
697 |
- weightsSave ( responseSaveFile, w, M, "W" ); |
698 |
+ responseSave( responseSaveFile, Iy, My, M, "IY" ); |
699 |
+ weightsSave ( responseSaveFile, w, Mw, M, "W" ); |
700 |
fclose( responseSaveFile ); |
701 |
} |
702 |
else |
703 |
{ |
704 |
- responseSave( responseSaveFile, Ir, M, "IR" ); |
705 |
- responseSave( responseSaveFile, Ig, M, "IG" ); |
706 |
- responseSave( responseSaveFile, Ib, M, "IB" ); |
707 |
- weightsSave ( responseSaveFile, w, M, "W"); |
708 |
+ responseSave( responseSaveFile, Ir, Mr, M, "IR" ); |
709 |
+ responseSave( responseSaveFile, Ig, Mg, M, "IG" ); |
710 |
+ responseSave( responseSaveFile, Ib, Mb, M, "IB" ); |
711 |
+ weightsSave ( responseSaveFile, w, Mw, M, "W"); |
712 |
fclose( responseSaveFile ); |
713 |
} |
714 |
} |
715 |
@@ -919,7 +979,7 @@ void pfshdrcalibrate( int argc, char* ar |
716 |
// clean up memory |
717 |
pfsio.freeFrame( frame ); |
718 |
delete[] w; |
719 |
- delete[] Iy; |
720 |
+ //delete[] Iy; |
721 |
delete[] Ir; |
722 |
delete[] Ig; |
723 |
delete[] Ib; |
724 |
@@ -944,16 +1004,27 @@ int main( int argc, char* argv[] ) |
725 |
pfshdrcalibrate( argc, argv ); |
726 |
} |
727 |
|
728 |
- catch( pfs::Exception ex ) |
729 |
+ catch( std::exception const &ex ) |
730 |
+ { |
731 |
+ fprintf( stderr, PROG_NAME " error: %s\n", ex.what() ); |
732 |
+ return EXIT_FAILURE; |
733 |
+ } |
734 |
+ |
735 |
+ catch( pfs::Exception const &ex ) |
736 |
{ |
737 |
fprintf( stderr, PROG_NAME " error: %s\n", ex.getMessage() ); |
738 |
return EXIT_FAILURE; |
739 |
} |
740 |
- |
741 |
- catch( QuietException ex ) |
742 |
+ |
743 |
+ catch( QuietException const &ex ) |
744 |
{ |
745 |
return EXIT_FAILURE; |
746 |
} |
747 |
- |
748 |
+ |
749 |
+ catch( ... ) |
750 |
+ { |
751 |
+ return EXIT_FAILURE; |
752 |
+ } |
753 |
+ |
754 |
return EXIT_SUCCESS; |
755 |
} |