face_detection_message_helper.h
Go to the documentation of this file.
00001 
00060 #pragma once
00061 
00062 // ROS includes
00063 #include <ros/ros.h>
00064 
00065 // ROS message includes
00066 #include <sensor_msgs/Image.h>
00067 #include <geometry_msgs/Point.h>
00068 #include <cob_perception_msgs/DetectionArray.h>
00069 #include <cob_perception_msgs/ColorDepthImageArray.h>
00070 
00071 // opencv
00072 #include <opencv2/opencv.hpp>
00073 
00074 #include <vector>
00075 
00076 
00077 class FaceDetectionMessageHelper
00078 {
00079 public:
00080 
00081         void prepareCartesionDetectionMessage(cob_perception_msgs::DetectionArray& detection_msg, const std_msgs::Header& msg_header,
00082                         const std::vector<cv::Mat>& heads_depth_images, const std::vector<cv::Rect>& head_bounding_boxes,
00083                         const std::vector<std::vector<cv::Rect> >& face_bounding_boxes, const std::vector<std::vector<std::string> >* identification_labels=0)
00084         {
00085                 detection_msg.header = msg_header;
00086 
00087                 // prepare message
00088                 for (int head = 0; head < (int)head_bounding_boxes.size(); head++)
00089                 {
00090                         if (face_bounding_boxes[head].size() == 0)
00091                         {
00092                                 // no faces detected in head region -> publish head position
00093                                 cob_perception_msgs::Detection det;
00094                                 const cv::Rect& head_bb = head_bounding_boxes[head];
00095                                 // set 3d position of head's center
00096                                 bool valid_3d_position = determine3DFaceCoordinates(heads_depth_images[head], 0.5 * (float)head_bb.width, 0.5 * (float)head_bb.height, det.pose.pose.position, 6);
00097                                 if (valid_3d_position == false)
00098                                         continue;
00099                                 det.pose.header = msg_header;
00100                                 det.pose.pose.orientation.x = 0.;
00101                                 det.pose.pose.orientation.y = 0.;
00102                                 det.pose.pose.orientation.z = 0.;
00103                                 det.pose.pose.orientation.w = 1.;
00104                                 // write bounding box
00105                                 det.mask.roi.x = head_bb.x;
00106                                 det.mask.roi.y = head_bb.y;
00107                                 det.mask.roi.width = head_bb.width;
00108                                 det.mask.roi.height = head_bb.height;
00109                                 // set label
00110                                 det.label = "UnknownHead";
00111                                 // set origin of detection
00112                                 det.detector = "head";
00113                                 // header
00114                                 det.header = msg_header;
00115                                 // add to message
00116                                 detection_msg.detections.push_back(det);
00117                         }
00118                         else
00119                         {
00120                                 // process all faces in head region
00121                                 for (int face = 0; face < (int)face_bounding_boxes[head].size(); face++)
00122                                 {
00123                                         cob_perception_msgs::Detection det;
00124                                         const cv::Rect& head_bb = head_bounding_boxes[head];
00125                                         const cv::Rect& face_bb = face_bounding_boxes[head][face];
00126                                         // set 3d position of head's center
00127                                         bool valid_3d_position = determine3DFaceCoordinates(heads_depth_images[head], face_bb.x + 0.5 * (float)face_bb.width, face_bb.y + 0.5 * (float)face_bb.height,
00128                                                         det.pose.pose.position, 6);
00129                                         if (valid_3d_position == false)
00130                                                 continue;
00131                                         det.pose.header = msg_header;
00132                                         det.pose.pose.orientation.x = 0.;
00133                                         det.pose.pose.orientation.y = 0.;
00134                                         det.pose.pose.orientation.z = 0.;
00135                                         det.pose.pose.orientation.w = 1.;
00136                                         // write bounding box
00137                                         det.mask.roi.x = head_bb.x + face_bb.x;
00138                                         det.mask.roi.y = head_bb.y + face_bb.y;
00139                                         det.mask.roi.width = face_bb.width;
00140                                         det.mask.roi.height = face_bb.height;
00141                                         // set label
00142                                         if (identification_labels!=0 && identification_labels->size()>head)
00143                                                 det.label = (*identification_labels)[head][face];
00144                                         else
00145                                                 det.label = "Unknown";
00146                                         // set origin of detection
00147                                         det.detector = "face";
00148                                         // header
00149                                         det.header = msg_header;
00150                                         // add to message
00151                                         detection_msg.detections.push_back(det);
00152                                 }
00153                         }
00154                 }
00155         }
00156 
00157 
00158         bool determine3DFaceCoordinates(const cv::Mat& depth_image, int center2Dx, int center2Dy, geometry_msgs::Point& center3D, int search_radius)
00159         {
00160                 // 3D world coordinates (and verify that the read pixel contained valid coordinates, otherwise search for valid pixel in neighborhood)
00161                 bool valid_coordinates = false;
00162                 for (int d = 0; (d < search_radius && !valid_coordinates); d++)
00163                 {
00164                         for (int v = -d; (v <= d && !valid_coordinates); v++)
00165                         {
00166                                 for (int u = -d; (u <= d && !valid_coordinates); u++)
00167                                 {
00168                                         if ((abs(v) != d && abs(u) != d) || center2Dx + u < 0 || center2Dx + u >= depth_image.cols || center2Dy + v < 0 || center2Dy + v >= depth_image.rows)
00169                                                 continue;
00170 
00171                                         const cv::Point3f& p = depth_image.at<cv::Point3f>(center2Dy + v, center2Dx + u);
00172                                         if (!isnan(p.x) && !isnan(p.y) && p.z != 0.f)
00173                                         {
00174                                                 valid_coordinates = true;
00175                                                 center3D.x = p.x;
00176                                                 center3D.y = p.y;
00177                                                 center3D.z = p.z;
00178                                         }
00179                                 }
00180                         }
00181                 }
00182                 return valid_coordinates;
00183         }
00184 };


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Mon May 6 2019 02:32:06