RealMonoCamera.cpp
Go to the documentation of this file.
00001 #include "RealMonoCamera.hpp"
00002 
00003 namespace virtual_camera {
00004 
00005 
00006 /*PUBLIC METHODS*/
00007 RealMonoCamera::RealMonoCamera(std::string name,
00008                 const boost::shared_ptr<tf::TransformListener> & listener):
00009         transformListener(listener) {
00010         this->name = name;
00011         this->positionCache = TableP2Ptr(new TableP2());
00012 }
00013 
00014 
00015 bool RealMonoCamera::isReady() {
00016         if (this->camInfo) {
00017                 if (this->image) {
00018                         return true;
00019                 }
00020         }
00021         return false;
00022 }
00023 
00024 
00025 sensor_msgs::CameraInfoConstPtr RealMonoCamera::getCameraInfo() {
00026         return this->camInfo;
00027 }
00028 
00029 
00030 void RealMonoCamera::setCameraInfo(const sensor_msgs::CameraInfoConstPtr & camInfo) {
00031         this->camInfo = camInfo;
00032         kMat[0][0] = camInfo->K[0];kMat[0][1] = camInfo->K[1];kMat[0][2] = camInfo->K[2];
00033         kMat[1][0] = camInfo->K[3];kMat[1][1] = camInfo->K[4];kMat[1][2] = camInfo->K[5];
00034         kMat[2][0] = camInfo->K[6];kMat[2][1] = camInfo->K[7];kMat[2][2] = camInfo->K[8];
00035 }
00036 
00037 
00038 void RealMonoCamera::updateImage(const sensor_msgs::ImageConstPtr & image) {
00039         this->image = image;
00040 }
00041 
00042 
00043 void RealMonoCamera::setPointsCache(std::string frame, const TableV3Ptr & points) {
00044         this->requestFrame = frame;
00045         this->requestPoints = points;
00046         this->buildInnerCache();
00047 }
00048 
00049 
00050 bool RealMonoCamera::validateCache() {
00051         //XXX: doesn't test if internal camera parameters changed
00052         tf::StampedTransform transform;
00053         try {
00054                 this->transformListener->lookupTransform(this->name, this->requestFrame,
00055                           ros::Time(0), transform);
00056         } catch (tf::TransformException & ex){
00057                     ROS_ERROR("%s",ex.what());
00058         }
00059         if (areTransformsEqual(transform, this->usedTransform)){
00060                 return true;
00061         }else {
00062                 this->buildInnerCache();
00063                 return false;
00064         }
00065 }
00066 
00067 
00068 std::string RealMonoCamera::getName() {
00069         return this->name;
00070 }
00071 
00072 
00073 TableP2ConstPtr RealMonoCamera::getCachedPositions() {
00074         return this->positionCache;
00075 }
00076 
00077 
00078 sensor_msgs::ImageConstPtr RealMonoCamera::getImage() {
00079         return this->image;
00080 }
00081 
00082 
00083 float RealMonoCamera::getWeight(int row, int col) {
00084         const Point2D & position = (*(this->positionCache))[row][col];
00085         if(position.x == NOT_VISIBLE) {
00086                 return 0;
00087         }
00088         float xW = 1 - std::fabs((2.0*position.x/camInfo->width)-1);
00089         float yW = 1 - std::fabs((2.0*position.y/camInfo->height)-1);
00090         return std::min(xW, yW);
00091 }
00092 
00093 /*PUBLIC METHODS END*/
00094 
00095 
00096 /*PRIVATE METHODS*/
00097 void RealMonoCamera::buildInnerCache() {
00098         tf::StampedTransform & transform = this->usedTransform;
00099         try {
00100                 this->transformListener->lookupTransform(this->name, this->requestFrame,
00101                   ros::Time(0), transform);
00102         } catch (tf::TransformException & ex){
00103             ROS_ERROR("%s",ex.what());
00104         }
00105         int rows = this->requestPoints->shape()[0];
00106         int cols = this->requestPoints->shape()[1];
00107         this->positionCache->resize(boost::extents[rows][cols]);
00108         for (int y=0; y < rows; y++) { //row major
00109                 for (int x=0; x < cols; x++) {
00110                         this->mapPointToInnerCache(y, x, transform);
00111                 }
00112         }
00113 }
00114 
00115 
00116 void RealMonoCamera::mapPointToInnerCache(
00117                 int row, int col, tf::StampedTransform & transform) {
00118         tf::Vector3 localPt = transform*(*(this->requestPoints))[row][col];
00119         Point2D & res = (*(this->positionCache))[row][col];
00120         if (localPt[2] > 0) {
00121                 this->applyPlumbBobDistortion(localPt);
00122                 tf::Vector3 imPt = (this->kMat)*localPt;
00123                 if (imPt[0] >= 0 && imPt[0] < this->camInfo->width &&
00124                         imPt[1] >= 0 && imPt[1] < this->camInfo->height) {
00125                         res.x = static_cast<int>(std::floor(imPt[0]));
00126                         res.y = static_cast<int>(std::floor(imPt[1]));
00127                         return;
00128                 }
00129         }
00130         //point not in image cameras view
00131         res.x = NOT_VISIBLE;
00132         res.y = NOT_VISIBLE;
00133 }
00134 
00135 
00136 void RealMonoCamera::applyPlumbBobDistortion(tf::Vector3 & p) {
00137         float x = p[0]/p[2];
00138         float y = p[1]/p[2];
00139         float r2 = x*x + y*y;
00140         float dx1 = 2*camInfo->D[2]*x*y + camInfo->D[3]*(r2+2*x*x);
00141         float dx2 = camInfo->D[2]*(r2 + 2*y*y) + 2*camInfo->D[3]*x*y;
00142   // Allow variable number of distortion coefficients following OpenCV implementation, see
00143   // http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
00144   float rad = 1 + camInfo->D[0]*r2 + camInfo->D[1]*r2*r2;
00145   if (camInfo->D.size() >= 5) {
00146     rad += camInfo->D[4]*r2*r2*r2;
00147   }
00148   if (camInfo->D.size() >= 8) {
00149     rad /= 1 + camInfo->D[5]*r2 + camInfo->D[6]*r2*r2 + camInfo->D[7]*r2*r2*r2;
00150   }
00151         p[0] = rad*x + dx1;
00152         p[1] = rad*y + dx2;
00153         p[2] = 1;
00154 }
00155 
00156 
00157 bool RealMonoCamera::areTransformsEqual(
00158                 const tf::StampedTransform & t1, const tf::StampedTransform & t2) {
00159         const tf::Vector3 & o1 = t1.getOrigin();
00160         const tf::Vector3 & o2 = t2.getOrigin();
00161         if (fabs(o1.getX() - o2.getX()) > 0.000001 ||
00162                 fabs(o1.getY() - o2.getY()) > 0.000001 ||
00163                 fabs(o1.getZ() - o2.getZ()) > 0.000001) {
00164                 return false;
00165         }
00166         const tf::Quaternion & r1 = t1.getRotation();
00167         const tf::Quaternion & r2 = t2.getRotation();
00168   // r1 and -r1 represents the same rotation
00169   if (fabs(r1.dot(r2)) < 0.999) {
00170                 return false;
00171         }
00172         return true;
00173 }
00174 /*PRIVATE METHODS END*/
00175 
00176 }
 All Classes Namespaces Files Functions Variables Typedefs Defines


virtual_camera
Author(s): Jan Brabec; maintained by Tomas Petricek / petrito1@cmp.felk.cvut
autogenerated on Tue Dec 10 2013 14:58:11