Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _ellipses_representation_h_
00026 #define _ellipses_representation_h_
00027
00028 #include <iri_clean_board/CleaningPlanConfig.h>
00029 #include "mutex.h"
00030
00031
00032
00033 #include <cv_bridge/cv_bridge.h>
00034 #include <sensor_msgs/image_encodings.h>
00035 #include <opencv2/imgproc/imgproc.hpp>
00036
00037
00038 #include <estirabot_msgs/StateRepresentationChanges.h>
00039 #include <estirabot_msgs/PointsDistanceMsg.h>
00040 #include <estirabot_msgs/DirtyArea.h>
00041 #include <estirabot_msgs/Ellipse.h>
00042 #include <estirabot_msgs/TraversedEllipses.h>
00043 #include <iri_perception_msgs/ImagePoint.h>
00044
00045
00046 #include <pcl/point_cloud.h>
00047 #include <pcl/io/pcd_io.h>
00048 #include <pcl/point_types.h>
00049 #include <pcl/common/common.h>
00050
00051
00052 #include <tf/transform_datatypes.h>
00053 #include <Eigen/Core>
00054 #include <Eigen/Geometry>
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00095 class EllipsesRepresentation
00096 {
00097 protected:
00104 CMutex alg_mutex_;
00105
00106
00107 static const int IMAGE_WIDTH = 640;
00108 static const int IMAGE_HEIGHT = 480;
00109
00110
00111 double minFillThreshold;
00112 double minAreaThreshold;
00113 bool board_plan;
00114 uint32_t max_number_ellipses;
00115 bool is_planning;
00116 bool is_learning;
00117
00118
00119 std::vector<cv::RotatedRect> imageEllipses;
00120 std::vector<estirabot_msgs::DirtyArea> dirtyAreas_;
00121 std::vector<double> ellipsesMinWidths;
00122 std::vector<double> ellipsesMaxWidths;
00123 std::vector<double> ellipsesArea;
00124 std::vector<uint8_t> ellipsesSparse;
00125 uint32_t small_objects_join_distance;
00126
00127
00128
00129 double small_area_threshold, medium_area_threshold;
00130
00131 double min_width_threshold, max_width_threshold;
00132 double near_distance_threshold;
00133 int initial_state_idx;
00134
00135 std::string dirtyAreaToString(estirabot_msgs::DirtyArea dirty_area, int idx);
00136
00137 std::string dirtyAreasDistancesToString(std::vector< estirabot_msgs::PointsDistanceMsg > distances);
00138
00139 std::string traversedEllipsesToString(std::vector<estirabot_msgs::TraversedEllipses> traversed_ellipses);
00140
00141 inline double getDistance(cv::Point2f p1, cv::Point2f p2)
00142 {
00143
00144 return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
00145 }
00146 inline double getDistance(iri_perception_msgs::ImagePoint p1, iri_perception_msgs::ImagePoint p2)
00147 {
00148 return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
00149 }
00150
00151
00158 void computeBoundingEllipses(cv::Mat image);
00159
00166 void clearLastEllipses();
00167
00174 void setSourceImage(cv::Mat image);
00175
00182 bool divideBigEllipse(cv::Mat image, cv::Mat ellipseMask, cv::RotatedRect currentEllipse);
00183
00184
00185 public:
00186
00187 cv::Mat state_image;
00188 cv::Mat show_image;
00189
00190
00197 typedef iri_clean_board::CleaningPlanConfig Config;
00198
00205 Config config_;
00206
00215 EllipsesRepresentation(void);
00216
00222 void lock(void) { alg_mutex_.enter(); };
00223
00229 void unlock(void) { alg_mutex_.exit(); };
00230
00238 bool try_enter(void) { return alg_mutex_.try_enter(); };
00239
00251 void config_update(Config& new_cfg, uint32_t level=0);
00252
00253
00254
00255
00262 ~EllipsesRepresentation(void);
00263
00264
00271 void createNewState(cv::Mat image);
00272
00273
00281 std::vector< estirabot_msgs::PointsDistanceMsg > distancesBetweenEllipses(std::vector<estirabot_msgs::DirtyArea> dirty_areas);
00282
00283
00291 std::vector< estirabot_msgs::TraversedEllipses > getTraversedEllipses(std::vector<estirabot_msgs::DirtyArea> dirty_areas);
00292 bool pointIsBetween(cv::Point2f p1, cv::Point2f p2, cv::Point2f point);
00293 bool pointIsBetween(iri_perception_msgs::ImagePoint new_p1, iri_perception_msgs::ImagePoint new_p2, iri_perception_msgs::ImagePoint new_point);
00294 bool pointIsBetween(iri_perception_msgs::ImagePoint new_p1, cv::Point2f p2, iri_perception_msgs::ImagePoint new_point);
00295
00296
00303 int32_t getNearestEllipse();
00304
00312 void drawPoints(std::vector< cv::Point2f > img_coords);
00313
00314
00315
00319 estirabot_msgs::Ellipse rotatedRectToRosEllipse(cv::RotatedRect ellipse) {
00320 estirabot_msgs::Ellipse emsg;
00321 emsg.size.width = ellipse.size.width;
00322 emsg.size.height = ellipse.size.height;
00323 emsg.center.x = ellipse.center.x;
00324 emsg.center.y = ellipse.center.y;
00325 emsg.angle = ellipse.angle;
00326 return emsg;
00327 };
00328
00332 cv::RotatedRect rosEllipseToRotatedRect(estirabot_msgs::Ellipse ellipse_msg) {
00333 cv::RotatedRect ellipse;
00334 cv::Size2f size(ellipse_msg.size.width, ellipse_msg.size.height);
00335 cv::Point2f center(ellipse_msg.center.x, ellipse_msg.center.y);
00336
00337
00338 ellipse = cv::RotatedRect(center, size, ellipse_msg.angle);
00339 return ellipse;
00340 };
00341
00342
00348 void truncateEllipsesNumber();
00349
00355 std::vector< cv::RotatedRect > loadEllipsesFromRosMsg(std::vector< estirabot_msgs::Ellipse > ellipses_msg);
00356 std::vector< cv::RotatedRect > loadEllipsesFromRosMsg(std::vector< estirabot_msgs::DirtyArea > dirty_areas_msg);
00357
00363 void writeStateToFile(std::string path,
00364 std::vector<estirabot_msgs::DirtyArea> dirty_areas);
00365
00366
00367
00368
00372 std::vector<estirabot_msgs::Ellipse> getEllipsesRosMsg() {
00373 std::vector<estirabot_msgs::Ellipse> ellipses_msg;
00374
00375 for(std::vector<cv::RotatedRect>::iterator j=imageEllipses.begin(); j!=imageEllipses.end(); ++j) {
00376 ellipses_msg.push_back(rotatedRectToRosEllipse(*j));
00377 }
00378
00379 return ellipses_msg;
00380 };
00381
00385 std::vector<cv::RotatedRect> getCurrentEllipses() { return imageEllipses; };
00386
00392 std::string getStateString(const std::vector<estirabot_msgs::DirtyArea> dirty_areas);
00393 std::string getStateStringOrdered(const std::vector<estirabot_msgs::DirtyArea> dirty_areas);
00394
00395 std::vector<estirabot_msgs::DirtyArea> orderDirtyAreas(const std::vector<estirabot_msgs::DirtyArea> dirty_areas,
00396 const std::vector<estirabot_msgs::DirtyArea> previous_dirty_areas);
00397
00401 std::vector<double> getEllipsesMinWidths() { return ellipsesMinWidths; };
00402
00406 std::vector<double> getEllipsesMaxWidths() { return ellipsesMaxWidths; };
00407
00411 std::vector<double> getEllipsesAreas() { return ellipsesArea; };
00412
00416 std::vector<estirabot_msgs::DirtyArea> getRosDirtyAreas();
00417 std::vector<estirabot_msgs::DirtyArea> calculateRosDirtyAreas(std::vector<cv::RotatedRect> ellipses);
00418
00422 double getEllipsesSummedAreas()
00423 {
00424 double sum_areas;
00425 for(std::vector<double>::iterator j=ellipsesArea.begin();j!=ellipsesArea.end();++j)
00426 sum_areas += *j;
00427 return sum_areas;
00428 };
00429
00433 std::vector< uint8_t > getEllipsesSparse() { return ellipsesSparse; };
00434
00438 size_t getEllipsesNumber() { return imageEllipses.size(); };
00439
00445 std::vector< size_t > getGoodPathThroughAllEllipses(size_t init_ellipse);
00446 std::vector< size_t > getGoodPathThroughAllDirtyAreas(std::vector< estirabot_msgs::DirtyArea > dirty_areas);
00447
00453 cv::RotatedRect getEllipseFromRosDirtyAreas(std::vector< estirabot_msgs::DirtyArea > dirty_areas, int idx);
00454
00455
00456
00457
00463 cv::Point2f currentArmPosition;
00464 };
00465
00466 #endif