00001
00034 #include "ros/ros.h"
00035 #include "sensor_msgs/Image.h"
00036 #include "image_transport/image_transport.h"
00037 #include "cv_bridge/CvBridge.h"
00038 #include "MetaFile.h"
00039 #include <opencv/cv.h>
00040 #include <opencv/highgui.h>
00041
00042 #include <std_msgs/String.h>
00043 #include <geometry_msgs/Point.h>
00044 #include <geometry_msgs/Transform.h>
00045 #include <sensor_msgs/Image.h>
00046 #include <boost/shared_ptr.hpp>
00047
00048 #include "re_vision/SearchFor.h"
00049
00050 #include <cstdlib>
00051 #include <string>
00052 #include <iomanip>
00053
00054 #include <boost/shared_ptr.hpp>
00055
00056 using namespace std;
00057
00058
00059
00060 class ImageGrabber
00061 {
00062 public:
00063 ImageGrabber(){}
00064 ~ImageGrabber(){}
00065 void topicImageRawGot(const sensor_msgs::Image::ConstPtr& msg);
00066 };
00067
00068
00069
00070 cv::Mat loadSomeImage(int idx);
00071 void createRequest(re_vision::SearchFor &srv, const cv::Mat &image);
00072 void showResponse(const re_vision::SearchFor &srv);
00073 void storeResponse(const re_vision::SearchFor &srv,
00074 const cv::Mat &image, int idx);
00075
00076
00077
00078
00079 static vector<string> m_object_list;
00080 static sensor_msgs::CvBridge m_bridge;
00081
00082
00083 static ros::NodeHandle *m_n;
00084 static ros::Subscriber m_camera_sub;
00085 static ros::ServiceClient m_client;
00086 static ImageGrabber m_grabber;
00087
00088
00089
00090 int main(int argc, char **argv)
00091 {
00092 sleep(1);
00093
00094 ros::init(argc, argv, "TestObjectDetector");
00095
00096 m_n = new ros::NodeHandle;
00097
00098 m_client = m_n->serviceClient<re_vision::SearchFor>("/re_vision/search_for");
00099
00100 m_camera_sub = m_n->subscribe("/image_raw",
00101 1, &ImageGrabber::topicImageRawGot, &m_grabber);
00102
00103
00104
00105
00106 std::string object = "bottle1";
00107 if(argc >= 2) object = argv[1];
00108
00109 if(object == "all")
00110 {
00111 m_object_list.push_back("van");
00112
00113
00114
00115
00116
00117 }
00118 else
00119 {
00120 m_object_list.push_back(object);
00121 }
00122
00123 stringstream ss;
00124 for(unsigned int k = 0; k < m_object_list.size(); ++k)
00125 {
00126 ss << m_object_list[k] << " ";
00127 }
00128
00129 if(false)
00130 ROS_INFO("There are %d available 3d objects: %s", m_object_list.size(),
00131 ss.str().c_str());
00132 else
00133 ROS_INFO("There are %d availale planar objects: %s", m_object_list.size(),
00134 ss.str().c_str());
00135
00136 re_vision::SearchFor srv;
00137 const int N = 0;
00138
00139
00140
00141
00142
00143 vector<int> counters(m_object_list.size(), 0);
00144
00145 for(int i = 0; i < N; ++i){
00146 cv::Mat image = loadSomeImage(i);
00147
00148 createRequest(srv, image);
00149
00150 ss.str("");
00151 for(unsigned int k = 0; k < srv.request.Objects.size(); ++k)
00152 {
00153 ss << srv.request.Objects[k] << " ";
00154 }
00155 ROS_INFO("Sending request to find object(s): %s", ss.str().c_str());
00156
00157 if (m_client.call(srv))
00158 {
00159 ROS_INFO("Request %d made ok", i);
00160 showResponse(srv);
00161
00162
00163 storeResponse(srv, image, i);
00164
00165 for(unsigned int j = 0; j < m_object_list.size(); j++)
00166 if(!srv.response.Detections[j].points2d.empty()) counters[j]++;
00167
00168
00169 }else{
00170 ROS_ERROR("Failed to call service re_vision::SearchFor (%d)", i);
00171 return 1;
00172 }
00173 }
00174
00175 cout << "Counters:" << endl;
00176 for(unsigned int j = 0; j < m_object_list.size(); j++){
00177 cout << "Object " << j << ": " << counters[j] << endl;
00178 }
00179
00180 ros::spin();
00181
00182 delete m_n;
00183
00184 return 0;
00185 }
00186
00187
00188
00189 void ImageGrabber::topicImageRawGot(const sensor_msgs::Image::ConstPtr& msg)
00190 {
00191 ROS_WARN("/image_raw got");
00192
00193 static int i = -1;
00194 i++;
00195
00196 re_vision::SearchFor srv;
00197
00198 IplImage * img_ipl =
00199 m_bridge.imgMsgToCv(msg, "passthrough");
00200 cv::Mat image = cv::Mat(img_ipl).clone();
00201
00202 createRequest(srv, image);
00203
00204 stringstream ss;
00205 for(unsigned int k = 0; k < srv.request.Objects.size(); ++k)
00206 {
00207 ss << srv.request.Objects[k] << " ";
00208 }
00209 ROS_INFO("Sending request to find object(s): %s", ss.str().c_str());
00210
00211 if (m_client.call(srv))
00212 {
00213 ROS_INFO("Request %d made ok", i);
00214 showResponse(srv);
00215
00216
00217 storeResponse(srv, image, i);
00218
00219
00220
00221 }else{
00222 ROS_ERROR("Failed to call service re_vision::SearchFor (%d)", i);
00223 }
00224
00225 }
00226
00227
00228
00229 void createRequest(re_vision::SearchFor &srv, const cv::Mat &image)
00230 {
00231
00232 IplImage img(image);
00233
00234 try{
00235 sensor_msgs::Image::Ptr ros_img_ptr = m_bridge.cvToImgMsg(&img, "passthrough");
00236 srv.request.Image = sensor_msgs::Image(*ros_img_ptr);
00237
00238 }catch (sensor_msgs::CvBridgeException error){
00239 ROS_ERROR("error in createRequest");
00240 }
00241
00242 srv.request.Objects.clear();
00243 for(unsigned int j = 0; j < m_object_list.size(); ++j)
00244 srv.request.Objects.push_back(m_object_list[j]);
00245
00246 srv.request.MaxPointsPerObject = 3;
00247 }
00248
00249
00250
00251 void showResponse(const re_vision::SearchFor &srv)
00252 {
00253 const vector<re_msgs::DetectedObject> &D = srv.response.Detections;
00254
00255 stringstream ss;
00256
00257
00258 if(0){
00259 ss << "ObjectDetector is not ready yet";
00260 }else{
00261 ss << "Response got: ";
00262
00263 if(!D.empty()) ss << endl;
00264
00265 vector<re_msgs::DetectedObject>::const_iterator it;
00266 vector<re_msgs::Pixel>::const_iterator pit;
00267 vector<geometry_msgs::Point>::const_iterator pit3d;
00268 for(it = D.begin(); it != D.end(); ++it){
00269 ss << " + Object " << it - D.begin() << " ";
00270
00271 if(it->points2d.empty())
00272 ss << "(not found)";
00273 else
00274 ss << "(found)";
00275
00276 ss << ": "
00277 << "position: X=" << it->pose.position.x
00278 << ", Y=" << it->pose.position.y
00279 << ", Z=" << it->pose.position.z
00280 << ", quaternion: "
00281 << it->pose.orientation.x << " "
00282 << it->pose.orientation.y << " "
00283 << it->pose.orientation.z << " "
00284 << it->pose.orientation.w << ". "
00285 << "There are " << it->points2d.size() << " points detected";
00286
00287 if(!it->points2d.empty()){
00288 ss << ":" << endl << " ";
00289 for(pit = it->points2d.begin(); pit != it->points2d.end(); ++pit){
00290 pit3d = it->points3d.begin() + (pit - it->points2d.begin());
00291
00292 ss << "(" << pit->x << ", " << pit->y << " => "
00293 << pit3d->x << ", " << pit3d->y << ", " << pit3d->z << "), ";
00294 }
00295 }
00296
00297 ss << endl;
00298 }
00299 }
00300
00301 ROS_INFO("%s", ss.str().c_str());
00302
00303 }
00304
00305
00306
00307 inline int getImIdx(int idx){
00308 return idx + 0;
00309 }
00310
00311 cv::Mat loadSomeImage(int idx)
00312 {
00313 const int im_idx = getImIdx(idx);
00314 stringstream ss;
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 ss << "/home/dorian/Universidad/Proyectos/RoboEarth/SvnUnizar/ObjectDetectorOld/images/fragoneta_mesa/frame"
00338 << setw(4) << setfill('0') << im_idx << ".jpg";
00339
00340 cv::Mat m = cv::imread(ss.str(), 0);
00341
00342 if(m.cols == 0)
00343 ROS_ERROR("Could not find image file: %s", ss.str().c_str());
00344
00345 return m;
00346 }
00347
00348
00349
00350 void storeResponse(const re_vision::SearchFor &srv,
00351 const cv::Mat &image, int idx)
00352 {
00353 const int im_idx = getImIdx(idx);
00354 stringstream ss;
00355
00356
00357 ss << "TestObjectDetector_result.png";
00358
00359 cv::Mat im;
00360 cv::cvtColor(image, im, CV_GRAY2RGB, 3);
00361
00362 CvScalar colors[] = {
00363 cvScalar(255, 0, 0),
00364 cvScalar(0, 255, 0)
00365 };
00366
00367
00368 vector<re_msgs::DetectedObject>::const_iterator it;
00369 for(it = srv.response.Detections.begin();
00370 it != srv.response.Detections.end(); ++it)
00371 {
00372 ROS_DEBUG("Image %d, object %d, points %d", im_idx,
00373 it -srv.response.Detections.begin(),
00374 it->points2d.size());
00375
00376 CvScalar color = colors[it - srv.response.Detections.begin()];
00377
00378 vector<re_msgs::Pixel>::const_iterator pit;
00379 for(pit = it->points2d.begin(); pit != it->points2d.end(); ++pit){
00380 cv::circle(im, cvPoint(pit->x, pit->y), 5, color, 1);
00381 }
00382 }
00383
00384 cv::imwrite(ss.str(), im);
00385 }
00386
00387
00388