rectification.cpp
Go to the documentation of this file.
00001 #include "rectification.hpp"
00002 
00003 
00004 #include <inttypes.h>
00005 
00006 #include <iostream>
00007 
00008 namespace fovis
00009 {
00010 
00011 Rectification::Rectification(const CameraIntrinsicsParameters& params) :
00012   _map_x(NULL),
00013   _map_y(NULL)
00014 {
00015   _input_camera = params;
00016   _rotation = new Eigen::Matrix3d(Eigen::Matrix3d::Identity());
00017   _rectified_camera = params;
00018   _rectified_camera.k1 = 0;
00019   _rectified_camera.k2 = 0;
00020   _rectified_camera.k3 = 0;
00021   _rectified_camera.p1 = 0;
00022   _rectified_camera.p2 = 0;
00023   populateMap();
00024 }
00025 
00026 Rectification::Rectification(const CameraIntrinsicsParameters& input_camera_params,
00027         const Eigen::Matrix3d& rotation,
00028         const CameraIntrinsicsParameters& rectified_camera_params) :
00029   _map_x(NULL),
00030   _map_y(NULL)
00031 {
00032   _input_camera = input_camera_params;
00033   _rotation = new Eigen::Matrix3d(rotation);
00034   _rectified_camera = rectified_camera_params;
00035   populateMap();
00036 }
00037 
00038 void
00039 Rectification::populateMap()
00040 {
00041   assert(_input_camera.width > 0 && _input_camera.height > 0);
00042   delete[] _map_x;
00043   delete[] _map_y;
00044   _map_x = new float[_input_camera.width * _input_camera.height];
00045   _map_y = new float[_input_camera.width * _input_camera.height];
00046 
00047   int input_width = _input_camera.width;
00048   int input_height = _input_camera.height;
00049   double fx  = _input_camera.fx;
00050   double fy  = _input_camera.fy;
00051   double cx  = _input_camera.cx;
00052   double cy  = _input_camera.cy;
00053   double fxp = _rectified_camera.fx;
00054   double fyp = _rectified_camera.fy;
00055   double cxp = _rectified_camera.cx;
00056   double cyp = _rectified_camera.cy;
00057   double k1  = _input_camera.k1;
00058   double k2  = _input_camera.k2;
00059   double k3  = _input_camera.k3;
00060   double p1  = _input_camera.p1;
00061   double p2  = _input_camera.p2;
00062 
00063   // this code is based on OpenCV cvUndistortPoints
00064   for (int y = 0; y < input_height; ++y) {
00065     for (int x = 0; x < input_width; ++x) {
00066       // normalize according to principal point and focal length
00067       double x1 = (x - cx)/fx;
00068       double y1 = (y - cy)/fy;
00069       double x0 = x1;
00070       double y0 = y1;
00071       // Iteratively undistort point
00072       for(int j = 0; j < 5; ++j) {
00073         double r2 = x1*x1 + y1*y1;
00074         double icdist = 1./(1. + ((k3*r2 + k2)*r2 + k1)*r2);
00075         double deltaX = 2*p1*x1*y1 + p2*(r2 + 2*x1*x1);
00076         double deltaY = p1*(r2 + 2*y1*y1) + 2*p2*x1*y1;
00077         x1 = (x0 - deltaX)*icdist;
00078         y1 = (y0 - deltaY)*icdist;
00079       }
00080       // rectification
00081       Eigen::Vector3d xyw = (*_rotation) * Eigen::Vector3d(x1,  y1, 1);
00082       x1 = xyw(0) / xyw(2);
00083       y1 = xyw(1) / xyw(2);
00084       // projection for rectified rectified image
00085       x1 = x1 * fxp + cxp;
00086       y1 = y1 * fyp + cyp;
00087       _map_x[y * input_width + x] = x1;
00088       _map_y[y * input_width + x] = y1;
00089     }
00090   }
00091 }
00092 
00093 Rectification::~Rectification()
00094 {
00095   delete[] _map_x;
00096   delete[] _map_y;
00097   delete _rotation;
00098   _map_x = NULL;
00099   _map_y = NULL;
00100 }
00101 
00102 Rectification*
00103 Rectification::makeCopy() const
00104 {
00105   Rectification* result = new Rectification();
00106   result->_input_camera = _input_camera;
00107   result->_rotation = new Eigen::Matrix3d(*_rotation);
00108   result->_rectified_camera = _rectified_camera;
00109   int num_elem = _input_camera.width * _input_camera.height;
00110   result->_map_x = new float[num_elem];
00111   result->_map_y = new float[num_elem];
00112   std::copy(_map_x, _map_x+num_elem, result->_map_x);
00113   std::copy(_map_y, _map_y+num_elem, result->_map_y);
00114   return result;
00115 }
00116 
00117 #if 0
00118 // just a quick function for debugging, not for serious use
00119 void fwd_map(int width, int height, const float * mapx, const float * mapy, uint8_t *img,
00120              uint8_t *img_out);
00121 void
00122 fwd_map(int width, int height, const float * mapx, const float * mapy,
00123         uint8_t *img, uint8_t *img_out) {
00124   for (int i=0; i < height; ++i) {
00125     for (int j=0; j < width; ++j) {
00126       int new_x = (int)mapx[width*i + j];
00127       int new_y = (int)mapy[width*i + j];
00128       if (new_x < 0 || new_x >= width) continue;
00129       if (new_y < 0 || new_y >= height) continue;
00130       img_out[width*new_y + new_x] = img[width*i + j];
00131     }
00132   }
00133 }
00134 #endif
00135 
00136 } /*  */


libfovis
Author(s): Albert Huang, Maurice Fallon
autogenerated on Thu Jun 6 2019 20:16:12