1 // -*- c-basic-offset: 4 -*- 2 /** @file PanoramaData.h 3 * 4 * @author Pablo d'Angelo <pablo.dangelo@web.de> 5 * 6 * $Id$ 7 * 8 * !! from Panorama.h 1947 9 * 10 * This is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public 12 * License as published by the Free Software Foundation; either 13 * version 2 of the License, or (at your option) any later version. 14 * 15 * This software is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public 21 * License along with this software. If not, see 22 * <http://www.gnu.org/licenses/>. 23 * 24 */ 25 26 #ifndef _PANORAMA_H 27 #define _PANORAMA_H 28 29 // if this file is preprocessed for SWIG, we want to ignore 30 // all the header inclusions that follow: 31 32 #ifndef _HSI_IGNORE_SECTION 33 34 #include <hugin_shared.h> 35 #include <vector> 36 #include <set> 37 #include <iostream> 38 39 #include <hugin_math/Matrix3.h> 40 #include <panodata/PanoramaVariable.h> 41 #include <panodata/SrcPanoImage.h> 42 #include <panodata/ControlPoint.h> 43 #include <panodata/Lens.h> 44 #include <panodata/PanoramaOptions.h> 45 46 #endif // _HSI_IGNORE_SECTION 47 48 namespace HuginBase { 49 50 /// 51 typedef std::set<unsigned int> UIntSet; 52 53 /// 54 typedef std::vector<unsigned int> UIntVector; 55 56 typedef std::vector<UIntSet> UIntSetVector; 57 58 /** Model for a panorama. 59 * 60 * This class contains the properties of a panorama 61 * That is: 62 * - images 63 * - variables that can be optimized. 64 * - links between image variables 65 * - control points 66 * - properites of the output panorama. 67 * 68 * view and controller classes can get information about these 69 * with the getXXX Functions. 70 * 71 * Images and Control points are numbered, and const references are 72 * handed out. this means that all interaction will be based on 73 * image or control point numbers. The references are not stable, 74 * they might disappear when other functions of this class are 75 * called, so its best to get a new reference whenever you need the object. 76 * 77 * This also means that the whole object is not threadsafe and concurrent 78 * access has to be synchronized from the outside. 79 * 80 */ 81 class IMPEX PanoramaData 82 { 83 84 public: 85 86 /// ~PanoramaData()87 virtual ~PanoramaData() {}; 88 89 90 /* get a subset of the panorama 91 * 92 * This returns a panorama that contains only the images specified by \imgs 93 * Useful for operations on a subset of the panorama 94 */ 95 // virtual Panorama getSubset(const UIntSet& imgs) const; 96 97 /* duplicate the panorama 98 * 99 * returns a copy of the pano state, except for the listeners. 100 */ 101 // virtual Panorama duplicate() const; 102 103 /// 104 virtual PanoramaData* getNewSubset(const UIntSet& imgs) const =0; 105 106 /// 107 virtual PanoramaData* getNewCopy() const =0; 108 109 virtual PanoramaData* getUnlinkedSubset(UIntSetVector& imageGroups) const = 0; 110 111 // -- Data Access -- 112 113 // = images = 114 115 /// number of images. 116 virtual std::size_t getNrOfImages() const =0; 117 118 /// get a panorama image, counting starts with 0 119 virtual const SrcPanoImage& getImage(std::size_t nr) const =0; 120 121 /// set a panorama image, counting starts with 0 122 virtual void setImage(std::size_t nr, const SrcPanoImage & img) =0; 123 124 /// the the number for a specific image 125 // virtual unsigned int getImageNr(const PanoImage * image) const =0; 126 127 /** add an Image to the panorama 128 * 129 * The Image must be initialized, the Lens must exist. 130 * 131 */ 132 virtual unsigned int addImage(const SrcPanoImage& img) =0; 133 134 /** creates an image, from filename, and a Lens, if needed */ 135 // virtual int addImageAndLens(const std::string & filename) =0; 136 137 /** add an Image to the panorama 138 * @return image number 139 */ 140 // virtual unsigned int addImage(const std::string & filename) =0; 141 142 /** remove an Image. 143 * 144 * also deletes/updates all associated control points. 145 */ 146 virtual void removeImage(unsigned int nr) =0; 147 148 /** swap images. 149 * 150 * swaps the images, image @p img1 becomes @p img2 and the other way round 151 */ 152 virtual void swapImages(unsigned int img1, unsigned int img2) =0; 153 154 /** moves images. 155 * 156 * moves the image from pos1 to pos2 157 */ 158 virtual void moveImage(size_t img1, size_t img2) =0; 159 160 /// get a complete description of a source image 161 virtual SrcPanoImage getSrcImage(unsigned imgNr) const =0; 162 163 /** set input image parameters 164 * TODO: Propagate changes to linked images. 165 */ 166 virtual void setSrcImage(unsigned int nr, const SrcPanoImage & img) =0; 167 168 /** set a new image filename 169 * 170 * It is assumed that it is of the same size 171 * as the old image. 172 * 173 */ 174 virtual void setImageFilename(unsigned int img, const std::string & fname) =0; 175 176 /** mark an image as active or inactive. 177 * 178 * This is only a flag, that can be turned on or off. 179 * If an image is marked active, then it should 180 * be used for optimizing and stitching. 181 * 182 * However, this is not done automatically. One has 183 * to use getActiveImages() to get the numbers of the 184 * active images, and pass these to the respective 185 * functions that do the stitching or optimisation 186 */ 187 virtual void activateImage(unsigned int imgNr, bool active=true) =0; 188 189 /** get active images */ 190 virtual UIntSet getActiveImages() const =0; 191 192 /* Link image variable functions. Used to group image variables which 193 * should share the same value. The initial value is the one kept by 194 * the image with number sourceImgNr. 195 */ 196 #define image_variable( name, type, default_value ) \ 197 virtual void linkImageVariable##name(unsigned int sourceImgNr, unsigned int destImgNr) =0; 198 #include "image_variables.h" 199 #undef image_variable 200 201 /* Unlink image variable functions. Makes a image variable independant 202 * of the other images. 203 */ 204 #define image_variable( name, type, default_value ) \ 205 virtual void unlinkImageVariable##name(unsigned int imgNr) =0; 206 #include "image_variables.h" 207 #undef image_variable 208 209 210 // = CPs = 211 212 /// number of control points 213 virtual std::size_t getNrOfCtrlPoints() const =0; 214 215 /// get a control point, counting starts with 0 216 virtual const ControlPoint & getCtrlPoint(std::size_t nr) const =0; 217 218 /// get all control point of this Panorama 219 virtual const CPVector & getCtrlPoints() const =0; 220 221 /** return all control points for a given image. */ 222 virtual std::vector<unsigned int> getCtrlPointsForImage(unsigned int imgNr) const =0; 223 224 /** set all control points (Ippei: Is this supposed to be 'add' method?) */ 225 virtual void setCtrlPoints(const CPVector & points) =0; 226 227 /** add a new control point.*/ 228 virtual unsigned int addCtrlPoint(const ControlPoint & point) =0; 229 230 /** remove a control point. 231 */ 232 virtual void removeCtrlPoint(unsigned int pNr) =0; 233 234 /** removes duplicates control points 235 */ 236 virtual void removeDuplicateCtrlPoints() =0; 237 238 /** change a control Point. 239 */ 240 virtual void changeControlPoint(unsigned int pNr, const ControlPoint & point) =0; 241 242 /// get the number of a control point 243 // virtual unsigned int getCtrlPointNr(const ControlPoint * point) const =0; 244 245 /** get the next unused line number for t3, ... control point creation */ 246 virtual int getNextCPTypeLineNumber() const =0; 247 248 /** assign new mode line numbers, if required */ 249 virtual void updateLineCtrlPoints() =0; 250 251 252 /** update control points distances. 253 * 254 * updates control distances and position in final panorama 255 * usually used to set the changes from the optimization. 256 * The control points must be the same as in 257 */ 258 virtual void updateCtrlPointErrors(const CPVector & controlPoints) =0; 259 260 /** update control points for a subset of images. 261 * 262 * Usually, the control point subset is created using subset() 263 * The number and ordering and control points must not be changed 264 * between the call to subset() and this function. 265 */ 266 virtual void updateCtrlPointErrors(const UIntSet & imgs, const CPVector & cps) =0; 267 268 // = Variables = 269 /* TODO most of this section needs fixing. The image variables are now stored 270 * in SrcPanoImage objects, the PanoramaData object should just duplicate 271 * the changes across all images sharing variables. 272 * We also need access to the links of the variables. 273 * At some point, this functions should be removed. Do not create new 274 * code using them. Instead, use getSrcImage. 275 */ 276 /// get variables of this panorama 277 virtual VariableMapVector getVariables() const =0; 278 279 /** get variables of an image 280 * 281 * Depreciated: Please use SrcPanoImage objects for variable access. 282 * 283 * @todo remove when not used. 284 * 285 * Note: no longer returns a reference as the no variable map with the 286 * correct values exists, now we use individual member variables in 287 * SrcPanoImage. 288 */ 289 virtual const VariableMap getImageVariables(unsigned int imgNr) const =0; 290 291 /** Set the variables. 292 * 293 * Usually used when the optimizer results should be applied. 294 * 295 */ 296 virtual void updateVariables(const VariableMapVector & vars) =0; 297 298 /** update variables for some specific images */ 299 virtual void updateVariables(const UIntSet & imgs, const VariableMapVector & var) =0; 300 301 /** Set variables for a single picture. 302 * 303 */ 304 virtual void updateVariables(unsigned int imgNr, const VariableMap & var) =0; 305 306 /** update a single variable 307 * 308 * It updates other images when the variable is linked 309 */ 310 virtual void updateVariable(unsigned int imgNr, const Variable &var) =0; 311 312 /** update the global white balace of the panorama by multiplying 313 * the red and blue factor of each image with given factors 314 */ 315 virtual void updateWhiteBalance(double redFactor, double blueFactor) =0; 316 317 // = Optimise Vector = 318 319 /** return the optimize settings stored inside panorama */ 320 virtual const OptimizeVector & getOptimizeVector() const =0; 321 322 /** set optimize setting */ 323 virtual void setOptimizeVector(const OptimizeVector & optvec) =0; 324 325 326 /** returns optimizer master switch */ 327 virtual const int getOptimizerSwitch() const =0; 328 /** set optimizer master switch */ 329 virtual void setOptimizerSwitch(const int newSwitch) =0; 330 331 /** return the photometric optimizer master switch */ 332 virtual const int getPhotometricOptimizerSwitch() const =0; 333 /** sets the photometric optimizer master switch */ 334 virtual void setPhotometricOptimizerSwitch(const int newSwitch) =0; 335 336 // = Panorama options = 337 338 /** returns the options for this panorama */ 339 virtual const PanoramaOptions & getOptions() const =0; 340 341 /** set new output settings 342 * This is not used directly for optimizing/stiching, but it can 343 * be feed into runOptimizer() and runStitcher(). 344 */ 345 virtual void setOptions(const PanoramaOptions & opt) =0; 346 347 348 349 // -- script interface -- 350 351 /** read after optimization, fills in control point errors. 352 * 353 * @param set of image numbers that where used during by 354 * printPanoramaScript(). 355 * @param vars will be set the the optimzied variables 356 * @param ctrlPoints will contain the controlpoints, with distance 357 * information 358 * 359 * @return false on error (could not read optimizer output, parse error) 360 */ 361 virtual void parseOptimizerScript(std::istream & i, 362 const UIntSet & imgs, 363 VariableMapVector & imgVars, 364 CPVector & ctrlPoints) const =0; 365 366 /// create an optimizer script 367 virtual void printPanoramaScript(std::ostream & o, 368 const OptimizeVector & optvars, 369 const PanoramaOptions & options, 370 const UIntSet & imgs, 371 bool forPTOptimizer, 372 const std::string & stripPrefix="") const =0; 373 374 /// create the stitcher script 375 virtual void printStitcherScript(std::ostream & o, 376 const PanoramaOptions & target, 377 const UIntSet & imgs) const =0; 378 379 380 // -- maintainance -- 381 382 public: 383 /// tells the data container to perform some maintainance if neccesary 384 virtual void changeFinished() =0; 385 386 /// mark image change for maintainance 387 virtual void imageChanged(unsigned int imgNr) =0; 388 /** set complete mask list for image with number */ 389 virtual void updateMasksForImage(unsigned int imgNr, MaskPolygonVector newMasks)=0; 390 /** updates all active masks 391 * 392 * this is necessary after variables of *one* image has changed, 393 * because positive masks have to be updated 394 */ 395 virtual void updateMasks(bool convertPosMaskToNeg=false)=0; 396 /** transfers given mask from image imgNr to all targetImgs 397 */ 398 virtual void transferMask(MaskPolygon mask,unsigned int imgNr, const UIntSet& targetImgs)=0; 399 /** updates the optimize vector according to master switches */ 400 virtual void updateOptimizeVector()=0; 401 /** returns set of reference image and images linked with reference images */ 402 virtual std::set<size_t> getRefImages()=0; 403 /** checks if yaw/pitch/roll of reference image can be check, 404 * it depends on number and type of control points */ 405 virtual void checkRefOptStatus(bool& linkRefImgsYaw, bool& linkRefImgsPitch, bool& linkRefImgsRoll)=0; 406 407 }; 408 409 410 411 /** this handler class will receive change events from the Panorama. 412 * 413 * Maybe a fine grained event interface is better, but it can be 414 * added later. 415 */ 416 class PanoramaObserver 417 { 418 public: 419 420 /// ~PanoramaObserver()421 virtual ~PanoramaObserver() {}; 422 423 /** Notification about a Panorama change. 424 * 425 * This function will always be called, even when the 426 * change could be handled by panoramaImageAdded() or 427 * other notify functions. 428 * 429 * This allows lazy observers to just listen to 430 * panoramaChanged(). 431 * 432 */ 433 virtual void panoramaChanged(Panorama &pano) =0; 434 435 /** notifies about changes to images 436 * 437 * Images might have been added/removed. to find out 438 * how many images are still there, use Panorama::getNrOfImages. 439 * 440 * @param pano the panorama object that changed 441 * @param changed set of changed images 442 * 443 */ 444 virtual void panoramaImagesChanged(Panorama& pano, 445 const UIntSet& changed) =0; 446 447 448 }; 449 450 451 /** Memento class for a PanoramaData object 452 * 453 * Preserves the internal state of a PanoramaData. 454 * Used when other objects need to get/set the state without 455 * knowing anything about the internals. 456 * 457 */ 458 class IMPEX PanoramaDataMemento 459 { 460 protected: 461 /// force pure abstract behaviour PanoramaDataMemento()462 PanoramaDataMemento() {}; 463 464 public: 465 /// ~PanoramaDataMemento()466 virtual ~PanoramaDataMemento() {}; 467 }; 468 469 470 /// 471 class IMPEX ManagedPanoramaData : public PanoramaData 472 { 473 public: 474 475 /// ~ManagedPanoramaData()476 virtual ~ManagedPanoramaData() {}; 477 478 479 // -- Observing -- 480 481 public: 482 /** add a panorama observer. 483 * 484 * It will recieve all change messages. 485 * An observer can only be added once. if its added twice, 486 * the second addObserver() will have no effect. 487 */ 488 virtual void addObserver(PanoramaObserver *o) =0; 489 490 /** remove a panorama observer. 491 * 492 * Observers must be removed before they are destroyed, 493 * else Panorama will try to notify them after they have been 494 * destroyed 495 * 496 * @return true if observer was known, false otherwise. 497 */ 498 virtual bool removeObserver(PanoramaObserver *observer) =0; 499 500 /** remove all panorama observers. 501 * 502 * @warning this is a hack. it must not be used on normal Panorama's. 503 */ 504 virtual void clearObservers() =0; 505 506 /** notify observers about changes in this class 507 * 508 * This needs to be called explicitly by somebody after 509 * changes have been made. 510 * Allows to compress multiple changes into one notification. 511 */ 512 virtual void changeFinished() =0; 513 514 /** clear dirty flag. call after load, save or new project */ 515 virtual void clearDirty() =0; 516 517 /** mark image for change notification. 518 * 519 * Does not send the notification, this is left 520 * to changedFinished() 521 */ 522 virtual void imageChanged(unsigned int imgNr) =0; 523 524 525 // -- Memento interface -- 526 527 public: 528 /// get the internal state 529 virtual PanoramaDataMemento* getNewMemento() const =0; 530 531 /// set the internal state 532 virtual bool setMementoToCopyOf(const PanoramaDataMemento* const memento) =0; 533 534 535 // -- Optimization Status -- 536 537 public: 538 /** true if control points or lens variables 539 * have been changed after the last optimisation 540 */ 541 virtual bool needsOptimization() =0; 542 543 /// 544 virtual void markAsOptimized(bool optimized=true) =0; 545 546 }; 547 548 549 } // namespace 550 551 552 553 554 #endif // _PANORAMA_H 555