ncs_nodelet.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <string>
18 #include <vector>
19 
20 #include <boost/filesystem/operations.hpp>
21 #include <cv_bridge/cv_bridge.h>
23 #include <opencv2/opencv.hpp>
25 #include <sensor_msgs/RegionOfInterest.h>
26 #include <object_msgs/Objects.h>
27 #include <object_msgs/ObjectsInBoxes.h>
31 
36 
37 namespace movidius_ncs_stream
38 {
40  : ncs_manager_handle_(nullptr)
41  , nh_(nh)
42  , pnh_(pnh)
43  , max_device_number_(255)
44  , start_device_index_(0)
45  , log_level_(Device::Errors)
46  , cnn_type_("")
47  , graph_file_path_("")
48  , category_file_path_("")
49  , network_dimension_(0)
50  , mean_(0)
51  , scale_(1.0)
52  , top_n_(1)
53 {
54  getParameters();
55  init();
56 }
57 
59 {
60 }
61 
63 {
64  ROS_DEBUG("NCSImpl get parameters");
65 
66  if (!pnh_.getParam("max_device_number", max_device_number_))
67  {
68  ROS_WARN("param max_device_number not set, use default");
69  }
70 
71  if (max_device_number_ <= 0)
72  {
73  ROS_ERROR_STREAM("invalid param max_device_number = " << max_device_number_);
74  throw std::exception();
75  }
76 
77  ROS_INFO_STREAM("use max_device_number = " << max_device_number_);
78 
79  if (!pnh_.getParam("start_device_index", start_device_index_))
80  {
81  ROS_WARN("param start_device_index not set, use default");
82  }
83 
84  if (start_device_index_ < 0)
85  {
86  ROS_ERROR_STREAM("invalid param start_device_index = " << start_device_index_);
87  throw std::exception();
88  }
89 
90  ROS_INFO_STREAM("use start_device_index = " << start_device_index_);
91 
92  if (!pnh_.getParam("log_level", log_level_))
93  {
94  ROS_WARN("param log_level not set, use default");
95  }
96 
97  if (log_level_ < Device::Nothing || log_level_ > Device::Verbose)
98  {
99  ROS_WARN_STREAM("invalid param log_level = " << log_level_);
100  throw std::exception();
101  }
102 
103  ROS_INFO_STREAM("use log_level = " << log_level_);
104 
105  if (!pnh_.getParam("graph_file_path", graph_file_path_))
106  {
107  ROS_WARN("param graph_file_path not set, use default");
108  }
109 
110  if (!boost::filesystem::exists(graph_file_path_))
111  {
112  ROS_ERROR_STREAM("graph_file_path = " << graph_file_path_ << " not exists");
113  throw std::exception();
114  }
115 
116  ROS_INFO_STREAM("use graph_file_path = " << graph_file_path_);
117 
118  if (!pnh_.getParam("category_file_path", category_file_path_))
119  {
120  ROS_WARN("param category_file_path not set, use default");
121  }
122 
123  if (!boost::filesystem::exists(category_file_path_))
124  {
125  ROS_ERROR_STREAM("category_file_path = " << category_file_path_ << " not exists");
126  throw std::exception();
127  }
128 
129  ROS_INFO_STREAM("use category_file_path = " << category_file_path_);
130 
131  if (!pnh_.getParam("cnn_type", cnn_type_))
132  {
133  ROS_WARN("param cnn_type not set, use default");
134  }
135 
136  if (cnn_type_.compare("alexnet") && cnn_type_.compare("googlenet") && cnn_type_.compare("inception_v1") &&
137  cnn_type_.compare("inception_v2") && cnn_type_.compare("inception_v3") && cnn_type_.compare("inception_v4") &&
138  cnn_type_.compare("mobilenet") && cnn_type_.compare("squeezenet") && cnn_type_.compare("tinyyolo_v1") &&
139  cnn_type_.compare("mobilenetssd"))
140  {
141  ROS_WARN_STREAM("invalid cnn_type_=" << cnn_type_);
142  throw std::exception();
143  }
144 
145  ROS_INFO_STREAM("use cnn_type_ = " << cnn_type_);
146 
147  if (!pnh_.getParam("network_dimension", network_dimension_))
148  {
149  ROS_WARN("param network_dimension not set, use default");
150  }
151 
152  if (network_dimension_ < 0)
153  {
154  ROS_WARN_STREAM("invalid network_dimension = " << network_dimension_);
155  throw std::exception();
156  }
157 
158  ROS_INFO_STREAM("use network_dimension = " << network_dimension_);
159 
160  for (int i = 0; i < 3; i++)
161  {
162  std::ostringstream oss;
163  oss << "channel" << (i + 1) << "_mean";
164  std::string mean_param_name = oss.str();
165  float mean_val;
166  if (!pnh_.getParam(mean_param_name, mean_val))
167  {
168  ROS_WARN_STREAM("param " << mean_param_name << "not set, use default");
169  }
170  ROS_INFO_STREAM("use " << mean_param_name << " = " << mean_val);
171  mean_.push_back(mean_val);
172  }
173 
174  if (!pnh_.getParam("top_n", top_n_))
175  {
176  ROS_WARN("param top_n not set, use default");
177  }
178 
179  if (top_n_ < 1)
180  {
181  ROS_WARN_STREAM("invalid top_n = " << top_n_);
182  throw std::exception();
183  }
184 
185  ROS_INFO_STREAM("use top_n = " << top_n_);
186 
187  if (!pnh_.getParam("scale", scale_))
188  {
189  ROS_WARN("param scale not set, use default");
190  }
191  if (scale_ < 0)
192  {
193  ROS_WARN_STREAM("invalid param scale = " << scale_);
194  throw std::exception();
195  }
196 
197  ROS_INFO_STREAM("use scale = " << scale_);
198 }
199 
201 {
202  ROS_DEBUG("NCSImpl onInit");
203 
204  ncs_manager_handle_ = std::make_shared<movidius_ncs_lib::NCSManager>(
207 
208  std::shared_ptr<ImageTransport> it = std::make_shared<ImageTransport>(nh_);
209 
210  if (!cnn_type_.compare("alexnet") || !cnn_type_.compare("googlenet") || !cnn_type_.compare("inception_v1") ||
211  !cnn_type_.compare("inception_v2") || !cnn_type_.compare("inception_v3") || !cnn_type_.compare("inception_v4") ||
212  !cnn_type_.compare("mobilenet") || !cnn_type_.compare("squeezenet"))
213  {
214  sub_ = it->subscribe("/camera/rgb/image_raw", 1, &NCSImpl::cbClassify, this);
215  pub_ = nh_.advertise<object_msgs::Objects>("classified_objects", 1);
216  }
217  else
218  {
219  sub_ = it->subscribe("/camera/rgb/image_raw", 1, &NCSImpl::cbDetect, this);
220  pub_ = nh_.advertise<object_msgs::ObjectsInBoxes>("detected_objects", 1);
221  }
222 
223  ncs_manager_handle_->startThreads();
224 }
225 
226 void NCSImpl::cbClassify(const sensor_msgs::ImageConstPtr& image_msg)
227 {
228  if (pub_.getNumSubscribers() == 0)
229  {
230  ROS_DEBUG_STREAM("skip inferring for no subscriber");
231  return;
232  }
233 
234  cv::Mat camera_data = cv_bridge::toCvCopy(image_msg, "bgr8")->image;
235 
236  FUNP_C classification_result_callback = boost::bind(&NCSImpl::cbGetClassificationResult, this, _1, _2);
237  ncs_manager_handle_->classifyStream(camera_data, classification_result_callback, image_msg);
238 }
239 
240 void NCSImpl::cbDetect(const sensor_msgs::ImageConstPtr& image_msg)
241 {
242  if (pub_.getNumSubscribers() == 0)
243  {
244  ROS_DEBUG_STREAM("skip inferring for no subscriber");
245  return;
246  }
247 
248  cv::Mat camera_data = cv_bridge::toCvCopy(image_msg, "bgr8")->image;
249 
250  FUNP_D detection_result_callback = boost::bind(&NCSImpl::cbGetDetectionResult, this, _1, _2);
251  ncs_manager_handle_->detectStream(camera_data, detection_result_callback, image_msg);
252 }
253 
255 {
256 }
257 
259 {
260  object_msgs::Objects objs;
261 
262  for (auto item : result->items)
263  {
264  object_msgs::Object obj;
265  obj.object_name = item.category;
266  obj.probability = item.probability;
267  objs.objects_vector.push_back(obj);
268  }
269 
270  objs.header = header;
271  objs.inference_time_ms = result->time_taken;
272  pub_.publish(objs);
273 }
274 
276 {
277  object_msgs::ObjectsInBoxes objs_in_boxes;
278 
279  for (auto item : result->items_in_boxes)
280  {
281  object_msgs::ObjectInBox obj;
282  obj.object.object_name = item.item.category;
283  obj.object.probability = item.item.probability;
284  obj.roi.x_offset = item.bbox.x;
285  obj.roi.y_offset = item.bbox.y;
286  obj.roi.width = item.bbox.width;
287  obj.roi.height = item.bbox.height;
288  objs_in_boxes.objects_vector.push_back(obj);
289  }
290 
291  objs_in_boxes.header = header;
292  objs_in_boxes.inference_time_ms = result->time_taken;
293 
294  pub_.publish(objs_in_boxes);
295 }
296 
298 {
299  ros::NodeHandle nh = getNodeHandle();
300  ros::NodeHandle pnh = getPrivateNodeHandle();
301  try
302  {
303  impl_.reset(new NCSImpl(nh, pnh));
304  }
306  {
307  ROS_ERROR_STREAM("Error: " << e.what());
308  ros::shutdown();
309  }
310  catch (...)
311  {
312  ROS_ERROR("exception caught while starting NCSNodelet");
313  ros::shutdown();
314  }
315 }
316 
317 } // namespace movidius_ncs_stream
318 
std::vector< float > mean_
Definition: ncs_nodelet.h:65
std::shared_ptr< DetectionResult > DetectionResultPtr
void publish(const boost::shared_ptr< M > &message) const
PLUGINLIB_EXPORT_CLASS(movidius_ncs_stream::NCSNodelet, nodelet::Nodelet)
boost::function< void(movidius_ncs_lib::DetectionResultPtr result, std_msgs::Header header)> FUNP_D
Definition: ncs_nodelet.h:34
const char * what() const noexcept
#define ROS_WARN(...)
NCSImpl(ros::NodeHandle &nh, ros::NodeHandle &pnh)
Definition: ncs_nodelet.cpp:39
void cbGetClassificationResult(movidius_ncs_lib::ClassificationResultPtr result, std_msgs::Header header)
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
void cbGetDetectionResult(movidius_ncs_lib::DetectionResultPtr result, std_msgs::Header header)
boost::function< void(movidius_ncs_lib::ClassificationResultPtr result, std_msgs::Header header)> FUNP_C
Definition: ncs_nodelet.h:33
std::shared_ptr< ClassificationResult > ClassificationResultPtr
uint32_t getNumSubscribers() const
#define ROS_INFO_STREAM(args)
bool getParam(const std::string &key, std::string &s) const
ROSCPP_DECL void shutdown()
void cbClassify(const sensor_msgs::ImageConstPtr &image)
void cbDetect(const sensor_msgs::ImageConstPtr &image)
#define ROS_ERROR_STREAM(args)
image_transport::Subscriber sub_
Definition: ncs_nodelet.h:54
#define ROS_ERROR(...)
#define ROS_DEBUG(...)
std::shared_ptr< movidius_ncs_lib::NCSManager > ncs_manager_handle_
Definition: ncs_nodelet.h:51


movidius_ncs_stream
Author(s): Xiaojun Huang
autogenerated on Mon Jun 10 2019 14:11:28