tools.cpp
Go to the documentation of this file.
00001 
00002 /*
00003  * tools.cpp
00004  *
00005  *  Created on: 13.07.2011
00006  *      Author: hess
00007  */
00008 
00009 #include <coverage_3d_tools/tools.h>
00010 
00011 #include <opencv2/ml/ml.hpp>
00012 #include <opencv2/highgui/highgui.hpp>
00013 
00014 
00015 float mahalanobis(const cv::Mat& v1, const cv::Mat& v2, const cv::Mat& invCov) {
00016 
00017         cv::Mat_<float>& ptr_v1 = (cv::Mat_<float>&) v1;
00018         cv::Mat_<float>& ptr_v2 = (cv::Mat_<float>&) v2;
00019         cv::Mat_<float>& ptr_cov = (cv::Mat_<float>&) invCov;
00020 
00021         float diff0 = 0;
00022         float diff1 = 0;
00023         float diff2 = 0;
00024 
00025         //take the difference
00026         for (int i = 0; i < 3; ++i) {
00027                 diff0 = ptr_v1(0, 0) - ptr_v2(0, 0);
00028                 diff1 = ptr_v1(0, 1) - ptr_v2(0, 1);
00029                 diff2 = ptr_v1(0, 2) - ptr_v2(0, 2);
00030         }
00031 
00032         float tmp0 = 0;
00033         float tmp1 = 0;
00034         float tmp2 = 0;
00035 
00036         //left-multiply
00037         for (int i = 0; i < 3; ++i) {
00038                 tmp0 += diff0 * ptr_cov(0, i);
00039                 tmp1 += diff1 * ptr_cov(1, i);
00040                 tmp2 += diff2 * ptr_cov(2, i);
00041                 //        cout << ptr
00042         }
00043 
00044         //right-multiply
00045         float result = 0;
00046         for (int i = 0; i < 3; ++i) {
00047                 result += tmp0 * diff0;
00048                 result += tmp1 * diff1;
00049                 result += tmp2 * diff2;
00050         }
00051 
00052         return result;
00053 }
00054 
00055 void computeCornersFromCell(const tf::Point center, const tf::Point v1,
00056                 const tf::Point v2, tf::Point* rect_points) {
00057 
00058         tf::Point curr_corner;
00059         rect_points[0] = center - v1 - v2;
00060         rect_points[1] = center + v1 - v2;
00061         rect_points[2] = center + v1 + v2;
00062         rect_points[3] = center - v1 + v2;
00063 }
00064 
00065 void computeCornersFromCell(const tf::Point center, const tf::Point v1,
00066                 const tf::Point v2, std::vector<tf::Point>& rect_points) {
00067 
00068         tf::Point curr_corner;
00069         rect_points.clear();
00070         rect_points.resize(4);
00071         rect_points[0] = center - v1 - v2;
00072         rect_points[1] = center + v1 - v2;
00073         rect_points[2] = center + v1 + v2;
00074         rect_points[3] = center - v1 + v2;
00075 }
00076 
00077 void computeRectPixel(const IplImage *ipl_image,
00078                 const std::vector<cv::Point>& points, std::vector<cv::Point>& pixel) {
00079 
00080         std::map<int, std::map<int, bool> > rect;
00081 
00082         //iterate over all four side of the rectangle
00083         for (int i = 0; i < 4; i++) {
00084 
00085                 //compute all points belonging to line
00086                 CvLineIterator iterator;
00087                 int pixel_count = cvInitLineIterator(ipl_image, points[i],
00088                                 points[(i + 1) % 4], &iterator, 8, 0);
00089                 //          ROS_INFO("pixel_count %i", pixel_count);
00090                 for (int j = 0; j < pixel_count; j++) {
00091                         int x = (iterator.ptr - (uchar*) ipl_image->imageData)
00092                                         / ipl_image->widthStep;
00093                         int y = ((iterator.ptr - (uchar*) ipl_image->imageData)
00094                                         % ipl_image->widthStep) / ipl_image->nChannels;
00095                         rect[x][y] = true;
00096 
00097                         CV_NEXT_LINE_POINT(iterator);
00098                 }
00099         }
00100 
00101         //collect all points belonging to the rectangle
00102         std::map<int, std::map<int, bool> >::iterator rect_it;
00103         pixel.clear();
00104         for (rect_it = rect.begin(); rect_it != rect.end(); rect_it++) {
00105                 int x = rect_it->first;
00106                 int y1 = rect_it->second.begin()->first;
00107                 int y2 = rect_it->second.rbegin()->first;
00108                 for (int y = y1; y <= y2; y++) {
00109 
00110                         //in case of wrong table detection: only push pixels inside the image
00111                         if ((x < ipl_image->height) && (y < ipl_image->width) && (x >= 0)
00112                                         && (y >= 0))
00113                                 pixel.push_back(cv::Point(x, y)); //TODO: check: that is really weird c and c++ different representation of x and y?
00114                 }
00115         }
00116 }
00117 
00118 void computeRectPixel(const cv::Mat& image,
00119                 const std::vector<cv::Point>& points, std::vector<cv::Point>& pixel) {
00120 
00121         std::map<int, std::map<int, bool> > rect;
00122 
00123         //iterate over all four sides of the rectangle
00124         for (int i = 0; i < 4; i++) {
00125                 //compute all points belonging to line
00126 //              std::cout << "point " << i << " " << points[i].x << " " << points[i].y
00127 //                              << std::endl;
00128                 cv::LineIterator it(image, points[i], points[(i + 1) % 4], 8, 0);
00129 
00130                 for (int j = 0; j < it.count; j++, ++it) {
00131 
00132                         rect[it.pos().x][it.pos().y] = true;
00133                 }
00134                 //      cvLine(image, points[i], points[(i + 1) % 4], color, 1, 8);
00135         }
00136 
00137         //collect all points belonging to the rectangle
00138         std::map<int, std::map<int, bool> >::iterator rect_it;
00139         pixel.clear();
00140         for (rect_it = rect.begin(); rect_it != rect.end(); rect_it++) {
00141                 int x = rect_it->first;
00142                 int y1 = rect_it->second.begin()->first;
00143                 int y2 = rect_it->second.rbegin()->first;
00144                 for (int y = y1; y <= y2; y++) {
00145 
00146                         //in case of wrong table detection: only push pixels inside the image
00147                         if ((x < image.rows) && (y < image.cols) && (x >= 0) && (y >= 0))
00148                                 pixel.push_back(cv::Point(y, x)); //TODO: check: that is really weird c and c++ different representation of x and y?
00149                 }
00150         }
00151 }
00152 
00153 bool linePlaneIntersection(const cv::Point3d& plane_normal,
00154                 const cv::Point3d& point_in_plane, const cv::Point3d& line_unit_vector,
00155                 const cv::Point3d& line_origin, cv::Point3d& intersection) {
00156 
00157         cv::Point3d tmp = (point_in_plane - line_origin);
00158         double numerator = tmp.dot(plane_normal);
00159         double denominator = line_unit_vector.dot(plane_normal);
00160 
00161         //if the line intersects the plane:
00162         if (std::fabs(numerator) > 0.00001 && std::fabs(denominator) > 0.00001) {
00163 
00164                 double distance_from_origin = numerator / denominator;
00165                 intersection = distance_from_origin * line_unit_vector;
00166                 return true;
00167         } else { //otherwise it is parallel or inside the plane, but we don't check the case
00168                 return false;
00169         }
00170 }
00171 
00172 bool getTransform(const std::string& source, const std::string& target, tf::TransformListener& listener, tf::StampedTransform& transform){
00173         bool received =false;
00174         int iter=0;
00175         while (!received && iter < 50) {
00176                 iter++;
00177                 ROS_DEBUG_STREAM("Looking up transform from " << source << " to " << target);
00178                 ros::Time lookup_time = ros::Time::now();
00179                 try {
00180                         ros::Duration timeout(0.1);
00181                         listener.waitForTransform(source,
00182                                         target, lookup_time, timeout);
00183                         listener.lookupTransform(source,
00184                                         target, lookup_time, transform);
00185                         received = true;
00186                 } catch (tf::LookupException& e) {
00187                         ROS_WARN_STREAM(e.what());
00188                         ROS_INFO("Continue waiting for transform.");
00189                 } catch (tf::ConnectivityException& e) {
00190                         ROS_WARN_STREAM("coverage::tools::getTransform: " << e.what());
00191                 } catch (std::exception& e) {
00192                         ROS_WARN_STREAM("other execption: " << e.what());
00193                 }
00194                 ros::Rate r(10);
00195                 r.sleep();
00196         }
00197         if (received){
00198                 return true;
00199         } else {
00200                 return false;
00201         }
00202 }
00203 
00204 bool getTransform(const std::string& source, const std::string& target, tf::StampedTransform& transform){
00205         tf::TransformListener listener;
00206         return (getTransform(source, target, listener, transform));
00207 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


coverage_3d_tools
Author(s): Juergen Hess
autogenerated on Wed Dec 26 2012 15:25:37