conversion.cpp
Go to the documentation of this file.
00001 #include <cstring>
00002 #include <stdexcept>
00003 
00004 #include <boost/format.hpp>
00005 
00006 #include <LinearMath/btMatrix3x3.h>
00007 #include <LinearMath/btQuaternion.h>
00008 #include <tf/transform_datatypes.h>
00009 
00010 #include <sensor_msgs/Image.h>
00011 #include <sensor_msgs/image_encodings.h>
00012 #include <sensor_msgs/distortion_models.h>
00013 
00014 #include <visp/vpImage.h>
00015 
00016 #define protected public
00017 # include <visp/vpMbEdgeTracker.h>
00018 #undef protected
00019 
00020 #define protected public
00021 # include <visp/vpMbKltTracker.h>
00022 #undef protected
00023 
00024 #include "conversion.hh"
00025 
00026 void rosImageToVisp(vpImage<unsigned char>& dst,
00027                     const sensor_msgs::Image::ConstPtr& src)
00028 {
00029   using sensor_msgs::image_encodings::RGB8;
00030   using sensor_msgs::image_encodings::RGBA8;
00031   using sensor_msgs::image_encodings::BGR8;
00032   using sensor_msgs::image_encodings::BGRA8;
00033   using sensor_msgs::image_encodings::MONO8;
00034   using sensor_msgs::image_encodings::MONO16;
00035   using sensor_msgs::image_encodings::numChannels;
00036 
00037   // Resize the image if necessary.
00038   if (src->width != dst.getWidth() || src->height != dst.getHeight())
00039     {
00040       ROS_INFO
00041         ("dst is %dx%d but src size is %dx%d, resizing.",
00042          src->width, src->height,
00043          dst.getWidth (), dst.getHeight ());
00044       dst.resize (src->height, src->width);
00045     }
00046 
00047   if(src->encoding == MONO8)
00048     memcpy(dst.bitmap,
00049            &src->data[0],
00050            dst.getHeight () * src->step * sizeof(unsigned char));
00051   else if(src->encoding == RGB8 || src->encoding == RGBA8
00052           || src->encoding == BGR8 || src->encoding == BGRA8)
00053     {
00054       unsigned nc = numChannels(src->encoding);
00055       unsigned cEnd =
00056         (src->encoding == RGBA8 || src->encoding == BGRA8) ? nc - 1 : nc;
00057 
00058       for(unsigned i = 0; i < dst.getWidth (); ++i)
00059         for(unsigned j = 0; j < dst.getHeight (); ++j)
00060           {
00061             int acc = 0;
00062             for(unsigned c = 0; c < cEnd; ++c)
00063               acc += src->data[j * src->step + i * nc + c];
00064             dst[j][i] =  acc / nc;
00065           }
00066     }
00067   else
00068     {
00069       boost::format fmt("bad encoding '%1'");
00070       fmt % src->encoding;
00071       throw std::runtime_error(fmt.str());
00072     }
00073 }
00074 
00075 void vispImageToRos(sensor_msgs::Image& dst,
00076                     const vpImage<unsigned char>& src)
00077 {
00078   dst.width = src.getWidth();
00079   dst.height = src.getHeight();
00080   dst.encoding = sensor_msgs::image_encodings::MONO8;
00081   dst.step = src.getWidth();
00082   dst.data.resize(dst.height * dst.step);
00083   for(unsigned i = 0; i < src.getWidth (); ++i)
00084     for(unsigned j = 0; j < src.getHeight (); ++j)
00085       dst.data[j * dst.step + i] = src[j][i];
00086 }
00087 
00088 void vpHomogeneousMatrixToTransform(geometry_msgs::Transform& dst,
00089                                     const vpHomogeneousMatrix& src)
00090 {
00091   btMatrix3x3 rotation;
00092   btQuaternion quaternion;
00093   for(unsigned i = 0; i < 3; ++i)
00094     for(unsigned j = 0; j < 3; ++j)
00095       rotation[i][j] = src[i][j];
00096   rotation.getRotation(quaternion);
00097 
00098   dst.translation.x = src[0][3];
00099   dst.translation.y = src[1][3];
00100   dst.translation.z = src[2][3];
00101 
00102   dst.rotation.x = quaternion.x();
00103   dst.rotation.y = quaternion.y();
00104   dst.rotation.z = quaternion.z();
00105   dst.rotation.w = quaternion.w();
00106 }
00107 
00108 void transformToVpHomogeneousMatrix(vpHomogeneousMatrix& dst,
00109                                     const geometry_msgs::Transform& src)
00110 {
00111   btQuaternion quaternion
00112     (src.rotation.x, src.rotation.y, src.rotation.z, src.rotation.w);
00113   btMatrix3x3 rotation(quaternion);
00114 
00115   // Copy the rotation component.
00116   for(unsigned i = 0; i < 3; ++i)
00117     for(unsigned j = 0; j < 3; ++j)
00118       dst[i][j] = rotation[i][j];
00119 
00120   // Copy the translation component.
00121   dst[0][3] = src.translation.x;
00122   dst[1][3] = src.translation.y;
00123   dst[2][3] = src.translation.z;
00124 }
00125 
00126 void transformToVpHomogeneousMatrix(vpHomogeneousMatrix& dst,
00127                                     const geometry_msgs::Pose& src)
00128 {
00129   btQuaternion quaternion
00130     (src.orientation.x, src.orientation.y, src.orientation.z,
00131      src.orientation.w);
00132   btMatrix3x3 rotation(quaternion);
00133 
00134   // Copy the rotation component.
00135   for(unsigned i = 0; i < 3; ++i)
00136     for(unsigned j = 0; j < 3; ++j)
00137       dst[i][j] = rotation[i][j];
00138 
00139   // Copy the translation component.
00140   dst[0][3] = src.position.x;
00141   dst[1][3] = src.position.y;
00142   dst[2][3] = src.position.z;
00143 }
00144 
00145 void transformToVpHomogeneousMatrix(vpHomogeneousMatrix& dst,
00146                                     const tf::Transform& src)
00147 {
00148   // Copy the rotation component.
00149   for(unsigned i = 0; i < 3; ++i)
00150     for(unsigned j = 0; j < 3; ++j)
00151       dst[i][j] = src.getBasis ()[i][j];
00152 
00153   // Copy the translation component.
00154   for (unsigned i = 0; i < 3; ++i)
00155     dst[i][3] = src.getOrigin ()[i];
00156   dst[3][3] = 1.;
00157 }
00158 
00159 void convertModelBasedSettingsConfigToVpMe(const visp_tracker::ModelBasedSettingsConfig& config,
00160                                    vpMe& moving_edge,
00161                                    vpMbTracker* tracker)
00162 {
00163   vpMbEdgeTracker* t = dynamic_cast<vpMbEdgeTracker*>(tracker);
00164   
00165   moving_edge.mask_size = config.mask_size;
00166   moving_edge.n_mask = config.n_mask;
00167   moving_edge.range = config.range;
00168   moving_edge.threshold = config.threshold;
00169   moving_edge.mu1 = config.mu1;
00170   moving_edge.mu2 = config.mu2;
00171   moving_edge.sample_step = config.sample_step;
00172   moving_edge.ntotal_sample = config.ntotal_sample;
00173 
00174   moving_edge.strip = config.strip;
00175   moving_edge.min_samplestep = config.min_samplestep;
00176   moving_edge.aberration = config.aberration;
00177   moving_edge.init_aberration = config.init_aberration;
00178 
00179   t->setLambda(config.lambda);
00180   t->setFirstThreshold(config.first_threshold);
00181   
00182   //FIXME: not sure if this is needed.
00183   moving_edge.initMask();
00184   // Reset the tracker and the node state.
00185   t->setMovingEdge(moving_edge);
00186 }
00187 
00188 void convertVpMeToModelBasedSettingsConfig(const vpMe& moving_edge,
00189                                    const vpMbTracker* tracker,
00190                                    visp_tracker::ModelBasedSettingsConfig& config)
00191 {
00192   const vpMbEdgeTracker* t = dynamic_cast<const vpMbEdgeTracker*>(tracker);
00193   
00194   config.mask_size = moving_edge.mask_size;
00195   config.n_mask = moving_edge.n_mask;
00196   config.range = moving_edge.range;
00197   config.threshold = moving_edge.threshold;
00198   config.mu1 = moving_edge.mu1;
00199   config.mu2 = moving_edge.mu2;
00200   config.sample_step = moving_edge.sample_step;
00201   config.ntotal_sample = moving_edge.ntotal_sample;
00202 
00203   config.strip = moving_edge.strip;
00204   config.min_samplestep = moving_edge.min_samplestep;
00205   config.aberration = moving_edge.aberration;
00206   config.init_aberration = moving_edge.init_aberration;
00207 
00208   config.lambda = t->lambda;
00209   config.first_threshold = t->percentageGdPt;
00210 }
00211 
00212 void convertModelBasedSettingsConfigToVpKltOpencv(const visp_tracker::ModelBasedSettingsConfig& config,
00213            vpKltOpencv& klt,
00214            vpMbTracker* tracker)
00215 {
00216   vpMbKltTracker* t = dynamic_cast<vpMbKltTracker*>(tracker);
00217   
00218   klt.setMaxFeatures(config.max_features);
00219   klt.setWindowSize(config.window_size);
00220   klt.setQuality(config.quality);
00221   klt.setMinDistance(config.min_distance);
00222   klt.setHarrisFreeParameter(config.harris);
00223   klt.setBlockSize(config.size_block);
00224   klt.setPyramidLevels(config.pyramid_lvl);
00225   
00226   t->setAngleAppear(vpMath::rad(config.angle_appear));
00227   t->setAngleDisappear(vpMath::rad(config.angle_disappear));
00228   t->setMaskBorder((unsigned)config.mask_border);
00229   
00230   t->setKltOpencv(klt);
00231 }
00232 
00233 void convertVpKltOpencvToModelBasedSettingsConfig(const vpKltOpencv& klt,
00234            const vpMbTracker* tracker,
00235            visp_tracker::ModelBasedSettingsConfig& config)
00236 {
00237   const vpMbKltTracker* t = dynamic_cast<const vpMbKltTracker*>(tracker);
00238   
00239   config.max_features = klt.getMaxFeatures();
00240   config.window_size = klt.getWindowSize();
00241   config.quality = klt.getQuality();
00242   config.min_distance = klt.getMinDistance();
00243   config.harris = klt.getHarrisFreeParameter();
00244   config.size_block = klt.getBlockSize();
00245   config.pyramid_lvl = klt.getPyramidLevels();
00246   
00247   config.angle_appear = vpMath::deg(t->angleAppears);
00248   config.angle_disappear = vpMath::deg(t->angleDisappears);
00249   config.mask_border = t->maskBorder;
00250 }
00251 
00252 void convertVpMeToInitRequest(const vpMe& moving_edge,
00253                               const vpMbTracker* tracker,
00254                               visp_tracker::Init& srv)
00255 {
00256   const vpMbEdgeTracker* t = dynamic_cast<const vpMbEdgeTracker*>(tracker);
00257   
00258   srv.request.moving_edge.mask_size = moving_edge.mask_size;
00259   srv.request.moving_edge.n_mask = moving_edge.n_mask;
00260   srv.request.moving_edge.range = moving_edge.range;
00261   srv.request.moving_edge.threshold = moving_edge.threshold;
00262   srv.request.moving_edge.mu1 = moving_edge.mu1;
00263   srv.request.moving_edge.mu2 = moving_edge.mu2;
00264   srv.request.moving_edge.sample_step = moving_edge.sample_step;
00265   srv.request.moving_edge.ntotal_sample = moving_edge.ntotal_sample;
00266 
00267   srv.request.moving_edge.strip = moving_edge.strip;
00268   srv.request.moving_edge.min_samplestep = moving_edge.min_samplestep;
00269   srv.request.moving_edge.aberration = moving_edge.aberration;
00270   srv.request.moving_edge.init_aberration = moving_edge.init_aberration;
00271 
00272   srv.request.moving_edge.lambda = t->lambda;
00273   srv.request.moving_edge.first_threshold = t->percentageGdPt;
00274 }
00275 
00276 void convertInitRequestToVpMe(const visp_tracker::Init::Request& req,
00277                               vpMbTracker* tracker,
00278                               vpMe& moving_edge)
00279 {
00280   vpMbEdgeTracker* t = dynamic_cast<vpMbEdgeTracker*>(tracker);
00281   
00282   moving_edge.mask_size = req.moving_edge.mask_size;
00283   moving_edge.n_mask = req.moving_edge.n_mask;
00284   moving_edge.range = req.moving_edge.range;
00285   moving_edge.threshold = req.moving_edge.threshold;
00286   moving_edge.mu1 = req.moving_edge.mu1;
00287   moving_edge.mu2 = req.moving_edge.mu2;
00288   moving_edge.sample_step = req.moving_edge.sample_step;
00289   moving_edge.ntotal_sample = req.moving_edge.ntotal_sample;
00290 
00291   moving_edge.strip = req.moving_edge.strip;
00292   moving_edge.min_samplestep = req.moving_edge.min_samplestep;
00293   moving_edge.aberration = req.moving_edge.aberration;
00294   moving_edge.init_aberration = req.moving_edge.init_aberration;
00295 
00296   t->setLambda(req.moving_edge.lambda);
00297   t->setFirstThreshold(req.moving_edge.first_threshold);
00298 }
00299 
00300 void convertVpKltOpencvToInitRequest(const vpKltOpencv& klt,
00301             const vpMbTracker* tracker,
00302             visp_tracker::Init& srv)
00303 {
00304   const vpMbKltTracker* t = dynamic_cast<const vpMbKltTracker*>(tracker);
00305   
00306   srv.request.klt_param.max_features = klt.getMaxFeatures();
00307   srv.request.klt_param.window_size = klt.getWindowSize();
00308   srv.request.klt_param.quality = klt.getQuality();
00309   srv.request.klt_param.min_distance = klt.getMinDistance();
00310   srv.request.klt_param.harris = klt.getHarrisFreeParameter();
00311   srv.request.klt_param.size_block = klt.getBlockSize();
00312   srv.request.klt_param.pyramid_lvl = klt.getPyramidLevels();
00313   
00314   srv.request.klt_param.angle_appear = vpMath::deg(t->angleAppears);
00315   srv.request.klt_param.angle_disappear = vpMath::deg(t->angleDisappears);
00316   srv.request.klt_param.mask_border = t->maskBorder;
00317 }
00318 
00319 void convertInitRequestToVpKltOpencv(const visp_tracker::Init::Request& req,
00320             vpMbTracker* tracker,
00321             vpKltOpencv& klt)
00322 {
00323   vpMbKltTracker* t = dynamic_cast<vpMbKltTracker*>(tracker);
00324   
00325   klt.setMaxFeatures(req.klt_param.max_features);
00326   klt.setWindowSize(req.klt_param.window_size);
00327   klt.setQuality(req.klt_param.quality);
00328   klt.setMinDistance(req.klt_param.min_distance);
00329   klt.setHarrisFreeParameter(req.klt_param.harris);
00330   klt.setBlockSize(req.klt_param.size_block);
00331   klt.setPyramidLevels(req.klt_param.pyramid_lvl);
00332   
00333   t->setAngleAppear(vpMath::rad(req.klt_param.angle_appear));
00334   t->setAngleDisappear(vpMath::rad(req.klt_param.angle_disappear));
00335   t->setMaskBorder((unsigned)req.klt_param.mask_border);
00336 }
00337 
00338 void initializeVpCameraFromCameraInfo(vpCameraParameters& cam,
00339                                       sensor_msgs::CameraInfoConstPtr info)
00340 {
00341   if (!info)
00342     throw std::runtime_error ("missing camera calibration data");
00343 
00344   // Check that the camera is calibrated, as specified in the
00345   // sensor_msgs/CameraInfo message documentation.
00346   if (info->K.size() != 3 * 3 || info->K[0] == 0.)
00347     throw std::runtime_error ("uncalibrated camera");
00348 
00349   // Check matrix size.
00350   if (!info || info->P.size() != 3 * 4)
00351     throw std::runtime_error
00352       ("camera calibration P matrix has an incorrect size");
00353 
00354   if (info->distortion_model.empty ())
00355     {
00356       const double& px = info->K[0 * 3 + 0];
00357       const double& py = info->K[1 * 3 + 1];
00358       const double& u0 = info->K[0 * 3 + 2];
00359       const double& v0 = info->K[1 * 3 + 2];
00360       cam.initPersProjWithoutDistortion(px, py, u0, v0);
00361       return;
00362     }
00363 
00364   if (info->distortion_model == sensor_msgs::distortion_models::PLUMB_BOB)
00365     {
00366       const double& px = info->P[0 * 4 + 0];
00367       const double& py = info->P[1 * 4 + 1];
00368       const double& u0 = info->P[0 * 4 + 2];
00369       const double& v0 = info->P[1 * 4 + 2];
00370       cam.initPersProjWithoutDistortion(px, py, u0, v0);
00371       return;
00372     }
00373 
00374   throw std::runtime_error ("unsupported distortion model");
00375 }


visp_tracker
Author(s): Thomas Moulard/thomas.moulard@gmail.com
autogenerated on Sat Dec 28 2013 17:46:03