00001
00002
00003
00004
00005
00006
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
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
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
00042 }
00043
00044
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
00083 for (int i = 0; i < 4; i++) {
00084
00085
00086 CvLineIterator iterator;
00087 int pixel_count = cvInitLineIterator(ipl_image, points[i],
00088 points[(i + 1) % 4], &iterator, 8, 0);
00089
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
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
00111 if ((x < ipl_image->height) && (y < ipl_image->width) && (x >= 0)
00112 && (y >= 0))
00113 pixel.push_back(cv::Point(x, 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
00124 for (int i = 0; i < 4; i++) {
00125
00126
00127
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
00135 }
00136
00137
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
00147 if ((x < image.rows) && (y < image.cols) && (x >= 0) && (y >= 0))
00148 pixel.push_back(cv::Point(y, x));
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
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 {
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 }