37 #include <jsk_topic_tools/log_utils.h> 
   39 #include <sensor_msgs/Image.h> 
   43 #include <boost/assign.hpp> 
   51     DiagnosticNodelet::onInit();
 
   59     srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
 
   60     dynamic_reconfigure::Server<Config>::CallbackType 
f =
 
   62     srv_->setCallback (
f);
 
   94     jsk_topic_tools::warnNoRemap(names);
 
  106     int l = distorted.rows / 2;
 
  109       float min_degree = 30;
 
  110       float min_radian = min_degree * 3.14159265 /180.0;
 
  111       float tan_min_radian = tan(min_radian);
 
  112       const float K = 341.656050955;
 
  114         cv::Mat undistorted(
l, 
l*4, CV_8UC3);
 
  115         cv::Mat undistorted_bilinear(
l, 
l*4, CV_8UC3);
 
  116         for(
int i = 0; 
i < undistorted.rows; ++
i){
 
  117           for(
int j = 0; j < undistorted.cols; ++j){
 
  120             double theta = 2.0 * 
PI * (double)(-j) / (double)(4.0 * 
l);
 
  124             int x = (
int)round(fTrueX) + 
l;
 
  125             int y = 
l - (
int)round(fTrueY);
 
  126             if (
x >= 0 && 
x < (2 * 
l) && y >= 0 && y < (2 * 
l))
 
  128                 for(
int c = 0; c < undistorted.channels(); ++c)
 
  129                   undistorted.data[ 
i * undistorted.step + j * undistorted.elemSize() + c ]
 
  130                     = distorted.data[
x * distorted.step + y * distorted.elemSize() + c];
 
  133             fTrueX = fTrueX + (double)
l;
 
  134             fTrueY = (double)
l - fTrueY;
 
  136             int iFloorX = (
int)floor(fTrueX);
 
  137             int iFloorY = (
int)floor(fTrueY);
 
  138             int iCeilingX = (
int)ceil(fTrueX);
 
  139             int iCeilingY = (
int)ceil(fTrueY);
 
  141             if (iFloorX < 0 || iCeilingX < 0 ||
 
  142                 iFloorX >= (2 * 
l) || iCeilingX >= (2 * 
l) ||
 
  143                 iFloorY < 0 || iCeilingY < 0 ||
 
  144                 iFloorY >= (2 * 
l) || iCeilingY >= (2 * 
l)) 
continue;
 
  146             double fDeltaX = fTrueX - (double)iFloorX;
 
  147             double fDeltaY = fTrueY - (double)iFloorY;
 
  149             cv::Mat clrTopLeft(1,1, CV_8UC3), clrTopRight(1,1, CV_8UC3), clrBottomLeft(1,1, CV_8UC3), clrBottomRight(1,1, CV_8UC3);
 
  150             for(
int c = 0; c < undistorted.channels(); ++c){
 
  151               clrTopLeft.data[ c ] = distorted.data[iFloorX * distorted.step + iFloorY * distorted.elemSize() + c];
 
  152               clrTopRight.data[ c ] = distorted.data[iCeilingX * distorted.step + iFloorY * distorted.elemSize() + c];
 
  153               clrBottomLeft.data[ c ] = distorted.data[iFloorX * distorted.step + iCeilingY * distorted.elemSize() + c];
 
  154               clrBottomRight.data[ c ] = distorted.data[iCeilingX * distorted.step + iCeilingY * distorted.elemSize() + c];
 
  157             double fTop0 = 
interpolate(fDeltaX, clrTopLeft.data[0], clrTopRight.data[0]);
 
  158             double fTop1 = 
interpolate(fDeltaX, clrTopLeft.data[1], clrTopRight.data[1]);
 
  159             double fTop2 = 
interpolate(fDeltaX, clrTopLeft.data[2], clrTopRight.data[2]);
 
  160             double fBottom0 = 
interpolate(fDeltaX, clrBottomLeft.data[0], clrBottomRight.data[0]);
 
  161             double fBottom1 = 
interpolate(fDeltaX, clrBottomLeft.data[1], clrBottomRight.data[1]);
 
  162             double fBottom2 = 
interpolate(fDeltaX, clrBottomLeft.data[2], clrBottomRight.data[2]);
 
  168             i0 = std::min(255, std::max(i0, 0));
 
  169             i1 = std::min(255, std::max(i1, 0));
 
  170             i2 = std::min(255, std::max(i2, 0));
 
  172             undistorted_bilinear.data[ 
i * undistorted_bilinear.step + j * undistorted_bilinear.elemSize() + 0] = i0;
 
  173             undistorted_bilinear.data[ 
i * undistorted_bilinear.step + j * undistorted_bilinear.elemSize() + 1] = i1;
 
  174             undistorted_bilinear.data[ 
i * undistorted_bilinear.step + j * undistorted_bilinear.elemSize() + 2] = i2;
 
  188         cv::Mat undistorted(
int(
l * 1.0 / tan_min_radian*
scale_), 
int(
l *  2.0 * 
PI * 
scale_), CV_8UC3);
 
  189         int center_x = distorted.rows/2, center_y = distorted.cols/2;
 
  192         for(
int i = 0; 
i < undistorted.rows; ++
i){
 
  193           for(
int j = 0; j < undistorted.cols; ++j){
 
  196               phi = atan(
l * 1.0 /
i*
scale_) + 0.5;
 
  197             float theta = (j-
int(undistorted.cols/2))/
scale_ * 1.0/
l;
 
  198             int x = K * phi * 
cos(theta) + center_x;
 
  199             int y = K * phi * 
sin(theta) + center_y;
 
  200             for(
int c = 0; c < undistorted.channels(); ++c){
 
  201               int index = undistorted.rows - 1 - 
i;
 
  204               int jndex = j + offset_jndex;
 
  205               if(jndex > undistorted.cols - 1)
 
  206                 jndex -= undistorted.cols - 1;
 
  207               undistorted.data[ 
index  * undistorted.step + jndex * undistorted.elemSize() + c ]
 
  208                 = distorted.data[ 
x * distorted.step + y * distorted.elemSize() + c];
 
  220       float max_radian = max_degree * 3.14159265 /180.0;
 
  221       float tan_max_radian = tan(max_radian);
 
  222       const float K = 341.656050955;
 
  223       const float absolute_max_degree = 85;
 
  224       const float absolute_max_radian = absolute_max_degree * 3.14159265 /180.0;
 
  225       float max_radius = max_radian * K;
 
  226       cv::Mat undistorted(
int(
l * tan_max_radian * 2 * 
scale_), 
int(
l * tan_max_radian * 2 * 
scale_), CV_8UC3);
 
  227       int center_x = distorted.rows/2, center_y = distorted.cols/2;
 
  228       int un_center_x = undistorted.rows/(2 * 
scale_), un_center_y = undistorted.cols/(2*
scale_);
 
  230       for(
int i = 0; 
i < undistorted.rows; ++
i){
 
  231         for(
int j = 0; j < undistorted.cols; ++j){
 
  232           int diff_x = 
i/
scale_-un_center_x, diff_y = j/
scale_-un_center_y;
 
  233           float radius = 
sqrt(pow(diff_x, 2) + pow(diff_y, 2));
 
  235           if( radian < absolute_max_radian ){
 
  236             float multi = 0, new_x = center_x, new_y = center_y;
 
  239               multi = radian * K / 
radius;
 
  240               new_x += diff_x * multi;
 
  241               new_y += diff_y * multi;
 
  244             for(
int c = 0; c < undistorted.channels(); ++c){
 
  245               undistorted.data[  
i * undistorted.step + j * undistorted.elemSize() + c ]
 
  246                 = distorted.data[ 
int(new_x) * distorted.step + 
int(new_y) * distorted.elemSize() + c];