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) {