00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <image_algos/pcd_to_image_projector_algo.h>
00033 #include "highgui.h"
00034
00035 using namespace image_algos;
00036
00037 void PCDToImageProjector::init (ros::NodeHandle& nh)
00038 {
00039 nh_ = nh;
00040 nh_.param("origin", origin_, std::string("/RightEyeCalcOff"));
00041 nh_.param("child", child_, std::string("/map"));
00042
00043
00044
00045
00046 nh_.param("focal_length", focal_length_, 0.00641331974023884);
00047 nh_.param("proj_center_x", proj_center_x_, 833.248646581603);
00048 nh_.param("proj_center_y", proj_center_y_, 661.107370424523);
00049 nh_.param("pix_size_x", pix_size_x_, 7.43100103980579e-06);
00050 nh_.param("pix_size_y", pix_size_y_, 7.4e-06);
00051
00052
00053
00054 }
00055
00056
00057 void PCDToImageProjector::pre ()
00058 {
00059
00060 }
00061
00062
00063 void PCDToImageProjector::post ()
00064 {
00065 cvReleaseImage(&subimage_);
00066
00067 }
00068
00069
00070 std::vector<std::string> PCDToImageProjector::requires ()
00071 {
00072 return std::vector<std::string>();
00073 }
00074
00075
00076 std::vector<std::string> PCDToImageProjector::provides ()
00077 {
00078 return std::vector<std::string>();
00079 }
00080
00081 void PCDToImageProjector::project_3D_point(const double &x, const double &y, const double &z, int &row, int &column)
00082 {
00083 double temp1,temp2;
00084 if (focal_length_ > 0.0)
00085 {
00086 temp1 = focal_length_ * (x / z );
00087 temp2 = focal_length_ * (y / z );
00088 }
00089 else
00090 {
00091 temp1 = x;
00092 temp2 = y;
00093 }
00094 column = ( temp1 / pix_size_x_ ) + proj_center_x_;
00095 row = ( temp2 / pix_size_y_ ) + proj_center_y_;
00096 }
00097
00098
00099 std::string PCDToImageProjector::process (sensor_msgs::PointCloud &cloud_in, IplImage *image)
00100 {
00101 try
00102 {
00103 tf_listener_.transformPointCloud(origin_, cloud_in, cloud_in);
00104 }
00105 catch (tf::TransformException ex)
00106 {
00107 ROS_ERROR("[PCDToImageProjector:] %s",ex.what());
00108 }
00109 ROS_INFO("[PCDToImageProjector:] cloud transformed to %s", origin_.c_str());
00110
00111 CvMemStorage* stor = cvCreateMemStorage (0);
00112 CvSeq* seq = cvCreateSeq (CV_SEQ_ELTYPE_POINT, sizeof (CvSeq), sizeof (CvPoint), stor);
00113 if (cloud_in.points.size() == 0)
00114 {
00115 ROS_WARN("[PCDToImageProjector:] Point cloud points with size 0!!! Returning.");
00116 return std::string("[PCDToImageProjector:] Point cloud points with size 0!!! Returning.");
00117 }
00118 for (unsigned long i = 0; i < cloud_in.points.size(); i++)
00119 {
00120 cv::Point3d pt_cv(cloud_in.points[i].x, cloud_in.points[i].y, cloud_in.points[i].z);
00121 CvPoint uv;
00122 project_3D_point(pt_cv.x, pt_cv.y, pt_cv.z, uv.y, uv.x);
00123 if (uv.x < 0 || uv.x > image->width)
00124 {
00125 ROS_WARN("[PCDToImageProjector:] width out of bounds");
00126 continue;
00127 }
00128 if (uv.y < 0 || uv.y > image->height)
00129 {
00130 ROS_WARN("[PCDToImageProjector:] height out of bounds");
00131 continue;
00132 }
00133
00134
00135 cvSeqPush( seq, &uv );
00136 }
00137
00138 CvRect rect = cvBoundingRect(seq);
00139 if (rect.width == 0 || rect.height == 0)
00140 {
00141 ROS_WARN("[PCDToImageProjector:] Rectangle's width = height = 0. This is impossible. Skipping ROI extraction.");
00142 return std::string("[PCDToImageProjector:] Rectangle's width = height = 0. This is impossible. Skipping ROI extraction.");
00143 }
00144 CvPoint pt1, pt2;
00145 pt1.x = rect.x;
00146
00147 if ((rect.x + (rect.width + 0.1*rect.width)) > image->width)
00148 {
00149 rect.width = image->width - rect.x;
00150 }
00151 else
00152 rect.width = rect.width + 0.1 * rect.width;
00153
00154 pt2.x = rect.x + rect.width;
00155 pt1.y = rect.y;
00156
00157
00158 if ((rect.y + (rect.height + 0.1*rect.height)) > image->height)
00159 {
00160 rect.height = image->height - rect.y;
00161 }
00162 else
00163 rect.height = rect.height + 0.1 * rect.height;
00164 pt2.y = rect.y+rect.height;
00165
00166
00167
00168 cvClearMemStorage( stor );
00169
00170
00171
00172 cvSetImageROI(image,rect);
00173
00174 subimage_ = cvCreateImage( cvSize(rect.width, rect.height), image->depth, image->nChannels );
00175 cvCopy(image, subimage_);
00176 cvResetImageROI(image);
00177
00178
00179 return std::string ("ok");
00180 }
00181
00182 std::string PCDToImageProjector::process (geometry_msgs::Polygon &cloud_in, IplImage *image)
00183 {
00184
00185 CvMemStorage* stor = cvCreateMemStorage (0);
00186 CvSeq* seq = cvCreateSeq (CV_SEQ_ELTYPE_POINT, sizeof (CvSeq), sizeof (CvPoint), stor);
00187 if (cloud_in.points.size() == 0)
00188 {
00189 ROS_WARN("[PCDToImageProjector:] Point cloud points with size 0!!! Returning.");
00190 return std::string("[PCDToImageProjector:] Point cloud points with size 0!!! Returning.");
00191 }
00192 for (unsigned long i = 0; i < cloud_in.points.size(); i++)
00193 {
00194
00195 geometry_msgs::PointStamped Pstamped_local;
00196 Pstamped_local.point.x = cloud_in.points[i].x;
00197 Pstamped_local.point.y = cloud_in.points[i].y;
00198 Pstamped_local.point.z = cloud_in.points[i].z;
00199 Pstamped_local.header.frame_id = child_;
00200 geometry_msgs::PointStamped Pstamped_global;
00201 try
00202 {
00203 tf_listener_.transformPoint(origin_, Pstamped_local, Pstamped_global);
00204 cloud_in.points[i].x = Pstamped_global.point.x;
00205 cloud_in.points[i].y = Pstamped_global.point.y;
00206 cloud_in.points[i].z = Pstamped_global.point.z;
00207 }
00208 catch (tf::TransformException ex)
00209 {
00210 ROS_ERROR("[PCDToImageProjector:] %s",ex.what());
00211 return ("PCDToImageProjector: failed polygon transform");
00212 }
00213
00214 cv::Point3d pt_cv(cloud_in.points[i].x, cloud_in.points[i].y, cloud_in.points[i].z);
00215 CvPoint uv;
00216 project_3D_point(pt_cv.x, pt_cv.y, pt_cv.z, uv.y, uv.x);
00217 if (uv.x < 0 || uv.x > image->width)
00218 {
00219 ROS_WARN("[PCDToImageProjector:] width out of bounds");
00220 continue;
00221 }
00222 if (uv.y < 0 || uv.y > image->height)
00223 {
00224 ROS_WARN("[PCDToImageProjector:] height out of bounds");
00225 continue;
00226 }
00227
00228
00229 cvSeqPush( seq, &uv );
00230 }
00231 CvRect rect = cvBoundingRect(seq);
00232 if (rect.width == 0 || rect.height == 0)
00233 {
00234 ROS_WARN("[PCDToImageProjector:] Rectangle's width = height = 0. This is impossible. Skipping ROI extraction.");
00235 return std::string("[PCDToImageProjector:] Rectangle's width = height = 0. This is impossible. Skipping ROI extraction.");
00236 }
00237 CvPoint pt1, pt2;
00238 pt1.x = rect.x;
00239
00240 if ((rect.x + (rect.width + 0.1*rect.width)) > image->width)
00241 {
00242 rect.width = image->width - rect.x;
00243 }
00244 else
00245 rect.width = rect.width + 0.1 * rect.width;
00246
00247 pt2.x = rect.x + rect.width;
00248 pt1.y = rect.y;
00249
00250
00251 if ((rect.y + (rect.height + 0.1*rect.height)) > image->height)
00252 {
00253 rect.height = image->height - rect.y;
00254 }
00255 else
00256 rect.height = rect.height + 0.1 * rect.height;
00257 pt2.y = rect.y+rect.height;
00258
00259
00260
00261 cvClearMemStorage( stor );
00262
00263
00264
00265 cvSetImageROI(image,rect);
00266
00267 subimage_ = cvCreateImage( cvSize(rect.width, rect.height), image->depth, image->nChannels );
00268 cvCopy(image, subimage_);
00269 cvResetImageROI(image);
00270
00271
00272 return std::string ("ok");
00273 }
00274
00275
00276 PCDToImageProjector::OutputType PCDToImageProjector::output ()
00277 {
00278 return subimage_;
00279 };
00280
00281
00282 #ifdef CREATE_NODE
00283 int main (int argc, char* argv[])
00284 {
00285 return standalone_node < PCDToImageProjector> (argc, argv);
00286 }
00287 #endif
00288