Go to the documentation of this file.00001 #include <numeric>
00002 #include <ros/ros.h>
00003 #include <algorithm>
00004
00005 #include <geometry_msgs/PointStamped.h>
00006 #include <opencv/cv.h>
00007 #include <opencv2/imgproc/imgproc.hpp>
00008 #include <opencv2/highgui/highgui.hpp>
00009 #include <image_transport/image_transport.h>
00010 #include <image_geometry/pinhole_camera_model.h>
00011 #include <image_geometry/pinhole_camera_model.h>
00012 #include <cv_bridge/cv_bridge.h>
00013 #include <sensor_msgs/image_encodings.h>
00014 #include <std_srvs/Empty.h>
00015
00016 namespace hrl_clickable_world {
00017
00018 class ClickableDisplay {
00019 public:
00020 ros::NodeHandle nh, nh_priv;
00021 image_transport::ImageTransport img_trans;
00022 image_transport::Subscriber camera_sub;
00023 ros::Publisher l_click_pub, r_click_pub;
00024 std::string img_frame;
00025 cv_bridge::CvImagePtr img_ptr;
00026 bool have_img;
00027
00028 ClickableDisplay();
00029 ~ClickableDisplay();
00030 void onInit();
00031 void imgCallback(const sensor_msgs::ImageConstPtr& img_msg);
00032 void showImg();
00033 static void mouseClickCallback(int event, int x, int y, int flags, void* data);
00034
00035 };
00036
00037 ClickableDisplay::ClickableDisplay() : nh_priv("clickable_world"),
00038 img_trans(nh),
00039 have_img(false) {
00040 }
00041
00042 void ClickableDisplay::onInit() {
00043 cv::namedWindow("Clickable World", 1);
00044 cv::setMouseCallback("Clickable World", &ClickableDisplay::mouseClickCallback, this);
00045
00046 camera_sub = img_trans.subscribe<ClickableDisplay>
00047 ("image", 1,
00048 &ClickableDisplay::imgCallback, this);
00049 l_click_pub = nh_priv.advertise<geometry_msgs::PointStamped>("l_mouse_click", 1);
00050 r_click_pub = nh_priv.advertise<geometry_msgs::PointStamped>("r_mouse_click", 1);
00051
00052 ROS_INFO("[clickable_display] ClickableDisplay loaded.");
00053 ros::Duration(1).sleep();
00054 }
00055
00056 void ClickableDisplay::imgCallback(const sensor_msgs::ImageConstPtr& img_msg) {
00057 img_frame = img_msg->header.frame_id;
00058 try {
00059 img_ptr = cv_bridge::toCvCopy(img_msg, sensor_msgs::image_encodings::BGR8);
00060 have_img = true;
00061 }
00062 catch(cv_bridge::Exception& e) {
00063 ROS_ERROR("[clickable_display] cv_bridge exception: %s", e.what());
00064 return;
00065 }
00066 }
00067
00068 void ClickableDisplay::showImg() {
00069 ros::Rate r(30);
00070 while(ros::ok()) {
00071 ros::spinOnce();
00072 if(have_img) {
00073 cv::imshow("Clickable World", img_ptr->image);
00074 cv::waitKey(3);
00075 }
00076 r.sleep();
00077 }
00078 }
00079
00080 void ClickableDisplay::mouseClickCallback(int event, int x, int y, int flags, void* param) {
00081 ClickableDisplay* this_ = reinterpret_cast<ClickableDisplay*>(param);
00082 if(event == CV_EVENT_LBUTTONDOWN) {
00083 geometry_msgs::PointStamped click_pt;
00084 click_pt.header.frame_id = this_->img_frame;
00085 click_pt.header.stamp = ros::Time::now();
00086 click_pt.point.x = x; click_pt.point.y = y;
00087 this_->l_click_pub.publish(click_pt);
00088 }
00089 if(event == CV_EVENT_RBUTTONDOWN) {
00090 geometry_msgs::PointStamped click_pt;
00091 click_pt.header.frame_id = this_->img_frame;
00092 click_pt.header.stamp = ros::Time::now();
00093 click_pt.point.x = x; click_pt.point.y = y;
00094 this_->r_click_pub.publish(click_pt);
00095 }
00096 }
00097
00098 ClickableDisplay::~ClickableDisplay() {
00099 cv::destroyWindow("Clickable World");
00100 }
00101
00102 };
00103
00104
00105 using namespace hrl_clickable_world;
00106
00107 int main(int argc, char **argv)
00108 {
00109 ros::init(argc, argv, "clickable_display");
00110 ClickableDisplay cd;
00111 cd.onInit();
00112 cd.showImg();
00113 ros::spin();
00114 return 0;
00115 }