Go to the documentation of this file.00001
00060 #pragma once
00061
00062
00063 #include <ros/ros.h>
00064
00065
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
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
00088 for (int head = 0; head < (int)head_bounding_boxes.size(); head++)
00089 {
00090 if (face_bounding_boxes[head].size() == 0)
00091 {
00092
00093 cob_perception_msgs::Detection det;
00094 const cv::Rect& head_bb = head_bounding_boxes[head];
00095
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
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
00110 det.label = "UnknownHead";
00111
00112 det.detector = "head";
00113
00114 det.header = msg_header;
00115
00116 detection_msg.detections.push_back(det);
00117 }
00118 else
00119 {
00120
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
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
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
00142 if (identification_labels!=0 && identification_labels->size()>head)
00143 det.label = (*identification_labels)[head][face];
00144 else
00145 det.label = "Unknown";
00146
00147 det.detector = "face";
00148
00149 det.header = msg_header;
00150
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
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 };