FaceContourRequestHandler.cpp
Go to the documentation of this file.
00001 #include <face_contour_detector/FaceContourRequestHandler.h>
00002 
00003 //
00004 #include <opencv/cv.h>
00005 #include <opencv/highgui.h>
00006 #include <sensor_msgs/Image.h>
00007 #include <cv_bridge/CvBridge.h>
00008 #include <image_transport/image_transport.h>
00009 
00010 //service definitions
00011 #include <face_contour_detector/GetFilters.h>
00012 #include <face_contour_detector/ApplyFilters.h>
00013 #include <face_contour_detector/autoselect_result.h>
00014 #include <face_contour_detector/ContourDetectorGUI.h>
00015 #include <face_contour_detector/experience_request.h>
00016 #include <face_contour_detector/filters/MaskBlur.h>
00017 
00018 #include <portrait_robot_msgs/alubsc_node_instr.h>
00019 #include <portrait_robot_msgs/alubsc_status_msg.h>
00020 
00021 //tinyxml
00022 #include <tinyxml/tinyxml.h>
00023 
00024 //
00025 #include <face_contour_detector/AutoParameterExplorer.h>
00026 #include <boost/function.hpp>
00027 #include <face_contour_detector/AreaParameterChooserWorker.h>
00028 
00029 namespace face_contour_detector {
00030 
00031 FaceContourRequestHandler::FaceContourRequestHandler(ros::NodeHandle& node,
00032                 std::string exploreConfigPath) :
00033                 node(node), exploreConfigPath(exploreConfigPath) {
00034 }
00035 FaceContourRequestHandler::~FaceContourRequestHandler() {
00036         while (!requests.empty()) {
00037                 delete requests.front().image;
00038                 delete requests.front().mask;
00039                 requests.pop();
00040         }
00041 }
00042 
00043 void FaceContourRequestHandler::SolveOneRequest() {
00044         if (!requests.empty()) {
00045                 //load latest request
00046 
00047                 cv::Mat* currentImg = requests.front().image;
00048                 cv::Mat* currentMask = requests.front().mask;
00049 
00050                 requests.pop();
00051 
00052                 M_SendStatusMessage("Blurring around masked areas");
00053 
00054                 //Apply MaskBlur filter
00055                 cv::Mat* maskedImage = new cv::Mat(currentImg->rows, currentImg->cols,
00056                                 CV_8UC3);
00057                 {
00058                         //setting the clearcolor to white
00059                         face_contour_detector::Bgr8 clearcolor;
00060                         clearcolor.b = 255;
00061                         clearcolor.g = 255;
00062                         clearcolor.r = 255;
00063                         face_contour_detector::filters::MaskBlur mb =
00064                                         face_contour_detector::filters::MaskBlur(10, clearcolor);
00065                         //mask to gray scale image
00066                         cv::Mat bwMask = cv::Mat(currentMask->rows, currentMask->cols,
00067                                         CV_8UC1);
00068                         cv::cvtColor(*currentMask, bwMask, CV_BGR2GRAY);
00069                         mb.SetMask(bwMask, 0, 255);
00070                         //apply the BLUUUURIIIING
00071                         mb.Apply(*currentImg, *maskedImage);
00072                         //cleaning up and setting the pointer
00073                         delete currentImg;
00074                         currentImg = maskedImage;
00075                         cv::imwrite("parameter_autoselect_bluredImage.png", *currentImg);
00076                 }
00077 
00078                 M_SendStatusMessage("starting exploration for good parameters...");
00079 
00080                 //save the results here
00081                 std::vector<face_contour_detector::autoselect_result> result;
00082 
00083                 //worker 1
00084                 std::vector<WorkerSetting> settings;
00085                 M_LoadExploreSettings(settings);
00086 
00087                 std::vector<WorkerSetting>::iterator setIt;
00088                 int i = 1;
00089                 for (setIt = settings.begin(); setIt != settings.end(); setIt++) {
00090                         face_contour_detector::AreaParameterChooserWorker worker(node,
00091                                         *currentImg, *currentMask, setIt->targetValues);
00092                         worker.CallculateParameters(setIt->numResults, setIt->steps,
00093                                         result);
00094 
00095                         if (result.size() < setIt->numResults) {
00096                                 ROS_ERROR("did not get enough results for the request");
00097                                 M_SendStatusMessage(
00098                                                 "did not get enough results for the request, please try to send a better image");
00099                                 delete currentImg;
00100                                 delete currentMask;
00101                                 return;
00102                         } else {
00103                                 std::stringstream sstr;
00104                                 sstr << "found " << result.size()
00105                                                 << " parameter combination(s) by exploring with worker "
00106                                                 << i;
00107                                 M_SendStatusMessage(sstr.str());
00108                         }
00109                         i++;
00110                 }
00111 
00112                 /*int steps = 15;
00113                  std::map<std::string, std::map<std::string, double> > targetValue;
00114                  targetValue["LeftEye"]["graphmass"] = 0.35;
00115                  targetValue["RightEye"]["graphmass"] = 0.35;
00116                  targetValue["Nose"]["graphmass"] = 0.35;
00117                  targetValue["Mouth"]["graphmass"] = 0.35;
00118                  targetValue["Complete Face"]["graphmass"] = 0.25;
00119 
00120                  */
00121 
00122                 M_SendStatusMessage(
00123                                 "try to find parameters by searching rated results...");
00124 
00125                 //sending to the next selector
00126                 ros::ServiceClient exprClient = node.serviceClient<
00127                                 face_contour_detector::experience_request>(
00128                                 "experience_autoselector");
00129                 face_contour_detector::experience_request exprSrv;
00130 
00131                 cv::Mat imgCopy = currentImg->clone();
00132                 cv::Mat maskCopy = currentMask->clone();
00133 
00134                 try {
00135                         sensor_msgs::CvBridge cvBridge;
00136                         IplImage ipl = imgCopy;
00137                         exprSrv.request.image = *(cvBridge.cvToImgMsg(&ipl));
00138 
00139                 } catch (sensor_msgs::CvBridgeException& error) {
00140                         ROS_ERROR(
00141                                         "could not convert the image with the cvBridge to a sensor_msgs/Image");
00142                         return;
00143                 }
00144 
00145                 try {
00146                         sensor_msgs::CvBridge cvBridge;
00147                         IplImage ipl = maskCopy;
00148                         exprSrv.request.mask = *(cvBridge.cvToImgMsg(&ipl));
00149 
00150                 } catch (sensor_msgs::CvBridgeException& error) {
00151                         ROS_ERROR(
00152                                         "could not convert the image with the cvBridge to a sensor_msgs/Image");
00153                         return;
00154                 }
00155 
00156                 if (exprClient.call(exprSrv)) {
00157                         std::vector<face_contour_detector::autoselect_result>::iterator it;
00158                         for (it = exprSrv.response.proposals.begin();
00159                                         it != exprSrv.response.proposals.end(); it++) {
00160                                 result.push_back(*it);
00161                         }
00162                         M_SendStatusMessage(
00163                                         "received experience based parameter combinations");
00164                 } else {
00165                         ROS_WARN(
00166                                         "Could not reach the experience based autoparameter chooser");
00167                 }
00168 
00169                 //worker 2
00170                 /*std::map<std::string, std::map<std::string, double> > targetValue2;
00171                  targetValue2["Complete Face"]["graphmass"] = 0.4;
00172 
00173                  AreaParameterChooserWorker worker2(node, *currentImg, *currentMask, targetValue2);
00174                  worker2.CallculateParameters(2, steps, result);
00175 
00176                  if (result.size() < 4) {
00177                  ROS_ERROR("did not get enough results for the request (worker2)");
00178                  M_SendStatusMessage("did not get enough results for the request, please try to make another image");
00179                  delete currentImg;
00180                  delete currentMask;
00181                  return;
00182                  }*/
00183 
00184                 //generate gui request
00185                 std::string topic = "display_on_gui";
00186                 ros::ServiceClient client = node.serviceClient<
00187                                 face_contour_detector::ContourDetectorGUI>(topic);
00188                 face_contour_detector::ContourDetectorGUI srv;
00189                 srv.request.proposals = result;
00190                 ROS_INFO("gui service request send");
00191                 M_SendStatusMessage("opening gui...");
00192                 if (client.call(srv)) {
00193                         ROS_INFO("gui respondet");
00194 
00195                         //ok lets send a anwser to glados
00196                         /*ros::ServiceClient resClient = node.serviceClient<portrait_robot_msgs::alubsc_node_instr>("/alubsc/edge_image");
00197                          portrait_robot_msgs::alubsc_node_instr resSrv;
00198                          resSrv.request.images.push_back(srv.response.result);
00199                          resSrv.request.abort = false;
00200 
00201                          if (resClient.call(resSrv)) {
00202                          ROS_INFO("Response send");
00203                          } else  {
00204                          ROS_INFO("could not reach response service");
00205                          }*/
00206 
00207                 } else {
00208                         ROS_ERROR("Failed to call service %s", topic.c_str());
00209                 }
00210                 M_SendStatusMessage("done");
00211 
00212                 //ImageMaskPair dummyP;
00213                 //dummyP.image = currentImg;
00214                 //dummyP.mask = currentMask;
00215 
00216                 //StaticResponse(dummyP);
00217 
00218                 //delete image data
00219                 delete currentImg;
00220                 delete currentMask;
00221 
00222                 ROS_INFO("solved a request");
00223         }
00224 }
00225 
00226 bool FaceContourRequestHandler::HandleAlubscRequest(
00227                 portrait_robot_msgs::alubsc_node_instr::Request &req,
00228                 portrait_robot_msgs::alubsc_node_instr::Response &res) {
00229         if (req.abort) {
00231                 M_SendStatusMessage("received abort");
00232         } else {
00233                 std::vector<sensor_msgs::Image>::const_iterator it;
00234                 ImageMaskPair p;
00235                 p.image = 0;
00236                 p.mask = 0;
00237                 int i = 0;
00238                 for (it = req.images.begin(); it != req.images.end(); it++) {
00239                         if (i > 1) {
00240                                 ROS_ERROR("More than two images in the message");
00241                                 res.success = false;
00242                                 return false;
00243                         }
00244                         try {
00245 
00246                                 sensor_msgs::CvBridge cvBridge;
00248                                 if (!cvBridge.fromImage(*it, "bgr8"))
00249                                         throw sensor_msgs::CvBridgeException(
00250                                                         "Conversion to OpenCV image failed");
00251                                 ;ROS_INFO(
00252                                                 "got image with widht=%i and height=%i", it->width, it->height);
00253                                 if (i == 0) {
00254                                         p.image = new cv::Mat(cvBridge.toIpl(), true);
00255                                 } else if (i == 1) {
00256                                         p.mask = new cv::Mat(cvBridge.toIpl(), true);
00257                                 }
00258                                 //cv::imwrite("filter_services_req_in.png", inputImage);
00259                         } catch (sensor_msgs::CvBridgeException& error) {
00260                                 ROS_ERROR(
00261                                                 "could not convert the image with the cvBridge to a cv::Mat");
00262                                 res.success = false;
00263                                 return false;
00264                         }
00265                         i++;
00266                 }
00267                 if (p.image == 0) {
00268                         ROS_ERROR("no image received");
00269                         res.success = false;
00270                         return false;
00271                 }
00272                 if (p.mask == 0) {
00273                         ROS_ERROR("no mask received");
00274                         res.success = false;
00275                         return false;
00276                 }
00277                 requests.push(p);
00278                 res.success = true;
00279         }
00280         return true;
00281 }
00282 
00283 void FaceContourRequestHandler::M_SendStatusMessage(
00284                 const std::string& message) {
00285         ros::ServiceClient client = node.serviceClient<
00286                         portrait_robot_msgs::alubsc_status_msg>("status_msg");
00287         portrait_robot_msgs::alubsc_status_msg srv;
00288         srv.request.ID = 2;
00289         srv.request.message = message;
00290         if (!client.call(srv)) {
00291                 ROS_WARN(
00292                                 "could not reach status message service \"%s\"", client.getService().c_str());
00293                 ROS_INFO("%s", message.c_str());
00294         }
00295 }
00296 
00297 void FaceContourRequestHandler::M_LoadExploreSettings(
00298                 std::vector<WorkerSetting>& settings) {
00299         TiXmlDocument doc(exploreConfigPath.c_str());
00300         if (!doc.LoadFile()) {
00301                 ROS_ERROR("Could not load the explore_settings xml config file");
00302                 M_SendStatusMessage(
00303                                 "Could not load the explore_settings xml config file");
00304                 return;
00305         }
00306         TiXmlElement* root = doc.RootElement();
00307         for (TiXmlElement* worker = root->FirstChildElement("worker"); worker;
00308                         worker = worker->NextSiblingElement("worker")) {
00309                 //check tag name
00310                 WorkerSetting setting;
00311                 if (worker->Attribute("steps")) {
00312                         setting.steps = atoi(worker->Attribute("steps"));
00313                 } else {
00314                         setting.steps = 15;
00315                 }
00316                 if (worker->Attribute("numresults")) {
00317                         setting.numResults = atoi(worker->Attribute("numresults"));
00318                 } else {
00319                         setting.numResults = 2;
00320                 }
00321                 for (TiXmlElement* area = worker->FirstChildElement("area"); area;
00322                                 area = area->NextSiblingElement("area")) {
00323                         if (area->Attribute("name")) {
00324                                 setting.targetValues[area->Attribute("name")] = std::map<
00325                                                 std::string, double>();
00326                                 for (TiXmlElement* targetValue = area->FirstChildElement(
00327                                                 "target_value");
00328                                                 targetValue;
00329                                                 targetValue = targetValue->NextSiblingElement(
00330                                                                 "target_value")) {
00331                                         if (targetValue->Attribute("name")
00332                                                         && targetValue->Attribute("value")) {
00333                                                 setting.targetValues[area->Attribute("name")][targetValue->Attribute(
00334                                                                 "name")] = atof(
00335                                                                 targetValue->Attribute("value"));
00336                                         }
00337                                 }
00338                         }
00339                 }
00340                 settings.push_back(setting);
00341         }
00342 }
00343 
00344 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends


face_contour_detector
Author(s): Fabian Wenzelmann and Julian Schmid
autogenerated on Wed Dec 26 2012 16:18:17