ObjectDetection.cpp
Go to the documentation of this file.
1 /*
2  * ObjectDetection.cpp
3  *
4  * Created on: Jan 07, 2017
5  * Author: Marko Bjelonic
6  * Institute: ETH Zurich, Robotic Systems Lab
7  */
8 
9 // Google Test
10 #include <gtest/gtest.h>
11 
12 // ROS
14 #include <ros/package.h>
15 #include <ros/ros.h>
16 #include <sensor_msgs/Image.h>
17 
18 // boost
19 #include <boost/thread.hpp>
20 
21 // OpenCV2.
22 #include <cv_bridge/cv_bridge.h>
23 #include <opencv2/core/core.hpp>
24 #include <opencv2/highgui/highgui.hpp>
25 #include <opencv2/imgproc/imgproc.hpp>
26 
27 // Actions.
28 #include <darknet_ros_msgs/CheckForObjectsAction.h>
29 
31 using CheckForObjectsActionClientPtr = std::shared_ptr<CheckForObjectsActionClient>;
32 
33 // c++
34 #include <cmath>
35 #include <string>
36 
37 #ifdef DARKNET_FILE_PATH
38 std::string darknetFilePath_ = DARKNET_FILE_PATH;
39 #else
40 #error Path of darknet repository is not defined in CMakeLists.txt.
41 #endif
42 
43 darknet_ros_msgs::BoundingBoxes boundingBoxesResults_;
44 
50 void checkForObjectsResultCB(const actionlib::SimpleClientGoalState& state, const darknet_ros_msgs::CheckForObjectsResultConstPtr& result) {
51  std::cout << "[ObjectDetectionTest] Received bounding boxes." << std::endl;
52 
53  boundingBoxesResults_ = result->bounding_boxes;
54 }
55 
56 bool sendImageToYolo(ros::NodeHandle nh, const std::string& pathToTestImage) {
58  CheckForObjectsActionClientPtr checkForObjectsActionClient;
59 
60  // Action clients.
61  std::string checkForObjectsActionName;
62  nh.param("/darknet_ros/camera_action", checkForObjectsActionName, std::string("/darknet_ros/check_for_objects"));
63  checkForObjectsActionClient.reset(new CheckForObjectsActionClient(nh, checkForObjectsActionName, true));
64 
65  // Wait till action server launches.
66  if (!checkForObjectsActionClient->waitForServer(ros::Duration(20.0))) {
67  std::cout << "[ObjectDetectionTest] sendImageToYolo(): checkForObjects action server has not been advertised." << std::endl;
68  return false;
69  }
70 
71  // Get test image
73  cv_ptr->image = cv::imread(pathToTestImage, cv::IMREAD_COLOR);
74  cv_ptr->encoding = sensor_msgs::image_encodings::RGB8;
75  sensor_msgs::ImagePtr image = cv_ptr->toImageMsg();
76 
77  // Generate goal.
78  darknet_ros_msgs::CheckForObjectsGoal goal;
79  goal.image = *image;
80 
81  // Send goal.
82  ros::Time beginYolo = ros::Time::now();
83  checkForObjectsActionClient->sendGoal(goal, boost::bind(&checkForObjectsResultCB, _1, _2),
86 
87  if (!checkForObjectsActionClient->waitForResult(ros::Duration(100.0))) {
88  std::cout << "[ObjectDetectionTest] sendImageToYolo(): checkForObjects action server took to long to send back result." << std::endl;
89  return false;
90  }
91  ros::Time endYolo = ros::Time::now();
92  std::cout << "[ObjectDetectionTest] Object detection for one image took " << endYolo - beginYolo << " seconds." << std::endl;
93  return true;
94 }
95 
96 TEST(ObjectDetection, DISABLED_DetectDog) {
97  srand(static_cast<unsigned int>(time(nullptr)));
98  ros::NodeHandle nodeHandle("~");
99 
100  // Path to test image.
101  std::string pathToTestImage = darknetFilePath_;
102  pathToTestImage += "/data/";
103  pathToTestImage += "dog";
104  pathToTestImage += ".jpg";
105 
106  // Send dog image to yolo.
107  ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
108  ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
109 
110  // Evaluate if yolo was able to detect the three objects: dog, bicycle and car.
111  bool detectedDog = false;
112  double centerErrorDog;
113  bool detectedBicycle = false;
114  double centerErrorBicycle;
115  bool detectedCar = false;
116  double centerErrorCar;
117 
118  for (auto& boundingBox : boundingBoxesResults_.bounding_boxes) {
119  double xPosCenter = boundingBox.xmin + (boundingBox.xmax - boundingBox.xmin) * 0.5;
120  double yPosCenter = boundingBox.ymin + (boundingBox.ymax - boundingBox.ymin) * 0.5;
121 
122  if (boundingBox.Class == "dog") {
123  detectedDog = true;
124  // std::cout << "centerErrorDog " << xPosCenter << ", " << yPosCenter << std::endl;
125  centerErrorDog = std::sqrt(std::pow(xPosCenter - 222.5, 2) + std::pow(yPosCenter - 361.5, 2));
126  }
127  if (boundingBox.Class == "bicycle") {
128  detectedBicycle = true;
129  // std::cout << "centerErrorBicycle " << xPosCenter << ", " << yPosCenter << std::endl;
130  centerErrorBicycle = std::sqrt(std::pow(xPosCenter - 338.0, 2) + std::pow(yPosCenter - 289.0, 2));
131  }
132  if (boundingBox.Class == "truck") {
133  detectedCar = true;
134  // std::cout << "centerErrorCar " << xPosCenter << ", " << yPosCenter << std::endl;
135  centerErrorCar = std::sqrt(std::pow(xPosCenter - 561.0, 2) + std::pow(yPosCenter - 126.5, 2));
136  }
137  }
138 
139  ASSERT_TRUE(detectedDog);
140  EXPECT_LT(centerErrorDog, 40.0);
141  ASSERT_TRUE(detectedBicycle);
142  EXPECT_LT(centerErrorBicycle, 40.0);
143  ASSERT_TRUE(detectedCar);
144  EXPECT_LT(centerErrorCar, 40.0);
145 }
146 
147 TEST(ObjectDetection, DetectANYmal) {
148  srand(static_cast<unsigned int>(time(nullptr)));
149  ros::NodeHandle nodeHandle("~");
150 
151  // Path to test image.
152  std::string pathToTestImage = ros::package::getPath("darknet_ros");
153  pathToTestImage += "/doc/";
154  pathToTestImage += "quadruped_anymal_and_person";
155  pathToTestImage += ".JPG";
156 
157  // Send ANYmal and person image to yolo.
158  ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
159  ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
160  ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
161 
162  // Evaluate if yolo was able to detect the three objects: dog, bicycle and car.
163  bool detectedPerson = false;
164  double centerErrorPersonX;
165  double centerErrorPersonY;
166 
167  for (auto& boundingBox : boundingBoxesResults_.bounding_boxes) {
168  double xPosCenter = boundingBox.xmin + (boundingBox.xmax - boundingBox.xmin) * 0.5;
169  double yPosCenter = boundingBox.ymin + (boundingBox.ymax - boundingBox.ymin) * 0.5;
170 
171  if (boundingBox.Class == "person") {
172  detectedPerson = true;
173  centerErrorPersonX = std::sqrt(std::pow(xPosCenter - 1650.0, 2));
174  centerErrorPersonY = std::sqrt(std::pow(xPosCenter - 1675.0, 2));
175  }
176  }
177 
178  ASSERT_TRUE(detectedPerson);
179  EXPECT_LT(centerErrorPersonX, 30);
180  EXPECT_LT(centerErrorPersonY, 30);
181 }
182 
183 TEST(ObjectDetection, DISABLED_DetectPerson) {
184  srand(static_cast<unsigned int>(time(nullptr)));
185  ros::NodeHandle nodeHandle("~");
186 
187  // Path to test image.
188  std::string pathToTestImage = darknetFilePath_;
189  pathToTestImage += "/data/";
190  pathToTestImage += "person";
191  pathToTestImage += ".jpg";
192 
193  ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
194  ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
195 
196  // Evaluate if yolo was able to detect the person.
197  bool detectedPerson = false;
198  double centerErrorPerson;
199 
200  for (auto& boundingBox : boundingBoxesResults_.bounding_boxes) {
201  double xPosCenter = boundingBox.xmin + (boundingBox.xmax - boundingBox.xmin) * 0.5;
202  double yPosCenter = boundingBox.ymin + (boundingBox.ymax - boundingBox.ymin) * 0.5;
203 
204  if (boundingBox.Class == "person") {
205  detectedPerson = true;
206  // std::cout << "centerErrorPerson " << xPosCenter << ", " << yPosCenter << std::endl;
207  centerErrorPerson = std::sqrt(std::pow(xPosCenter - 228.0, 2) + std::pow(yPosCenter - 238.0, 2));
208  }
209  }
210 
211  ASSERT_TRUE(detectedPerson);
212  EXPECT_LT(centerErrorPerson, 40.0);
213 }
TEST(ObjectDetection, DISABLED_DetectDog)
boost::function< void(const FeedbackConstPtr &feedback)> SimpleFeedbackCallback
bool sendImageToYolo(ros::NodeHandle nh, const std::string &pathToTestImage)
boost::function< void()> SimpleActiveCallback
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ROSLIB_DECL std::string getPath(const std::string &package_name)
actionlib::SimpleActionClient< darknet_ros_msgs::CheckForObjectsAction > CheckForObjectsActionClient
void checkForObjectsResultCB(const actionlib::SimpleClientGoalState &state, const darknet_ros_msgs::CheckForObjectsResultConstPtr &result)
darknet_ros_msgs::BoundingBoxes boundingBoxesResults_
static Time now()
std::shared_ptr< CheckForObjectsActionClient > CheckForObjectsActionClientPtr


darknet_ros
Author(s): Marko Bjelonic
autogenerated on Wed May 5 2021 02:58:30