1 // -*- c-basic-offset: 4 -*- 2 3 /** @file SrcPanoImage.h 4 * 5 * @brief 6 * 7 * @author Pablo d'Angelo <pablo.dangelo@web.de> 8 * James Legg 9 * 10 * !! from PanoImage.h 1970 11 * 12 * $Id$ 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public 16 * License as published by the Free Software Foundation; either 17 * version 2 of the License, or (at your option) any later version. 18 * 19 * This software is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public 25 * License along with this software. If not, see 26 * <http://www.gnu.org/licenses/>. 27 * 28 */ 29 30 #ifndef _PANODATA_SRCPANOIMAGE_H 31 #define _PANODATA_SRCPANOIMAGE_H 32 33 // if this file is preprocessed for SWIG, we want to ignore 34 // all the header inclusions that follow: 35 36 #ifndef _HSI_IGNORE_SECTION 37 38 #include <hugin_shared.h> 39 #include <hugin_config.h> 40 #include <iostream> 41 #include <vector> 42 #include <vigra/diff2d.hxx> 43 44 #include <hugin_utils/utils.h> 45 #include <hugin_math/hugin_math.h> 46 #include "PanoramaVariable.h" 47 #include "ImageVariable.h" 48 #include "Mask.h" 49 #include <map> 50 51 #endif // _HSI_IGNORE_SECTION 52 53 namespace HuginBase { 54 55 class Panorama; 56 57 /** typedef for general map for storing metadata in files */ 58 typedef std::map<std::string, std::string> FileMetaData; 59 60 /** Base class containing all the variables, but missing some of the other 61 * important functions and with some daft accessors. 62 * 63 * Used for lazy metaprogramming, we include image_variables.h several times 64 * with different defintions of image_variable to get all the repetitive bits 65 * out the way. This should reduce typos and cut and paste errors. 66 */ 67 class IMPEX BaseSrcPanoImage 68 { 69 public: 70 /// 71 enum Projection { 72 RECTILINEAR = 0, 73 PANORAMIC = 1, 74 CIRCULAR_FISHEYE = 2, 75 FULL_FRAME_FISHEYE = 3, 76 EQUIRECTANGULAR = 4, 77 FISHEYE_ORTHOGRAPHIC = 8, 78 FISHEYE_STEREOGRAPHIC = 10, 79 FISHEYE_EQUISOLID = 21, 80 FISHEYE_THOBY = 20 81 }; 82 83 /// 84 enum CropMode { 85 NO_CROP=0, 86 CROP_RECTANGLE=1, 87 CROP_CIRCLE=2 88 }; 89 90 /// vignetting correction mode (bitflags, no real enum) 91 enum VignettingCorrMode { 92 VIGCORR_NONE = 0, ///< no vignetting correction 93 VIGCORR_RADIAL = 1, ///< radial vignetting correction 94 VIGCORR_FLATFIELD = 2, ///< flatfield correction 95 VIGCORR_DIV = 4 ///< correct by division. 96 }; 97 98 /// 99 enum ResponseType { 100 RESPONSE_EMOR=0, ///< empirical model of response 101 RESPONSE_LINEAR, ///< linear response 102 RESPONSE_GAMMA, ///< a simple gamma response curve 103 RESPONSE_FILE, ///< load response curve from file (not implemented yet) 104 RESPONSE_ICC ///< use ICC for transformation into linear data (not implemented yet) 105 }; 106 107 /// Check that the variables match. 108 bool operator==(const BaseSrcPanoImage & other) const; 109 110 111 public: 112 /// BaseSrcPanoImage()113 BaseSrcPanoImage() 114 {}; 115 ~BaseSrcPanoImage()116 virtual ~BaseSrcPanoImage() {}; 117 118 // property accessors 119 public: 120 // get[variable name] functions. Return the value stored in the ImageVariable. 121 #define image_variable( name, type, default_value ) \ 122 type get##name() const { return m_##name.getData(); } 123 #include "image_variables.h" 124 #undef image_variable 125 126 // get[variable name]IV functions. Return a const reference to the ImageVariable. 127 #define image_variable( name, type, default_value ) \ 128 const ImageVariable<type > & get##name##IV() const { return m_##name; } 129 #include "image_variables.h" 130 #undef image_variable 131 132 // set[variable name] functions 133 #define image_variable( name, type, default_value ) \ 134 void set##name(type data) { m_##name.setData(data); } 135 #include "image_variables.h" 136 #undef image_variable 137 138 /* The link[variable name] functions 139 * Pass a pointer to another SrcPanoImg and the respective image variable 140 * will be shared between the images. Afterwards, changing the variable with 141 * set[variable name] on either image also sets the other image. 142 */ 143 #define image_variable( name, type, default_value ) \ 144 void link##name (BaseSrcPanoImage * target) \ 145 { m_##name.linkWith(&(target->m_##name)); } 146 #include "image_variables.h" 147 #undef image_variable 148 149 /* The unlink[variable name] functions 150 * Unlinking a variable makes it unique to this image. Then changing it will 151 * not affect the other images. 152 */ 153 #define image_variable( name, type, default_value ) \ 154 void unlink##name () \ 155 { m_##name.removeLinks(); } 156 #include "image_variables.h" 157 #undef image_variable 158 159 /* The [variable name]isLinked functions 160 * Returns true if the variable has links, or false if it is independant. 161 */ 162 #define image_variable( name, type, default_value ) \ 163 bool name##isLinked () const \ 164 { return m_##name.isLinked(); } 165 #include "image_variables.h" 166 #undef image_variable 167 168 /* The [variable name]isLinkedWith functions 169 * Returns true if the variable is linked with the equivalent variable in 170 * the specified image, false otherwise. 171 */ 172 #define image_variable( name, type, default_value ) \ 173 bool name##isLinkedWith (const BaseSrcPanoImage & image) const \ 174 { return m_##name.isLinkedWith(&(image.m_##name)); } 175 #include "image_variables.h" 176 #undef image_variable 177 178 protected: 179 // the image variables m_[variable name] 180 #define image_variable( name, type, default_value ) \ 181 ImageVariable<type> m_##name {ImageVariable<type>(default_value)}; 182 #include "image_variables.h" 183 #undef image_variable 184 }; 185 186 187 /** All variables of a source image. 188 * 189 * In the long term, this simplified class will replace 190 * PanoImage and Image options and the variables array. 191 * All image variables are stored in this class, regardless of what the 192 * variable is attached to (lens, sensor, position). 193 */ 194 class IMPEX SrcPanoImage : public BaseSrcPanoImage 195 { 196 public: 197 /// SrcPanoImage()198 SrcPanoImage() :BaseSrcPanoImage() 199 {}; 200 SrcPanoImage(const BaseSrcPanoImage::Projection projection,const double hfov,const vigra::Size2D size)201 SrcPanoImage(const BaseSrcPanoImage::Projection projection, const double hfov, const vigra::Size2D size) :BaseSrcPanoImage() 202 { 203 setProjection(projection); 204 setHFOV(hfov); 205 setSize(size); 206 }; 207 ~SrcPanoImage()208 virtual ~SrcPanoImage() {}; 209 public: 210 /** "resize" image, 211 * adjusts all distortion coefficients for usage with a source image 212 * of size @p size 213 */ 214 void resize(const vigra::Size2D & size); 215 216 /** check if a coordinate is inside the source image 217 */ 218 bool isInside(vigra::Point2D p, bool ignoreMasks=false) const; 219 220 /// 221 bool horizontalWarpNeeded(); 222 223 // Accessors 224 // These are either: 225 // #- extra ones that are derived from image varibles, or 226 // #- replacements where we need extra processing. 227 public: 228 bool getCorrectTCA() const; 229 230 /** Set the crop mode. 231 * 232 * This sets the cropping region to the entire image when set to NO_CROP, 233 * unlike the lazy metaprogrammed equivalent in BaseSrcPanoImage. 234 */ 235 void setCropMode(CropMode val); 236 237 /** returns true, if projection requires cicular crop */ 238 bool isCircularCrop() const; 239 240 /** Set the image size in pixels 241 * 242 * If we aren't cropping the image, set the size to the entire image 243 */ 244 void setSize(vigra::Size2D val); 245 246 hugin_utils::FDiff2D getRadialDistortionCenter() const; 247 248 hugin_utils::FDiff2D getRadialVigCorrCenter() const; 249 250 // these are linked to ExposureValue, which is done with the above. 251 // exposure value is log2 of inverse exposure factor. 252 double getExposure() const; 253 void setExposure(const double & val); 254 255 256 /** Get the width of the image in pixels. 257 * 258 * Should not be used, use getSize().width() instead. 259 * This is here for compatiblity with PnaoImage, but should be removed. 260 * 261 * @todo replace all calls to getWidth() with getSize().width(). 262 */ getWidth()263 int getWidth() const 264 { return getSize().width(); } 265 266 /** Get the height of the image in pixels. 267 * 268 * Should not be used, use getSize().height() instead. 269 * This is here for compatiblity with PnaoImage, but should be removed. 270 * 271 * @todo replace all calls to getHeight() with getSize().height(). 272 */ getHeight()273 int getHeight() const 274 { return getSize().height(); } 275 276 double getVar(const std::string & name) const; 277 278 void setVar(const std::string & name, double val); 279 280 /** Return all the image variables in a variable map 281 * 282 * Returns a map of all the variables for this image. It is adivisable to 283 * use the individual getX functions where apropriate instead. 284 * 285 * @todo remove this infavour of the individual get*() functions. This 286 * creates a map of all the variables, regardless of which ones are actually 287 * needed, every time it is called. 288 */ 289 VariableMap getVariableMap() const; 290 291 /** try to convert Exif date time string to struct tm 292 * @return 0, if conversion was sucessfull */ 293 const int getExifDateTime(struct tm* datetime) const; 294 295 /** unlinking vignetting parameters should unlink the vignetting correction mode 296 */ unlinkRadialVigCorrCoeff()297 void unlinkRadialVigCorrCoeff () 298 { 299 m_RadialVigCorrCoeff.removeLinks(); 300 m_VigCorrMode.removeLinks(); 301 } 302 303 /** unlinking vignetting parameters should unlink the vignetting correction mode 304 */ unlinkRadialVigCorrCenterShift()305 void unlinkRadialVigCorrCenterShift () 306 { 307 m_RadialVigCorrCenterShift.removeLinks(); 308 m_VigCorrMode.removeLinks(); 309 } 310 311 /** unlinking the EMOR parameters should unlink the correction mode. 312 */ unlinkEMoRParams()313 void unlinkEMoRParams () 314 { 315 m_EMoRParams.removeLinks(); 316 m_ResponseType.removeLinks(); 317 } 318 319 /** linking vignetting parameters should link the vignetting correction mode 320 */ linkRadialVigCorrCoeff(SrcPanoImage * target)321 void linkRadialVigCorrCoeff (SrcPanoImage * target) 322 { 323 m_RadialVigCorrCoeff.linkWith(&(target->m_RadialVigCorrCoeff)); 324 m_VigCorrMode.linkWith(&(target->m_VigCorrMode)); 325 } 326 327 /** linking vignetting parameters should link the vignetting correction mode 328 */ linkRadialVigCorrCenterShift(SrcPanoImage * target)329 void linkRadialVigCorrCenterShift (SrcPanoImage * target) 330 { 331 m_RadialVigCorrCenterShift.linkWith(&(target->m_RadialVigCorrCenterShift)); 332 m_VigCorrMode.linkWith(&(target->m_VigCorrMode)); 333 } 334 335 /** linking the EMOR parameters should link the correction mode. 336 */ linkEMoRParams(SrcPanoImage * target)337 void linkEMoRParams (SrcPanoImage * target) 338 { 339 m_EMoRParams.linkWith(&(target->m_EMoRParams)); 340 m_ResponseType.linkWith(&(target->m_ResponseType)); 341 } 342 linkStack(SrcPanoImage * target)343 void linkStack (SrcPanoImage * target) 344 { m_Stack.linkWith(&(target->m_Stack)); } 345 346 /** check if the image size is known, if try to load the information from the file */ 347 bool checkImageSizeKnown(); 348 /** try to fill out information about the image, by examining the exif data 349 */ 350 bool readEXIF(); 351 /** apply values found in EXIF data to SrcPanoImage class, call readEXIF() before to initialize some values*/ 352 bool applyEXIFValues(bool applyEVValue=true); 353 354 /** calculate hfov of an image given focal length, image size and crop factor */ 355 static double calcHFOV(SrcPanoImage::Projection proj, double fl, double crop, vigra::Size2D imageSize); 356 357 /** calcualte focal length, given crop factor and hfov */ 358 static double calcFocalLength(SrcPanoImage::Projection proj, double hfov, double crop, vigra::Size2D imageSize); 359 360 /** calculate crop factor, given focal length and hfov */ 361 static double calcCropFactor(SrcPanoImage::Projection proj, double hfov, double focalLength, vigra::Size2D imageSize); 362 363 /** calculate exposure value */ 364 double calcExifExposureValue(); 365 366 /** updates the focal length, changes the hfov to reflect thew newFocalLength */ 367 void updateFocalLength(double newFocalLength); 368 /** updates the crop factor, the hfov is calculates so that focal length remains the same */ 369 void updateCropFactor(double focalLength, double newCropFactor); 370 371 /** tries to read cropfactor from lens database 372 you need to call SrcPanoImage::readEXIF before to fill some values 373 @return true, if information could be read from database */ 374 bool readCropfactorFromDB(); 375 /** tries to read projection and crop area from lens database 376 you need to call SrcPanoImage::readEXIF before to fill some values 377 @param ignoreFovRectilinear if this parameter is true, the fov of 378 rectilinear is not read from the database, otherwise the hfov 379 is populated with the value from the database 380 @return true, if information could be read from database */ 381 bool readProjectionFromDB(const bool ignoreFovRectilinear=true); 382 /** tries to read distortion data from lens database 383 you need to call SrcPanoImage::readEXIF before to fill some values 384 @return true, if information could be read from database */ 385 bool readDistortionFromDB(); 386 /** tries to read vignetting data from lens database 387 you need to call SrcPanoImage::readEXIF before to fill some values 388 @return true, if information could be read from database */ 389 bool readVignettingFromDB(); 390 /** constructs the lens name for the database 391 it is the lensname if known, for compact cameras it is constructed from camera maker and camera model */ 392 std::string getDBLensName() const; 393 394 /** returns true, if image has masks associated */ 395 bool hasMasks() const; 396 /** returns true, if image has positive masks */ 397 bool hasPositiveMasks() const; 398 /** returns true, if image has active masks */ 399 bool hasActiveMasks() const; 400 /** add newMask to list of masks */ 401 void addMask(MaskPolygon newMask); 402 /** add newMask to list of active masks */ 403 void addActiveMask(MaskPolygon newMask); 404 /** clears list of active masks */ 405 void clearActiveMasks(); 406 /** changes type of mask with index to given newType */ 407 void changeMaskType(unsigned int index, HuginBase::MaskPolygon::MaskType newType); 408 /** delete mask at index */ 409 void deleteMask(unsigned int index); 410 /** delete all masks */ 411 void deleteAllMasks(); 412 /** writes all mask lines to stream, using given image number */ 413 void printMaskLines(std::ostream &o, unsigned int newImgNr) const; 414 /** returns true, if point p is inside of one mask polygon */ 415 bool isInsideMasks(vigra::Point2D p) const; 416 417 private: 418 419 /** Check if Exiv orientation tag can be trusted */ 420 bool trustExivOrientation(); 421 }; 422 423 typedef std::vector<SrcPanoImage> ImageVector; 424 425 } // namespace 426 427 #endif // PANOIMAGE_H 428