ed_sensor_integration
fitter_gui.cpp
Go to the documentation of this file.
1 #include "ed_sensor_integration/FitModel.h"
2 #include "ed_sensor_integration/GetModels.h"
3 #include "ed_sensor_integration/GetSnapshots.h"
4 
5 #include <ros/init.h>
6 #include <ros/node_handle.h>
7 #include <ros/service_client.h>
8 
9 #include <opencv2/highgui/highgui.hpp>
10 #include <opencv2/imgproc/imgproc.hpp>
11 
12 #include "ed_sensor_integration/GUIAction.h"
13 
14 // ----------------------------------------------------------------------------------------------------
15 
16 double BUTTON_SIZE = 30;
17 double MODEL_SIZE = 180;
18 double BORDER_SIZE = 10;
19 
20 // ----------------------------------------------------------------------------------------------------
21 
22 struct Model
23 {
25  cv::Mat image;
26 };
27 
28 // ----------------------------------------------------------------------------------------------------
29 
30 struct View
31 {
32  View() {}
33  View(cv::Mat& img_, const cv::Rect& rect_) : rect(rect_), roi(img_(rect)) {}
34 
35  cv::Rect rect;
36  cv::Mat roi;
37 };
38 
39 // ----------------------------------------------------------------------------------------------------
40 
41 unsigned int revision_ = 0;
43 ros::ServiceClient cl_fit_model_;
45 
46 // Models
47 bool models_requested_ = false;
49 unsigned int i_model_start = 0;
51 
54 
55 // GUI actions
56 ed_sensor_integration::GUIAction::ConstPtr gui_action_;
57 
58 void DrawModels(cv::Mat& img, unsigned int i_start);
59 
60 // ----------------------------------------------------------------------------------------------------
61 
62 void mouseCallback(int event, int x, int y, int flags, void* ptr)
63 {
64  cv::Point mpos(x, y);
65 
66  if (event == CV_EVENT_LBUTTONDOWN)
67  {
68  if (model_view.rect.contains(mpos))
69  {
70  mpos -= model_view.rect.tl();
71 
72  if (mpos.y < BUTTON_SIZE)
73  {
74  if (i_model_start > 0)
75  --i_model_start;
76  }
77  else if (mpos.y > model_view.rect.height - BUTTON_SIZE)
78  {
79  if (i_model_start < models_.size() - 1)
80  ++i_model_start;
81  }
82  else
83  {
85  }
86 
88  }
89  else if (snapshot_view.rect.contains(mpos))
90  {
91  std::cout << "SNAPSHOT" << std::endl;
92  }
93 
94 
95 // if (current_image_id_.empty())
96 // {
97 // std::cout << "No image" << std::endl;
98 // return;
99 // }
100 
101 // ed_sensor_integration::FitModel srv;
102 // srv.request.click_x = x;
103 // srv.request.click_y = y;
104 // srv.request.image_id = current_image_id_;
105 // srv.request.model_name = "robotics_testlab_B.hallway_cabinet";
106 
107 // if (cl_fit_model_.call(srv))
108 // {
109 
110 // }
111  }
112 }
113 
114 // ----------------------------------------------------------------------------------------------------
115 
116 void DrawModels(cv::Mat& img, unsigned int i_start)
117 {
118  img.setTo(cv::Vec3b(20, 20, 20));
119 
120  int y = BUTTON_SIZE + BORDER_SIZE;
121  double width = img.cols;
122  for(unsigned int i = i_start; i < models_.size(); ++i)
123  {
124  std::cout << i << ": " << y << std::endl;
125 
126  const cv::Mat& model_img = models_[i].image;
127  double ratio = std::min((width - 2 * BORDER_SIZE) / model_img.cols,
128  MODEL_SIZE / model_img.cols);
129 
130  if (y + MODEL_SIZE > img.rows - BUTTON_SIZE - BORDER_SIZE)
131  {
132  std::cout << y + MODEL_SIZE << std::endl;
133  break;
134  }
135 
136  cv::Rect rect(cv::Point(BORDER_SIZE, y), cv::Size(ratio * model_img.cols, ratio * model_img.rows));
137  cv::Mat roi = img(rect);
138 
139  cv::resize(model_img, roi, rect.size());
140 
141  if (i == i_model_selected)
142  {
143  cv::rectangle(img, rect, cv::Scalar(50, 50, 255), 3);
144  }
145 
146  y += MODEL_SIZE + BORDER_SIZE;
147  }
148 
149  cv::rectangle(img, cv::Point(5, 0), cv::Point(width - 5, BUTTON_SIZE), cv::Scalar(20, 20, 100), 2, 1);
150  cv::rectangle(img, cv::Point(5, img.rows - BUTTON_SIZE), cv::Point(width - 5, img.rows), cv::Scalar(20, 20, 100), 2, 1);
151 
152 }
153 
154 // ----------------------------------------------------------------------------------------------------
155 
156 void DrawSnapshot(cv::Mat& img)
157 {
158  cv::rectangle(img, cv::Point(0, 0), cv::Point(BUTTON_SIZE, img.rows), cv::Scalar(20, 20, 100), 2, 1);
159  cv::rectangle(img, cv::Point(img.cols - BUTTON_SIZE, 0), cv::Point(img.cols, img.rows), cv::Scalar(20, 20, 100), 2, 1);
160 
162  if (it == snapshots_.end())
163  return;
164 
165  const cv::Mat& snapshot = it->second;
166 
167  double ratio = std::min((double)(img.cols - 2 * (BUTTON_SIZE + BORDER_SIZE)) / snapshot.cols,
168  (double)(img.rows - 2 * BORDER_SIZE) / snapshot.rows);
169 
170  cv::Rect rect(cv::Point(BUTTON_SIZE + BORDER_SIZE, BORDER_SIZE),
171  cv::Size(ratio * snapshot.cols, ratio * snapshot.rows));
172 
173  cv::Mat roi = img(rect);
174  cv::resize(snapshot, roi, rect.size());
175 }
176 
177 // ----------------------------------------------------------------------------------------------------
178 
180 {
181 
182 }
183 
184 // ----------------------------------------------------------------------------------------------------
185 
186 void cbGUIAction(const ed_sensor_integration::GUIAction::ConstPtr& msg)
187 {
188  if (msg->action == "switch_snapshot")
189  {
190  current_image_id_ = msg->params[0];
192  }
193  else if (msg->action == "fit_model")
194  {
195  std::string model_name = msg->params[0];
196  std::string image_id = msg->params[1];
197  double click_x_ratio = atof(msg->params[2].c_str());
198  double click_y_ratio = atof(msg->params[3].c_str());
199  }
200 
201  gui_action_ = msg;
202 }
203 
204 // ----------------------------------------------------------------------------------------------------
205 
206 int main(int argc, char **argv)
207 {
208  ros::init(argc, argv, "ed_fitter_gui");
209 
210  ros::NodeHandle nh;
211 
212  ros::ServiceClient cl_get_snapshots = nh.serviceClient<ed_sensor_integration::GetSnapshots>("ed/gui/get_snapshots");
213  ros::ServiceClient cl_get_models = nh.serviceClient<ed_sensor_integration::GetModels>("ed/gui/get_models");
214  cl_fit_model_ = nh.serviceClient<ed_sensor_integration::FitModel>("ed/gui/fit_model");
215 
216  ros::Subscriber sub_gui_actions_= nh.subscribe<ed_sensor_integration::GUIAction>("ed/gui/viz_action", 1, cbGUIAction);
217 
218  cv::Mat canvas(480, 840, CV_8UC3, cv::Scalar(20, 20, 20));
219 
220  cv::namedWindow("Fitter GUI", 1);
221  cv::setMouseCallback("Fitter GUI", mouseCallback);
222 
223  snapshot_view = View(canvas, cv::Rect(cv::Point(0, 0), cv::Size(640, 480)));
224  model_view = View(canvas, cv::Rect(cv::Point(640, 0), cv::Size(200, 480)));
225 
226  ros::Time t_last_update(0);
227 
228  while(ros::ok())
229  {
230  ros::Time time = ros::Time::now();
231 
232  if (time - t_last_update > ros::Duration(1.0))
233  {
234  if (!models_requested_)
235  {
236  ed_sensor_integration::GetModels srv;
237  if (cl_get_models.call(srv))
238  {
239  std::cout << "received: " << srv.response.model_images.size() << " models" << std::endl;
240 
241  models_.resize(srv.response.model_names.size());
242  for(unsigned int i = 0; i < srv.response.model_names.size(); ++i)
243  {
244  Model& m = models_[i];
245  m.image = cv::imdecode(srv.response.model_images[i].data, CV_LOAD_IMAGE_UNCHANGED);
246  m.name = srv.response.model_names[i];
247 
248  }
249 
251 
252  models_requested_ = true;
253  }
254  else
255  {
256  std::cout << "Could not query models" << std::endl;
257  }
258  }
259 
260  ed_sensor_integration::GetSnapshots srv;
261  srv.request.revision = revision_;
262 
263  if (cl_get_snapshots.call(srv))
264  {
265  std::cout << "received: " << srv.response.images.size() << " new images" << std::endl;
266 
267  for(unsigned int i = 0; i < srv.response.images.size(); ++i)
268  {
269  cv::Mat image = cv::imdecode(srv.response.images[i].data, CV_LOAD_IMAGE_UNCHANGED);
270  snapshots_[srv.response.image_ids[i]] = image;
271  current_image_id_ = srv.response.image_ids[i];
272  }
273  revision_ = srv.response.new_revision;
274 
276  }
277  else
278  {
279  ROS_ERROR("Could not call service");
280  }
281 
282  t_last_update = time;
283  }
284 
285  cv::imshow("Fitter GUI", canvas);
286  cv::waitKey(30);
287  }
288 
289  return 0;
290 }
models_requested_
bool models_requested_
Definition: fitter_gui.cpp:47
View
Definition: fitter_gui.cpp:30
revision_
unsigned int revision_
Definition: fitter_gui.cpp:41
View::rect
cv::Rect rect
Definition: fitter_gui.cpp:35
std::string
mouseCallback
void mouseCallback(int event, int x, int y, int flags, void *ptr)
Definition: fitter_gui.cpp:62
Model::name
std::string name
Definition: fitter_gui.cpp:24
std::vector
DrawSnapshot
void DrawSnapshot(cv::Mat &img)
Definition: fitter_gui.cpp:156
MODEL_SIZE
double MODEL_SIZE
Definition: fitter_gui.cpp:17
View::View
View()
Definition: fitter_gui.cpp:32
DrawModels
void DrawModels(cv::Mat &img, unsigned int i_start)
Definition: fitter_gui.cpp:116
main
int main(int argc, char **argv)
Definition: fitter_gui.cpp:206
DrawAction
void DrawAction()
Definition: fitter_gui.cpp:179
image
cv::Mat image
std::cout
BUTTON_SIZE
double BUTTON_SIZE
Definition: fitter_gui.cpp:16
BORDER_SIZE
double BORDER_SIZE
Definition: fitter_gui.cpp:18
snapshot_view
View snapshot_view
Definition: fitter_gui.cpp:52
current_image_id_
std::string current_image_id_
Definition: fitter_gui.cpp:44
cbGUIAction
void cbGUIAction(const ed_sensor_integration::GUIAction::ConstPtr &msg)
Definition: fitter_gui.cpp:186
model_view
View model_view
Definition: fitter_gui.cpp:53
std::map
gui_action_
ed_sensor_integration::GUIAction::ConstPtr gui_action_
Definition: fitter_gui.cpp:56
std::min
T min(T... args)
std::endl
T endl(T... args)
models_
std::vector< Model > models_
Definition: fitter_gui.cpp:48
i_model_selected
int i_model_selected
Definition: fitter_gui.cpp:50
Model::image
cv::Mat image
Definition: fitter_gui.cpp:25
snapshots_
std::map< std::string, cv::Mat > snapshots_
Definition: fitter_gui.cpp:42
i_model_start
unsigned int i_model_start
Definition: fitter_gui.cpp:49
Model
Definition: fitter_gui.cpp:22
cl_fit_model_
ros::ServiceClient cl_fit_model_
Definition: fitter_gui.cpp:43
View::roi
cv::Mat roi
Definition: fitter_gui.cpp:36
View::View
View(cv::Mat &img_, const cv::Rect &rect_)
Definition: fitter_gui.cpp:33