Hugin trunk 0.1
Loading...
Searching...
No Matches
PanoToolsInterface.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
2
27#include <hugin_config.h>
28
29#include <stdlib.h>
30
31#include "PanoToolsInterface.h"
32
33#include <vector>
34#include <set>
35#include <hugin_utils/utils.h>
39
40namespace HuginBase { namespace PTools {
41
49
50void Transform::updatePTData(const vigra::Diff2D &srcSize,
51 const VariableMap & srcVars,
53 const vigra::Diff2D & destSize,
55 const std::vector<double> & destProjParam,
56 double destHFOV)
57{
58 if (m_initialized) {
61 }
62
63 // fill our data into the Pano Tools structures.
65 srcVars, srcProj, true);
67}
68
69
70void Transform::createTransform(const PanoramaData & pano, unsigned int imgNr,
71 const PanoramaOptions & dest, vigra::Diff2D srcSize)
72{
73 const SrcPanoImage & img = pano.getImage(imgNr);
74 if (srcSize.x == 0 && srcSize.y == 0) {
75 srcSize.x = img.getWidth();
76 srcSize.y = img.getHeight();
77 }
79 pano.getImageVariables(imgNr),
80 (Lens::LensProjectionFormat)pano.getImage(imgNr).getProjection(),
81 vigra::Diff2D(dest.getWidth(), dest.getHeight()),
82 dest.getProjection(),
83 dest.getProjectionParameters(),
84 dest.getHFOV(),
85 vigra::Diff2D(img.getWidth(), img.getHeight()));
86}
87
89{
90 VariableMap vars;
91 // not very nice, but I don't like to change all the stuff in this file..
92 vars.insert(make_pair(std::string("v"), Variable(std::string("v"), src.getHFOV())));
93 vars.insert(make_pair(std::string("a"), Variable("a", src.getRadialDistortion()[0])));
94 vars.insert(make_pair(std::string("b"), Variable("b", src.getRadialDistortion()[1])));
95 vars.insert(make_pair(std::string("c"), Variable("c", src.getRadialDistortion()[2])));
96 vars.insert(make_pair(std::string("d"), Variable("d", src.getRadialDistortionCenterShift().x)));
97 vars.insert(make_pair(std::string("e"), Variable("e", src.getRadialDistortionCenterShift().y)));
98 vars.insert(make_pair(std::string("g"), Variable("g", src.getShear().x)));
99 vars.insert(make_pair(std::string("t"), Variable("t", src.getShear().y)));
100
101 vars.insert(make_pair(std::string("r"), Variable("r", src.getRoll())));
102 vars.insert(make_pair(std::string("p"), Variable("p", src.getPitch())));
103 vars.insert(make_pair(std::string("y"), Variable("y", src.getYaw())));
104
105 vars.insert(make_pair(std::string("TrX"), Variable("TrX", src.getX())));
106 vars.insert(make_pair(std::string("TrY"), Variable("TrY", src.getY())));
107 vars.insert(make_pair(std::string("TrZ"), Variable("TrZ", src.getZ())));
108
109 vars.insert(make_pair(std::string("Tpy"), Variable("Tpy", src.getTranslationPlaneYaw())));
110 vars.insert(make_pair(std::string("Tpp"), Variable("Tpp", src.getTranslationPlanePitch())));
111
112 createInvTransform(src.getSize(),
113 vars,
114 (Lens::LensProjectionFormat) src.getProjection(),
115 dest.getSize(),
116 dest.getProjection(),
117 dest.getProjectionParameters(),
118 dest.getHFOV(),
119 src.getSize());
120}
121
123{
124
125 VariableMap vars;
126 // not very nice, but I don't like to change all the stuff in this file..
127 vars.insert(make_pair(std::string("v"), Variable(std::string("v"), src.getHFOV())));
128 vars.insert(make_pair(std::string("a"), Variable("a", src.getRadialDistortion()[0])));
129 vars.insert(make_pair(std::string("b"), Variable("b", src.getRadialDistortion()[1])));
130 vars.insert(make_pair(std::string("c"), Variable("c", src.getRadialDistortion()[2])));
131 vars.insert(make_pair(std::string("d"), Variable("d", src.getRadialDistortionCenterShift().x)));
132 vars.insert(make_pair(std::string("e"), Variable("e", src.getRadialDistortionCenterShift().y)));
133 vars.insert(make_pair(std::string("g"), Variable("g", src.getShear().x)));
134 vars.insert(make_pair(std::string("t"), Variable("t", src.getShear().y)));
135
136 vars.insert(make_pair(std::string("r"), Variable("r", src.getRoll())));
137 vars.insert(make_pair(std::string("p"), Variable("p", src.getPitch())));
138 vars.insert(make_pair(std::string("y"), Variable("y", src.getYaw())));
139
140 vars.insert(make_pair(std::string("TrX"), Variable("TrX", src.getX())));
141 vars.insert(make_pair(std::string("TrY"), Variable("TrY", src.getY())));
142 vars.insert(make_pair(std::string("TrZ"), Variable("TrZ", src.getZ())));
143
144 vars.insert(make_pair(std::string("Tpy"), Variable("Tpy", src.getTranslationPlaneYaw())));
145 vars.insert(make_pair(std::string("Tpp"), Variable("Tpp", src.getTranslationPlanePitch())));
146
147 createTransform(src.getSize(),
148 vars,
149 (Lens::LensProjectionFormat) src.getProjection(),
150 dest.getSize(),
151 dest.getProjection(),
152 dest.getProjectionParameters(),
153 dest.getHFOV(),
154 src.getSize());
155}
156
157
158void Transform::createTransform(const vigra::Diff2D & srcSize,
161 const vigra::Diff2D &destSize,
163 const std::vector<double> & destProjParam,
164 double destHFOV,
165 const vigra::Diff2D & originalSrcSize)
166{
167 m_srcTX = destSize.x/2.0;
168 m_srcTY = destSize.y/2.0;
169
170 m_destTX = srcSize.x/2.0;
171 m_destTY = srcSize.y/2.0;
172
173 // adjust parameters dependant on the image size.
174 if (originalSrcSize.x != 0 && originalSrcSize.y != 0) {
175 double rx = srcSize.x / (double)originalSrcSize.x;
176 double ry = srcSize.y / (double)originalSrcSize.y;
177 map_get(srcVars,"d").setValue( map_get(srcVars,"d").getValue() * rx );
178 map_get(srcVars,"e").setValue( map_get(srcVars,"e").getValue() * ry );
179 }
180
183 // create the actual stack
185}
186
187
188void Transform::createInvTransform(const PanoramaData & pano, unsigned int imgNr,
189 const PanoramaOptions & dest, vigra::Diff2D srcSize)
190{
191 const SrcPanoImage & img = pano.getImage(imgNr);
192 if (srcSize.x == 0 && srcSize.y == 0) {
193 srcSize.x = img.getWidth();
194 srcSize.y = img.getHeight();
195 }
197 pano.getImageVariables(imgNr),
198 (Lens::LensProjectionFormat)pano.getImage(imgNr).getProjection(),
199 vigra::Diff2D(dest.getWidth(), dest.getHeight()),
200 dest.getProjection(),
201 dest.getProjectionParameters(),
202 dest.getHFOV(),
203 vigra::Diff2D(img.getWidth(), img.getHeight()));
204}
205
206void Transform::createInvTransform(const vigra::Diff2D & srcSize,
209 const vigra::Diff2D & destSize,
211 const std::vector<double> & destProjParam,
212 double destHFOV,
213 const vigra::Diff2D & originalSrcSize)
214{
215 m_srcTX = srcSize.x/2.0;
216 m_srcTY = srcSize.y/2.0;
217
218 m_destTX = destSize.x/2.0;
219 m_destTY = destSize.y/2.0;
220
221 // adjust parameters dependant on the image size.
222 if (originalSrcSize.x != 0 && originalSrcSize.y != 0) {
223 double rx = srcSize.x / (double)originalSrcSize.x;
224 double ry = srcSize.y / (double)originalSrcSize.y;
225 map_get(srcVars,"d").setValue( map_get(srcVars,"d").getValue() * rx );
226 map_get(srcVars,"e").setValue( map_get(srcVars,"e").getValue() * ry );
227 }
228
232 destHFOV);
233 // create the actual stack
235}
236
237
238bool Transform::transform(double & x_dest, double & y_dest,
239 double x_src, double y_src) const
240{
241 void * params= (void *) (&m_stack);
242 return execute_stack_new(x_src, y_src, &x_dest, &y_dest, params) != 0;
243}
244
247{
248 double x_dest, y_dest;
249 void * params= (void *) (&m_stack);
250 bool ok = execute_stack_new(src.x, src.y, &x_dest, &y_dest, params) != 0;
251 dest.x = x_dest;
252 dest.y = y_dest;
253 return ok;
254}
255
260 double x_src, double y_src) const
261{
262 x_src -= m_srcTX - 0.5 ;
263 y_src -= m_srcTY - 0.5;
264
265 void * params= (void *) (&m_stack);
267 if(ok)
268 {
269 x_dest += m_destTX - 0.5;
270 y_dest += m_destTY - 0.5;
271 }
272 else
273 {
274 // if the image coordinates could not transformed, e.g. this can happen
275 // with non-zero translation parameters, set the result to a point
276 // outside the image (-1,-1)
277 // better solution would be to evaluate the return value of transformImgCoord
278 x_dest = -1;
279 y_dest = -1;
280 };
281 return ok;
282}
283
284
286{
288 if (gl.im) {
289 for (int i = 0; i < gl.numIm; i++) {
290 VariableMap vars;
291 vars.insert(make_pair(std::string("TrX"), Variable("TrX", gl.im[i].cP.trans_x)));
292 vars.insert(make_pair(std::string("TrY"), Variable("TrY", gl.im[i].cP.trans_y)));
293 vars.insert(make_pair(std::string("TrZ"), Variable("TrZ", gl.im[i].cP.trans_z)));
294 vars.insert(make_pair(std::string("Tpy"), Variable("Tpy", gl.im[i].cP.trans_yaw)));
295 vars.insert(make_pair(std::string("Tpp"), Variable("Tpp", gl.im[i].cP.trans_pitch)));
296
297 vars.insert(make_pair(std::string("v"), Variable("v", gl.im[i].hfov)));
298 vars.insert(make_pair(std::string("y"), Variable("y", gl.im[i].yaw)));
299 vars.insert(make_pair(std::string("r"), Variable("r", gl.im[i].roll)));
300 vars.insert(make_pair(std::string("p"), Variable("p", gl.im[i].pitch)));
301 vars.insert(make_pair(std::string("a"), Variable("a", gl.im[i].cP.radial_params[0][3])));
302 vars.insert(make_pair(std::string("b"), Variable("b", gl.im[i].cP.radial_params[0][2])));
303 vars.insert(make_pair(std::string("c"), Variable("c", gl.im[i].cP.radial_params[0][1])));
304
305 vars.insert(make_pair(std::string("e"), Variable("e", gl.im[i].cP.vertical_params[0])));
306 vars.insert(make_pair(std::string("d"), Variable("d", gl.im[i].cP.horizontal_params[0])));
307
308 //Modified by Dev
309 vars.insert(make_pair(std::string("g"), Variable("g", gl.im[i].cP.shear_x)));
310 vars.insert(make_pair(std::string("t"), Variable("t", gl.im[i].cP.shear_y)));
311
312
313 res.push_back(vars);
314 }
315 }
316 return res;
317}
318
320{
321 CPVector result;
322 if (gl.cpt) {
323 for (int i = 0; i < gl.numPts; i++) {
324 ControlPoint pnt(gl.cpt[i].num[0], gl.cpt[i].x[0], gl.cpt[i].y[0],
325 gl.cpt[i].num[1], gl.cpt[i].x[1], gl.cpt[i].y[1], (ControlPoint::OptimizeMode) gl.cpt[i].type);
326 pnt.error = sqrt(distSquared(i));
327 result.push_back(pnt);
328 }
329 }
330 return result;
331}
332
333
334void setDestImage(Image & image, vigra::Diff2D size,
335 unsigned char * imageData,
337 const std::vector<double> & projParams,
338 double destHFOV)
339{
340 SetImageDefaults(&image);
341 image.width = size.x;
342 image.height = size.y;
343 image.bytesPerLine = image.width*3;
344 image.bitsPerPixel = 24;
345 image.dataSize = image.height * image.bytesPerLine;
346 // Allocate memory for pointer to pointer to image data
347// image.data = (unsigned char**)malloc( sizeof(unsigned char*) );
348// if(image.data == NULL) {
349// DEBUG_FATAL("Out of memory");
350// }
351 image.data = 0;
354 image.format = projd.internalFormat;
355 } else {
356 image.format = _equirectangular;
357 DEBUG_ERROR("unsupported projection");
358 }
359 image.formatParamCount = projd.numberOfParameters;
360 assert(image.formatParamCount == (int) projParams.size());
361 for (int i=0; i < projd.numberOfParameters; i++) {
362 image.formatParam[i] = projParams[i];
363 DEBUG_DEBUG("projection parameter " << i << ": " << image.formatParam[i]);
364 }
365 image.hfov = destHFOV;
366}
367
368
369// internal function, used by setFullImage() to set the distortion parameters
370void initCPrefs(cPrefs & p, const VariableMap &vars)
371{
373
374 double val;
375 double a = const_map_get(vars,"a").getValue();
376 double b = const_map_get(vars,"b").getValue();
377 double c = const_map_get(vars,"c").getValue();
378 if (a != 0.0 || b != 0.0 || c != 0) {
379 p.radial = 1;
380 p.radial_params[0][3] = p.radial_params[1][3] = p.radial_params[2][3] = a;
381 p.radial_params[0][2] = p.radial_params[1][2] = p.radial_params[2][2] = b;
382 p.radial_params[0][1] = p.radial_params[1][1] = p.radial_params[2][1] = c;
383 double d = 1.0 - (a+b+c);
384 p.radial_params[0][0] = p.radial_params[1][0] = p.radial_params[2][0] = d;
385 } else {
386 p.radial = 0;
387 }
388
389 val = const_map_get(vars,"e").getValue();
390 if (val != 0.0) {
391 p.vertical = TRUE;
392 p.vertical_params[0] = p.vertical_params[1] = p.vertical_params[2] = val;
393 } else {
394 p.vertical = FALSE;
395 p.vertical_params[0] = p.vertical_params[1] = p.vertical_params[2] = 0;
396 }
397
398 val = const_map_get(vars,"d").getValue();
399 if (val != 0.0) {
400 p.horizontal = TRUE;
401 p.horizontal_params[0] = p.horizontal_params[1] = p.horizontal_params[2] = val;
402 } else {
403 p.horizontal = FALSE;
404 p.horizontal_params[0] = p.horizontal_params[1] = p.horizontal_params[2] = 0;
405 }
406
407 p.trans_x = const_map_get(vars,"TrX").getValue();
408 p.trans_y = const_map_get(vars,"TrY").getValue();
409 p.trans_z = const_map_get(vars,"TrZ").getValue();
410 if (p.trans_x != 0 || p.trans_y != 0 || p.trans_z != 0)
411 {
412 p.trans = TRUE;
413 p.trans_yaw = const_map_get(vars,"Tpy").getValue();
414 p.trans_pitch = const_map_get(vars,"Tpp").getValue();
415 }
416 else
417 {
418 p.trans = FALSE;
419 p.trans_yaw = 0;
420 p.trans_pitch = 0;
421 }
422
423
424 // FIXME add shear parameters
425 val = const_map_get(vars, "g").getValue();
426 double val2 = const_map_get(vars, "t").getValue();
427 if (val2 != 0.0 || val != 0.0) {
428 p.shear = TRUE;
429 p.shear_x = val;
430 p.shear_y = val2;
431 } else {
432 p.shear = FALSE;
433 }
434 p.resize = FALSE;
435 p.luminance = FALSE;
436 p.cutFrame = FALSE;
437 p.fourier = FALSE;
438
439 // calculate correction radius
441
442}
443
444void setFullImage(Image & image, vigra::Diff2D size,
445 unsigned char * imageData, const VariableMap & vars,
448{
449 SetImageDefaults(&image);
450 image.width = size.x;
451 image.height = size.y;
452 image.bytesPerLine = image.width*3;
453 image.bitsPerPixel = 24;
454 image.dataSize = image.height * image.bytesPerLine;
455
456#if 0
457 // Allocate memory for pointer to pointer to image data
458 image.data = (unsigned char**)malloc( sizeof(unsigned char*) );
459 if(image.data == NULL) {
460 DEBUG_FATAL("Out of memory");
461 }
462 *(image.data) = imageData;
463#else
464 image.data = 0;
465#endif
466
467 image.dataformat = _RGB;
468 switch (format) {
470 image.format = _rectilinear;
471 break;
473 image.format = _panorama;
474 break;
476 image.format = _fisheye_circ;
477 break;
479 image.format = _fisheye_ff;
480 break;
482 image.format = _equirectangular;
483 break;
485 image.format = _orthographic;
486 break;
488 image.format = _stereographic;
489 break;
491 image.format = _equisolid;
492 break;
494 image.format = _thoby;
495 }
496 image.hfov = const_map_get(vars,"v").getValue();
497 image.yaw = const_map_get(vars,"y").getValue();
498 image.pitch = const_map_get(vars,"p").getValue();
499 image.roll = const_map_get(vars,"r").getValue();
500
501 //fill cPrefs struct
502 if (correctDistortions) {
503 initCPrefs(image.cP,vars);
504 }
505
506 // no name
507 image.name[0]=0;
508
509 image.selection.top = 0;
510 image.selection.left = 0;
511 image.selection.right = image.width;
512 image.selection.bottom = image.height;
513}
514
515// ===========================================================================
516// ===========================================================================
517
518
519// prepare a Trform struct for the adjust operation, image -> pano
521{
522 trf.src = (Image *) malloc(sizeof(Image));
524 trf.dest = (Image *) malloc(sizeof(Image));
525 SetImageDefaults(trf.dest);
526 trf.success = TRUE;
527 trf.tool = _adjust;
529 trf.data = 0;
530 trf.interpolator = _nn;
531 trf.gamma = 1.0;
532}
533
534
535void freeImage(Image &img)
536{
537 if (img.data) {
538 myfree((void**)img.data);
539 }
540}
541
542}} // namespace
Somewhere to specify what variables belong to what.
represents a control point
OptimizeMode
minimize x,y or both.
bool transformImgCoord(double &x_dest, double &y_dest, double x_src, double y_src) const
like transform, but return image coordinates, not cartesian coordinates
void createTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
initialize pano->image transformation
void createInvTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
create image->pano transformation
void updatePTData(const vigra::Diff2D &srcSize, const VariableMap &srcVars, Lens::LensProjectionFormat &srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat &destProj, const std::vector< double > &destProjParam, double destHFOV)
bool transform(double &x_dest, double &y_dest, double x_src, double y_src) const
excecute transform
Model for a panorama.
virtual const VariableMap getImageVariables(unsigned int imgNr) const =0
get variables of an image
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
Panorama image options.
ProjectionFormat
Projection of final panorama.
All variables of a source image.
int getWidth() const
Get the width of the image in pixels.
int getHeight() const
Get the height of the image in pixels.
a variable has a value and a name.
#define DEBUG_ERROR(msg)
Definition utils.h:76
#define DEBUG_DEBUG(msg)
Definition utils.h:68
#define DEBUG_FATAL(msg)
Definition utils.h:78
void setDestImage(Image &image, vigra::Diff2D size, unsigned char *imageData, const PanoramaOptions::ProjectionFormat &format, const std::vector< double > &projParams, double destHFOV)
set an output image, with properties from opts, that points to the bitmap data of imgData
void setFullImage(Image &image, vigra::Diff2D size, unsigned char *imageData, const VariableMap &vars, const Lens::LensProjectionFormat format, bool correctDistortions)
fills image with a complete input image, including distortion correction parameters if correctDistort...
VariableMapVector GetAlignInfoVariables(const AlignInfo &gl)
void createAdjustTrform(TrformStr &trf)
void initCPrefs(cPrefs &p, const VariableMap &vars)
CPVector GetAlignInfoCtrlPoints(const AlignInfo &gl)
void freeImage(Image &img)
free the pointer storage needed by Image
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
Definition wxcms.cpp:39
std::vector< VariableMap > VariableMapVector
std::vector< ControlPoint > CPVector
std::map< std::string, Variable > VariableMap
Map::mapped_type & map_get(Map &m, const typename Map::key_type &key)
get a map element.
Definition stl_utils.h:98
const Map::mapped_type & const_map_get(const Map &m, const typename Map::key_type &key)
Definition stl_utils.h:110
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