40 #include "dnn_detect/DetectedObject.h" 41 #include "dnn_detect/DetectedObjectArray.h" 42 #include "dnn_detect/Detect.h" 44 #include <opencv2/highgui.hpp> 45 #include <opencv2/dnn.hpp> 46 #include <opencv2/calib3d.hpp> 50 #include <boost/algorithm/string.hpp> 51 #include <boost/format.hpp> 55 #include <condition_variable> 60 std::condition_variable
cond;
95 bool trigger_callback(dnn_detect::Detect::Request &req,
96 dnn_detect::Detect::Response &res);
98 void image_callback(
const sensor_msgs::ImageConstPtr &msg);
105 dnn_detect::Detect::Response &res)
110 std::unique_lock<std::mutex> lock(
mutx);
115 res.result = results;
123 if (single_shot && !triggered) {
128 ROS_INFO(
"Got image %d", msg->header.seq);
136 int w = cv_ptr->image.cols;
137 int h = cv_ptr->image.rows;
139 if (rotate_flag >= 0) {
140 cv::rotate(cv_ptr->image, rotated_image, rotate_flag);
141 rotated_image.copyTo(cv_ptr->image);
144 cv::resize(cv_ptr->image, resized_image, cvSize(im_size, im_size));
145 cv::Mat blob = cv::dnn::blobFromImage(resized_image, scale_factor,
146 cvSize(im_size, im_size), mean_val,
false);
148 net.setInput(blob,
"data");
149 cv::Mat objs = net.forward(
"detection_out");
151 cv::Mat detectionMat(objs.size[2], objs.size[3], CV_32F,
154 std::unique_lock<std::mutex> lock(
mutx);
155 results.header.frame_id = msg->header.frame_id;
156 results.objects.clear();
158 for(
int i = 0; i < detectionMat.rows; i++) {
160 float confidence = detectionMat.at<
float>(i, 2);
161 if (confidence > min_confidence) {
162 int object_class = (int)(detectionMat.at<
float>(i, 1));
164 int x_min =
static_cast<int>(detectionMat.at<
float>(i, 3) * w);
165 int y_min =
static_cast<int>(detectionMat.at<
float>(i, 4) * h);
166 int x_max =
static_cast<int>(detectionMat.at<
float>(i, 5) * w);
167 int y_max =
static_cast<int>(detectionMat.at<
float>(i, 6) * h);
169 std::string class_name;
170 if (object_class >= class_names.size()) {
171 class_name =
"unknown";
172 ROS_ERROR(
"Object class %d out of range of class names",
176 class_name = class_names[object_class];
178 std::string label = str(boost::format{
"%1% %2%"} %
179 class_name % confidence);
182 dnn_detect::DetectedObject obj;
183 obj.class_name = class_name;
184 obj.confidence = confidence;
189 results.objects.push_back(obj);
191 Rect object(x_min, y_min, x_max-x_min, y_max-y_min);
193 rectangle(cv_ptr->image,
object, Scalar(0, 255, 0));
195 cv::Size text_size = cv::getTextSize(label,
196 FONT_HERSHEY_SIMPLEX, 0.75, 2, &baseline);
197 putText(cv_ptr->image, label, Point(x_min, y_min-text_size.height),
198 FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 255, 0));
202 results_pub.publish(results);
204 image_pub.publish(cv_ptr->toImageMsg());
208 ROS_ERROR(
"cv_bridge exception: %s", e.what());
210 catch(cv::Exception & e) {
213 ROS_DEBUG(
"Notifying condition variable");
223 std::string proto_net_file;
224 std::string caffe_model_file;
225 std::string classes(
"background," 226 "aeroplane,bicycle,bird,boat,bottle,bus,car,cat,chair," 227 "cow,diningtable,dog,horse,motorbike,person,pottedplant," 228 "sheep,sofa,train,tvmonitor");
233 nh.
param<
string>(
"data_dir", dir,
"");
234 nh.
param<
string>(
"protonet_file", proto_net_file,
235 "MobileNetSSD_deploy.prototxt.txt");
236 nh.
param<
string>(
"caffe_model_file", caffe_model_file,
237 "MobileNetSSD_deploy.caffemodel");
243 nh.
param<std::string>(
"class_names", classes, classes);
245 boost::split(
class_names, classes, boost::is_any_of(
","));
249 net = cv::dnn::readNetFromCaffe(dir +
"/" + proto_net_file,
250 dir +
"/" + caffe_model_file);
252 catch(cv::Exception & e) {
262 nh.
advertise<dnn_detect::DetectedObjectArray>(
"/dnn_objects", 20);
272 int main(
int argc,
char ** argv) {
image_transport::Publisher image_pub
Subscriber subscribe(const std::string &base_topic, uint32_t queue_size, const boost::function< void(const sensor_msgs::ImageConstPtr &)> &callback, const ros::VoidPtr &tracked_object=ros::VoidPtr(), const TransportHints &transport_hints=TransportHints())
dnn_detect::DetectedObjectArray results
ros::ServiceServer detect_srv
int main(int argc, char **argv)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Publisher advertise(const std::string &base_topic, uint32_t queue_size, bool latch=false)
DnnNode(ros::NodeHandle &nh)
image_transport::ImageTransport it
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void image_callback(const sensor_msgs::ImageConstPtr &msg)
std::vector< std::string > class_names
image_transport::Subscriber img_sub
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
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)
std::condition_variable cond
virtual void spin(CallbackQueue *queue=0)
bool trigger_callback(dnn_detect::Detect::Request &req, dnn_detect::Detect::Response &res)
ros::Publisher results_pub