00001 #include <iostream>
00002 #include <sstream>
00003 #include <assert.h>
00004 #include <algorithm>
00005
00006 #include <ros/ros.h>
00007 #include <ros/package.h>
00008 #include <tf/tf.h>
00009 #include <image_transport/image_transport.h>
00010 #include <opencv/cv.h>
00011 #include <cv_bridge/CvBridge.h>
00012 #include <opencv2/imgproc/imgproc.hpp>
00013 #include <opencv2/highgui/highgui.hpp>
00014 #include <sensor_msgs/Image.h>
00015
00016 #include <ee_cart_imped_action/ee_cart_imped_arm.hh>
00017
00018 #include <portrait_painter/getLines.h>
00019 #include <portrait_painter/JobSubmission.h>
00020 #include <portrait_painter/Point2D.h>
00021 #include <portrait_robot_msgs/alubsc_node_instr.h>
00022 #include <portrait_robot_msgs/alubsc_status_msg.h>
00023 #include <portrait_painter/PainterUtils.h>
00024
00025 using namespace cv;
00026 using namespace std;
00027 using namespace portrait_painter;
00028
00029 int processImage(string filename);
00030 void portrait_painter::sendStatus(string message, ros::ServiceClient client);
00031 bool handleInstruction(portrait_robot_msgs::alubsc_node_instr::Request &req,
00032 portrait_robot_msgs::alubsc_node_instr::Response &res);
00033
00034
00035 bool jobScheduled;
00036 string jobFilename;
00037
00038 int main(int argc, char** argv) {
00039
00040 ros::init(argc, argv, "painter_lineExtractor");
00041
00042 jobScheduled = false;
00043
00044 ros::NodeHandle n;
00045 ros::ServiceServer InstructionServer = n.advertiseService(
00046 "/alubsc/node_instr/painter", handleInstruction);
00047 while (ros::ok()) {
00048 if (jobScheduled) {
00049 processImage(jobFilename);
00050 jobScheduled = false;
00051 }
00052 ros::spinOnce();
00053 }
00054
00055
00056
00057
00058 }
00059
00060
00061
00062
00063 bool handleInstruction(portrait_robot_msgs::alubsc_node_instr::Request &req,
00064 portrait_robot_msgs::alubsc_node_instr::Response &res) {
00065 string filename = ros::package::getPath("portrait_painter")
00066 + "/bin/contours.bmp";
00067
00068 try {
00069 sensor_msgs::CvBridge cvBridge;
00071 if (!cvBridge.fromImage(req.images[0], "mono8"))
00072 throw sensor_msgs::CvBridgeException(
00073 "Conversion to OpenCV image failed");
00074 cv::Mat image = cv::Mat(cvBridge.toIpl(), true);
00075 cv::imwrite(filename, image);
00076 } catch (sensor_msgs::CvBridgeException &error) {
00077 ROS_ERROR("could not convert the image with the cvBridge to a cv::Mat");
00078 res.success = false;
00079 return false;
00080 }
00081 jobScheduled = true;
00082 jobFilename = filename;
00083 return true;
00084 }
00085
00086
00087
00088
00089 int processImage(string filename) {
00090 Mat image = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
00091
00092
00093
00094
00095 float percentualSizeOfImage = 0.06;
00096 assert(percentualSizeOfImage > 0 && percentualSizeOfImage < 0.5);
00097 int newHeight = image.rows / (float) (1.0 - 1.5 * percentualSizeOfImage);
00098 Mat outputImage(newHeight, image.cols, 0);
00099 for (int x = 0; x < image.rows; x++)
00100 for (int y = 0; y < image.cols; y++)
00101 outputImage.at<unsigned int>(x, y) = image.at<unsigned int>(x, y);
00102
00103
00104 cv::imwrite(filename, outputImage);
00105
00106
00107 GetLines gl;
00108 gl.getLines(filename);
00109 gl.drawPR2(percentualSizeOfImage);
00110 gl.drawLines();
00111
00112 vector<pair<CvPoint2D32f, vector<CvPoint2D32f> > > lines = gl.scaleTo(1,
00113 false);
00114
00115 ros::NodeHandle n;
00116 ros::ServiceClient client =
00117 n.serviceClient<portrait_painter::JobSubmission>("job_submission");
00118 ros::ServiceClient msg_client = getMessageClient(n);
00119
00120
00121 portrait_painter::JobSubmission job;
00122
00123 job.request.height = outputImage.rows;
00124 job.request.width = outputImage.cols;
00125
00126
00127 for (size_t i = 0; i < lines.size(); i++) {
00128 job.request.points.clear();
00129 job.request.start.x = lines[i].first.x;
00130 job.request.start.y = lines[i].first.y;
00131
00132 std::ostringstream oss;
00133 oss << "Drawing line no. " << i + 1 << ", " << lines.size() - i
00134 << " to go";
00135 sendStatus(oss.str(), msg_client);
00136 job.request.last = (i == lines.size() - 1) ? true : false;
00137
00138
00139 for (size_t j = 0; j < lines[i].second.size(); j++) {
00140 portrait_painter::Point2D p;
00141 p.x = lines[i].second[j].x;
00142 p.y = lines[i].second[j].y;
00143 job.request.points.push_back(p);
00144 }
00145 if (client.call(job)) {
00146 if (!job.response.success) {
00147
00148 sendStatus(
00149 "PainterMain is not ready! Canvas not set?\nAborting processing of image",
00150 msg_client);
00151 break;
00152 }
00153 } else {
00154 ROS_ERROR("Failed to call service");
00155 return 1;
00156 }
00157 }
00158 sendStatus("I am done drawing the picture! How do you like it?",
00159 msg_client);
00160
00161 EECartImpedArm arm("r_arm_cart_imped_controller");
00162
00163
00164 ee_cart_imped_msgs::EECartImpedGoal traj;
00165 tf::Quaternion o = tf::createQuaternionFromRPY(0, 0, 0);
00166 EECartImpedArm::addTrajectoryPoint(traj, 0.5, -0.5, 0.5, o.x(), o.y(),
00167 o.z(), o.w(), 20, 20, 20, 30, 30, 30, false, false, false, false,
00168 false, false, 2, "/torso_lift_link");
00169 arm.startTrajectory(traj);
00170 return 0;
00171 }
00172