Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StraightenPanorama.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
26 #include "StraightenPanorama.h"
27 
28 #include <hugin_math/eig_jacobi.h>
29 
30 namespace HuginBase {
31 
33 {
34  // landscape/non rotated portrait detection is not working correctly
35  // should use the exif rotation tag but thats not stored anywhere currently...
36  // 1: use y axis (image x axis), for normal image
37  // 0: use z axis (image y axis), for non rotated portrait images
38  // (usually rotation is just stored in EXIF tag)
39  std::vector<int> coord_idx;
40 
41  for (unsigned int i = 0; i < panorama.getNrOfImages(); i++) {
42  SrcPanoImage img = panorama.getSrcImage(i);
43  if (img.getExifMake().empty() || img.getExifModel().empty())
44  {
45  img.readEXIF();
46  };
47  double roll = img.getExifOrientation();
48  if (roll == 90 || roll == 270 ) {
49  coord_idx.push_back(2);
50  } else {
51  coord_idx.push_back(1);
52  }
53  }
54 
55  // build covariance matrix of X
56  Matrix3 cov;
57  unsigned int nrOfVariableImages=0;
58 
59  for (unsigned int i = 0; i < panorama.getNrOfImages(); i++)
60  {
61  const SrcPanoImage & img=panorama.getImage(i);
62  if(img.YawisLinked())
63  {
64  //only consider images which are not linked with the previous ones
65  bool consider=true;
66  for(unsigned int j=0; j<i; j++)
67  {
68  if(img.YawisLinkedWith(panorama.getImage(j)))
69  {
70  consider=false;
71  break;
72  };
73  };
74  if(!consider)
75  continue;
76  };
77  double y = const_map_get(panorama.getImageVariables(i), "y").getValue();
78  double p = const_map_get(panorama.getImageVariables(i), "p").getValue();
79  double r = const_map_get(panorama.getImageVariables(i), "r").getValue();
80  Matrix3 mat;
82  nrOfVariableImages++;
83  DEBUG_DEBUG("mat = " << mat);
84  for (int j=0; j<3; j++) {
85  for (int k=0; k<3; k++) {
86  cov.m[j][k] += mat.m[j][coord_idx[i]] * mat.m[k][coord_idx[i]];
87  }
88  }
89  }
90  cov /= nrOfVariableImages;
91  DEBUG_DEBUG("cov = " << cov);
92 
93  // calculate eigenvalues and vectors
94  Matrix3 eigvectors;
95  double eigval[3];
96  int eigvalIdx[3];
97  int maxsweep = 100;
98  int maxannil = 0;
99  double eps = 1e-16;
100 
101  hugin_utils::eig_jacobi(3, cov.m, eigvectors.m, eigval, eigvalIdx, &maxsweep, &maxannil, &eps);
102 
103  DEBUG_DEBUG("Eigenvectors & eigenvalues:" << std::endl
104  << "V = " << eigvectors << std::endl
105  << "D = [" << eigval[0] << ", " << eigval[1] << ", " << eigval[2] << " ]"
106  << "idx = [" << eigvalIdx[0] << ", " << eigvalIdx[1] << ", " << eigvalIdx[2] << " ]");
107 
108  // get up vector, eigenvector with smallest eigenvalue
109  Vector3 up;
110  up.x = eigvectors.m[eigvalIdx[2]][0];
111  up.y = eigvectors.m[eigvalIdx[2]][1];
112  up.z = eigvectors.m[eigvalIdx[2]][2];
113 
114  // normalize vector
115  up.Normalize();
116  DEBUG_DEBUG("Up vector: up = " << up );
117 
118  double rotAngle = acos(up.Dot(Vector3(0,0,1)));
119  if (rotAngle > M_PI/2) {
120  // turn in shorter direction
121  up *= -1;
122  rotAngle = acos(up.Dot(Vector3(0,0,1)));
123  }
124  DEBUG_DEBUG("rotation Angle: " << rotAngle);
125 
126  // get rotation axis
127  Vector3 rotAxis = up.Cross(Vector3(0,0,1));
128  DEBUG_DEBUG("rotAxis = " << rotAngle);
129 
130  // calculate rotation matrix
131  Matrix3 rotMat = GetRotationAroundU(rotAxis, -rotAngle);
132  DEBUG_DEBUG("rotMat = " << rotMat);
133 
134  return rotMat;
135 }
136 
137 } // namespace
double Dot(const Vector3 &v) const
dot product
Definition: Vector3.h:169
double y
Definition: Vector3.h:47
double m[3][3]
we define the Matrix3 as 3 colums of 3 rows
Definition: Matrix3.h:41
virtual const VariableMap getImageVariables(unsigned int imgNr) const =0
get variables of an image
general : Matrix3 is a class for handling 3x3 Matrix manipulation.
Definition: Matrix3.h:37
const Map::mapped_type & const_map_get(const Map &m, const typename Map::key_type &key)
Definition: stl_utils.h:110
void SetRotationPT(double yaw, double pitch, double roll)
set rotation in panotools style, code adapted from Panotools-Script by Bruno Postle ...
Definition: Matrix3.cpp:110
bool Normalize()
Normalize.
Definition: Vector3.cpp:80
Matrix3 GetRotationAroundU(const Vector3 &U, double Angle)
return the rotation matrix around vector U : checked
Definition: Matrix3.h:161
static Matrix3 calcStraighteningRotation(const PanoramaData &panorama)
Model for a panorama.
Definition: PanoramaData.h:81
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
Vector3 Cross(const Vector3 &v) const
cross product
Definition: Vector3.h:163
double z
Definition: Vector3.h:47
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
bool readEXIF()
try to fill out information about the image, by examining the exif data
lu decomposition and linear LMS solver
#define DEG_TO_RAD(x)
Definition: hugin_math.h:44
general : Vector3 is a class for handling 3D Vectors manipulation.
Definition: Vector3.h:43
virtual SrcPanoImage getSrcImage(unsigned imgNr) const =0
get a complete description of a source image
double x
x,y,z coordinates, 0 at the initialisation
Definition: Vector3.h:47
virtual std::size_t getNrOfImages() const =0
number of images.
All variables of a source image.
Definition: SrcPanoImage.h:194
#define M_PI
Definition: GaborFilter.cpp:34
void eig_jacobi(int n, double a[3][3], double v[3][3], double *d, int *ind, int *maxsweep, int *maxannil, double *epsilon)
Implements jacobi eigenvalue/vector algorithm on a symmetric matrix stored as a 2 dimensional matrix ...
Definition: eig_jacobi.cpp:68