PICCANTE  0.4
The hottest HDR imaging library!
rectification.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_COMPUTER_VISION_RECTIFICATION_HPP
19 #define PIC_COMPUTER_VISION_RECTIFICATION_HPP
20 
21 #include <vector>
22 #include <cmath>
23 #include <stdlib.h>
24 
25 #include "../base.hpp"
26 
27 #include "../image.hpp"
28 
29 #include "../image_vec.hpp"
30 
31 #include "../filtering/filter_warp_2d.hpp"
32 #include "../filtering/filter_rotation.hpp"
33 
34 #include "../computer_vision/camera_matrix.hpp"
35 
36 #include "../util/eigen_util.hpp"
37 
38 #ifndef PIC_DISABLE_EIGEN
39 
40 #ifndef PIC_EIGEN_NOT_BUNDLED
41  #include "../externals/Eigen/Dense"
42  #include "../externals/Eigen/SVD"
43  #include "../externals/Eigen/Geometry"
44 #else
45  #include <Eigen/Dense>
46  #include <Eigen/SVD>
47  #include <Eigen/Geometry>
48 #endif
49 
50 #endif
51 
52 namespace pic {
53 
54 #ifndef PIC_DISABLE_EIGEN
55 
66  Image *img1,
67  Eigen::Matrix3d &T0,
68  Eigen::Matrix3d &T1,
69  ImageVec *out,
70  bool bPartial = true)
71 {
72  if(img0 == NULL || img1 == NULL) {
73  return out;
74  }
75 
76  if(out == NULL) {
77  out = new ImageVec();
78  }
79 
80  auto H0 = MatrixConvert(T0);
81  auto H1 = MatrixConvert(T1);
82  FilterWarp2D warp0(H0);
83  FilterWarp2D warp1(H1);
84 
85  int bmin0[2], bmin1[2], bmax0[2], bmax1[2];
86 
87  FilterWarp2D::computeBoundingBox(H0, warp0.getBCentroid(), img0->widthf, img0->heightf, bmin0, bmax0);
88  FilterWarp2D::computeBoundingBox(H1, warp1.getBCentroid(), img1->widthf, img1->heightf, bmin1, bmax1);
89 
90  if(bPartial) {
91  bmin0[1] = MIN(bmin0[1], bmin1[1]);
92  bmax0[1] = MAX(bmax0[1], bmax1[1]);
93 
94  bmin1[1] = bmin0[1];
95  bmax1[1] = bmax0[1];
96  } else {
97  for(int i = 0; i < 2; i++) {
98  bmin0[i] = MIN(bmin0[i], bmin1[i]);
99  bmin1[i] = bmin0[i];
100 
101  bmax0[i] = MAX(bmax0[i], bmax1[i]);
102  bmax1[i] = bmax0[i];
103  }
104  }
105 
106  warp0.setBoundingBox(bmin0, bmax0);
107  warp1.setBoundingBox(bmin1, bmax1);
108 
109  Image *img0_r = NULL;
110  Image *img1_r = NULL;
111 
112  bool bTest = out->size() == 2;
113  if(bTest) {
114  img0_r = out->at(0);
115  img1_r = out->at(1);
116  }
117 
118  img0_r = warp0.Process(Single(img0), img0_r);
119  img1_r = warp1.Process(Single(img1), img1_r);
120 
121  if(!bTest) {
122  out->push_back(img0_r);
123  out->push_back(img1_r);
124  }
125 
126  return out;
127 }
128 
140  Image *img1,
141  Eigen::Matrix34d &M0,
142  Eigen::Matrix34d &M1,
143  ImageVec *out = NULL,
144  bool bPartial = true)
145 {
146  //NOTE: we should check that img0 and img1 are valid...
147  if(img0 == NULL || img1 == NULL) {
148  return out;
149  }
150 
151  if(out == NULL) {
152  out = new ImageVec();
153  }
154 
155  Eigen::Matrix34d M0_r, M1_r;
156  Eigen::Matrix3d T0, T1;
157 
158  cameraRectify(M0, M1, M0_r, M1_r, T0, T1);
159 
160  //check if the trasform is correct!
161  Eigen::Vector3d corners[4], corners_T0[4];
162  corners[0] = Eigen::Vector3d(0.0, 0.0, 1.0);
163  corners[1] = Eigen::Vector3d(img0->widthf, 0.0, 1.0);
164  corners[2] = Eigen::Vector3d(img0->widthf, img0->heightf, 1.0);
165  corners[3] = Eigen::Vector3d(img0->heightf, 0.0, 1.0);
166 
167  for(int i = 0; i < 4; i ++) {
168  corners_T0[i] = T0 * corners[i];
169  corners_T0[i] /= corners_T0[i][2];
170  }
171 
172  auto d_c = corners[2] - corners[0];
173  auto d_c_T0 = corners_T0[2] - corners_T0[0];
174 
175  bool b_x = std::signbit(d_c[0]) == std::signbit(d_c_T0[0]);
176  bool b_y = std::signbit(d_c[1]) == std::signbit(d_c_T0[1]);
177 
178  double f_x = b_x ? 1.0 : -1.0;
179  double f_y = b_y ? 1.0 : -1.0;
180 
181 
182  auto H = DiagonalMatrix(Eigen::Vector3d(f_x, f_y, 1));
183  T0 = H * T0;
184  T1 = H * T1;
185 
186  out = computeImageRectificationWarp(img0, img1, T0, T1, out, bPartial);
187 
188  return out;
189 }
190 
205  Image *img1,
206  Eigen::Matrix3d &K0,
207  Eigen::Matrix3d &R0,
208  Eigen::Vector3d &t0,
209  Eigen::Matrix3d &K1,
210  Eigen::Matrix3d &R1,
211  Eigen::Vector3d &t1,
212  ImageVec *out = NULL,
213  bool bPartial = true)
214 {
215  //NOTE: we should check that img0 and img1 are valid...
216  if(img0 == NULL || img1 == NULL) {
217  return out;
218  }
219 
220  if(out == NULL) {
221  out = new ImageVec();
222  }
223 
224  Eigen::Matrix34d M0_r, M1_r;
225  Eigen::Matrix3d T0, T1;
226 
227  cameraRectify(K0, R0, t0, K1, R1, t1, M0_r, M1_r, T0, T1);
228 
229  out = computeImageRectificationWarp(img0, img1, T0, T1, out, bPartial);
230 
231  return out;
232 }
233 
243 PIC_INLINE void alignPanoramicLL(Eigen::Matrix3d &R0, Eigen::Vector3d &t0,
244  Eigen::Matrix3d &R1, Eigen::Vector3d &t1,
245  Eigen::Matrix3d &R01, Eigen::Vector3d &t01)
246 {
247  t01 = t1 - t0;
248  Eigen::Matrix3d R0_t = Eigen::Transpose< Eigen::Matrix3d >(R0);
249 
250  //R0 --> I
251  //t0 --> 0
252 
253  R01 = R0_t * R1;
254  t01 = R0_t * t01;
255 }
256 
267  Image *img0,
268  Image *img1,
269  Eigen::Matrix3d &R01,
270  Eigen::Vector3d &t01,
271  ImageVec *out = NULL)
272 {
273  //NOTE: we should check that img0 and img1 are valid...
274  if(img0 == NULL || img1 == NULL) {
275  return out;
276  }
277 
278  if(out == NULL) {
279  out = new ImageVec();
280  }
281 
282  //rotation 1
283  Eigen::Matrix3d R01_t = Eigen::Transpose< Eigen::Matrix3d >(R01);
284 
285  //rotation 2
286  Eigen::Vector3d X(0.0, 1.0, 0.0);
287  Eigen::Vector3d n;
288  n = t01.cross(X);
289  n.normalize();
290 
291  double alpha = std::acos(t01.dot(X));
292  Eigen::Matrix3d rot, rotation1;
293 
294  rot = Eigen::AngleAxisd(alpha, n);
295  rotation1 = rot * R01_t;
296 
297  Eigen::Matrix3f rotation0f, rotation1f;
298  rotation0f = rot.cast<float>();
299  rotation1f = rotation1.cast<float>();
300 
301  out->push_back(FilterRotation::execute(img0, NULL, rotation0f));
302  out->push_back(FilterRotation::execute(img1, NULL, rotation1f));
303  return out;
304 }
305 
306 #endif // PIC_DISABLE_EIGEN
307 
308 } // end namespace pic
309 
310 #endif // PIC_COMPUTER_VISION_RECTIFICATION_HPP
int size() const
size computes the number of values.
Definition: image.hpp:481
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
bool getBCentroid()
getBCentroid
Definition: filter_warp_2d.hpp:108
PIC_INLINE ImageVec * computeImageRectification(Image *img0, Image *img1, Eigen::Matrix34d &M0, Eigen::Matrix34d &M1, ImageVec *out=NULL, bool bPartial=true)
computeImageRectification this function rectifies two images
Definition: rectification.hpp:139
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
PIC_INLINE ImageVec * computeImageRectificationWarp(Image *img0, Image *img1, Eigen::Matrix3d &T0, Eigen::Matrix3d &T1, ImageVec *out, bool bPartial=true)
computeImageRectificationWarp
Definition: rectification.hpp:65
float heightf
Definition: image.hpp:84
PIC_INLINE Matrix3x3 MatrixConvert(Eigen::Matrix3f &mat)
MatrixConvert converts a matrix from a Eigen::Matrix3f representation into a Matrix3x3 representation...
Definition: eigen_util.hpp:356
#define PIC_INLINE
Definition: base.hpp:33
float widthf
Definition: image.hpp:84
#define MIN(a, b)
Definition: math.hpp:69
The Image class stores an image as buffer of float.
Definition: image.hpp:60
void setBoundingBox(int *bmin, int *bmax)
setBoundingBox
Definition: filter_warp_2d.hpp:186
PIC_INLINE Eigen::Matrix3d DiagonalMatrix(Eigen::Vector3d D)
DiagonalMatrix creates a diagonal matrix.
Definition: eigen_util.hpp:113
PIC_INLINE void cameraRectify(Eigen::Matrix3d &K0, Eigen::Matrix3d &R0, Eigen::Vector3d &t0, Eigen::Matrix3d &K1, Eigen::Matrix3d &R1, Eigen::Vector3d &t1, Eigen::Matrix34d &P0_out, Eigen::Matrix34d &P1_out, Eigen::Matrix3d &T0, Eigen::Matrix3d &T1)
cameraRectify
Definition: camera_matrix.hpp:294
PIC_INLINE ImageVec * computeImageRectificationPanoramicLL(Image *img0, Image *img1, Eigen::Matrix3d &R01, Eigen::Vector3d &t01, ImageVec *out=NULL)
computeImageRectificationPanoramicLL
Definition: rectification.hpp:266
PIC_INLINE ImageVec Single(Image *img)
Single creates an std::vector which contains img; this is for filters input.
Definition: image_vec.hpp:36
Definition: bilateral_separation.hpp:25
#define MAX(a, b)
Definition: math.hpp:73
static void computeBoundingBox(Matrix3x3 &h, bool bCentroid, float width, float height, int *bmin, int *bmax)
computeBoundingBox
Definition: filter_warp_2d.hpp:122
PIC_INLINE void alignPanoramicLL(Eigen::Matrix3d &R0, Eigen::Vector3d &t0, Eigen::Matrix3d &R1, Eigen::Vector3d &t1, Eigen::Matrix3d &R01, Eigen::Vector3d &t01)
alignPanoramicLL
Definition: rectification.hpp:243
static Image * execute(Image *imgIn, Image *imgOut, float angleX, float angleY, float angleZ)
execute
Definition: filter_rotation.hpp:194
The FilterWarp2D class.
Definition: filter_warp_2d.hpp:31