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
00035 #ifndef _CLASS_PINHOLE_PROJECTION_CPP_
00036 #define _CLASS_PINHOLE_PROJECTION_CPP_
00037
00038 #include "class_pinhole_projection.h"
00039
00040
00041
00042
00047 int class_pinhole_projection::set_projection_plane(double a, double b, double c, double d)
00048 {
00049 projection_plane.a = a;
00050 projection_plane.b = b;
00051 projection_plane.c = c;
00052 projection_plane.d = d;
00053 return 1;}
00054
00060 int class_pinhole_projection::print_CvMat(cv::Mat *mat, const char* name)
00061 {
00062
00063 if (name==NULL)
00064 {
00065 printf("cvMat has %d cols and %d lines\n", mat->cols, mat->rows);
00066 }
00067 else
00068 {
00069 printf("%s has %d cols and %d lines\n",name, mat->cols, mat->rows);
00070 }
00071
00072 for (int l=0; l<mat->rows; l++)
00073 {
00074 printf("[");
00075 for (int c=0; c<mat->cols; c++)
00076 {
00077 printf("%3.2f ", mat->at<double>(l,c));
00078 }
00079 printf("]\n");
00080 }
00081
00082 return 1;}
00083
00084 int class_pinhole_projection::project_vertex_to_pixel(const pcl::PointCloud<pcl::PointXYZ>::Ptr v, std::vector<pcl::PointXY>* p)
00085 {
00086
00087 cv::Mat vertexes(4, (int)v->points.size(), CV_64FC1);
00088 cv::Mat pixels(3, (int)v->points.size(), CV_64FC1);
00089
00090
00091 for (size_t i=0; i < v->points.size(); i++)
00092 {
00093 vertexes.at<double>(0,i) = v->points.at(i).x;
00094 vertexes.at<double>(1,i) = v->points.at(i).y;
00095 vertexes.at<double>(2,i) = v->points.at(i).z;
00096 vertexes.at<double>(3,i) = 1;
00097 }
00098
00099
00100 cv::Mat transformation;
00101 transformation.create(4,4,CV_64F);
00102 transformation = intrinsic*extrinsic;
00103
00104
00105
00106 pixels = transformation*vertexes;
00107
00108
00109
00110 p->erase(p->begin(), p->end());
00111
00112
00113
00114 for (int i=0; i < pixels.cols; i++)
00115 {
00116 pcl::PointXY pt;
00117 pt.x = (pixels.at<double>(0,i) / pixels.at<double>(2,i));
00118 pt.y = (pixels.at<double>(1,i) / pixels.at<double>(2,i));
00119 p->push_back(pt);
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 return 1;}
00151
00152
00153 int class_pinhole_projection::project_pixel_with_color_to_vertex(const pcl::PointCloud<pcl::PointXYZRGB>* p, pcl::PointCloud<pcl::PointXYZRGB>* v)
00154 {
00155 cv::Mat transformation;
00156 transformation.create(4,4,CV_64F);
00157 transformation = intrinsic*extrinsic;
00158
00159 cv::Mat* M = &transformation;
00160 int valid_projections=0;
00161
00162
00163 double p11 = M->at<double>(0,0); double p12 = M->at<double>(0,1); double p13 = M->at<double>(0,2); double p14 = M->at<double>(0,3);
00164 double p21 = M->at<double>(1,0); double p22 = M->at<double>(1,1); double p23 = M->at<double>(1,2); double p24 = M->at<double>(1,3);
00165 double p31 = M->at<double>(2,0); double p32 = M->at<double>(2,1); double p33 = M->at<double>(2,2); double p34 = M->at<double>(2,3);
00166
00167
00168 double &A = projection_plane.a; double &B = projection_plane.b; double &C = projection_plane.c; double &D = projection_plane.d;
00169
00170
00171 double K1 = (C*p12*p34+p13*D*p32-p12*p33*D-p32*C*p14-p13*B*p34+p33*B*p14);
00172 double K2 = (p32*C*p24-p34*C*p22-p33*B*p24-p32*p23*D+p33*D*p22+p34*p23*B);
00173 double K3 = (-p13*D*p22+C*p14*p22-C*p12*p24+p12*p23*D-p14*p23*B+p13*B*p24);
00174 double K4 = (C*p31*p12+p11*p33*B+p13*A*p32-C*p11*p32-p33*A*p12-p31*p13*B);
00175 double K5 = (C*p21*p32+p31*p23*B+p33*A*p22-C*p31*p22-p23*A*p32-p21*p33*B);
00176 double K6 = (-C*p21*p12-p11*p23*B+C*p11*p22+p23*A*p12+p21*p13*B-p13*A*p22);
00177 double K7 = (p11*p34*C-p13*A*p34-p11*p33*D+p33*A*p14+p31*p13*D-p31*C*p14);
00178 double K8 = (-p33*A*p24-p31*p23*D+p23*A*p34+p21*p33*D-C*p21*p34+C*p31*p24);
00179 double K9 = (C*p21*p14+p13*A*p24-p23*A*p14-p21*p13*D+p11*p23*D-C*p11*p24);
00180 double K10 = (C*p31*p12+p11*p33*B+p13*A*p32-C*p11*p32-p33*A*p12-p31*p13*B);
00181 double K11 = (C*p21*p32+p31*p23*B+p33*A*p22-C*p31*p22-p23*A*p32-p21*p33*B);
00182 double K12 = (-C*p21*p12-p11*p23*B+C*p11*p22+p23*A*p12+p21*p13*B-p13*A*p22);
00183
00184
00185 v->points.erase(v->points.begin(), v->points.end());
00186
00187
00188 cv::Mat XYZ_plane(4, 1, CV_64FC1);
00189 XYZ_plane.at<double>(3,0) = 1;
00190 cv::Mat XYZ_image(4, 1, CV_64FC1);
00191
00192
00193 for (int i=0; i<(int)p->points.size();i++)
00194 {
00195 pcl::PointXYZRGB pix = p->at(i);
00196 pcl::PointXYZRGB pt;
00197 pt.x = -(K1*pix.y + K2*pix.x + K3) / (K4*pix.y + K5*pix.x + K6);
00198 pt.y = (K7*pix.y + K8*pix.x + K9) / (K10*pix.y + K11*pix.x + K12);
00199 pt.z = -(A*pt.x + B*pt.y + D)/C;
00200
00201
00202 XYZ_plane.at<double>(0,0) = pt.x;
00203 XYZ_plane.at<double>(1,0) = pt.y;
00204 XYZ_plane.at<double>(2,0) = pt.z;
00205 XYZ_image = extrinsic*XYZ_plane;
00206
00207 if (XYZ_image.at<double>(2,0)>0)
00208 {
00209 valid_projections++;
00210 pt.rgb = pix.rgb;
00211 v->points.push_back(pt);
00212 }
00213 else
00214 {
00215 pt.x = NAN;
00216 pt.y = NAN;
00217 pt.z = NAN;
00218 pt.rgb = NAN;
00219 v->points.push_back(pt);
00220 }
00221 }
00222
00223 if (0)
00224 {
00225 ROS_INFO("Projecting %d pixels. Valid projections = %d", (int)p->size(), valid_projections);
00226 }
00227 return valid_projections;};
00228
00229 int class_pinhole_projection::project_pixel_to_vertex(const std::vector<pcl::PointXY>* p, pcl::PointCloud<pcl::PointXYZ>* v)
00230 {
00231 cv::Mat transformation;
00232 transformation.create(4,4,CV_64F);
00233 transformation = intrinsic*extrinsic;
00234
00235 cv::Mat* M = &transformation;
00236 int valid_projections=0;
00237
00238
00239 double p11 = M->at<double>(0,0); double p12 = M->at<double>(0,1); double p13 = M->at<double>(0,2); double p14 = M->at<double>(0,3);
00240 double p21 = M->at<double>(1,0); double p22 = M->at<double>(1,1); double p23 = M->at<double>(1,2); double p24 = M->at<double>(1,3);
00241 double p31 = M->at<double>(2,0); double p32 = M->at<double>(2,1); double p33 = M->at<double>(2,2); double p34 = M->at<double>(2,3);
00242
00243
00244 double &A = projection_plane.a; double &B = projection_plane.b; double &C = projection_plane.c; double &D = projection_plane.d;
00245
00246
00247 double K1 = (C*p12*p34+p13*D*p32-p12*p33*D-p32*C*p14-p13*B*p34+p33*B*p14);
00248 double K2 = (p32*C*p24-p34*C*p22-p33*B*p24-p32*p23*D+p33*D*p22+p34*p23*B);
00249 double K3 = (-p13*D*p22+C*p14*p22-C*p12*p24+p12*p23*D-p14*p23*B+p13*B*p24);
00250 double K4 = (C*p31*p12+p11*p33*B+p13*A*p32-C*p11*p32-p33*A*p12-p31*p13*B);
00251 double K5 = (C*p21*p32+p31*p23*B+p33*A*p22-C*p31*p22-p23*A*p32-p21*p33*B);
00252 double K6 = (-C*p21*p12-p11*p23*B+C*p11*p22+p23*A*p12+p21*p13*B-p13*A*p22);
00253 double K7 = (p11*p34*C-p13*A*p34-p11*p33*D+p33*A*p14+p31*p13*D-p31*C*p14);
00254 double K8 = (-p33*A*p24-p31*p23*D+p23*A*p34+p21*p33*D-C*p21*p34+C*p31*p24);
00255 double K9 = (C*p21*p14+p13*A*p24-p23*A*p14-p21*p13*D+p11*p23*D-C*p11*p24);
00256 double K10 = (C*p31*p12+p11*p33*B+p13*A*p32-C*p11*p32-p33*A*p12-p31*p13*B);
00257 double K11 = (C*p21*p32+p31*p23*B+p33*A*p22-C*p31*p22-p23*A*p32-p21*p33*B);
00258 double K12 = (-C*p21*p12-p11*p23*B+C*p11*p22+p23*A*p12+p21*p13*B-p13*A*p22);
00259
00260
00261 v->points.erase(v->points.begin(), v->points.end());
00262
00263
00264 cv::Mat XYZ_plane(4, 1, CV_64FC1);
00265 XYZ_plane.at<double>(3,0) = 1;
00266 cv::Mat XYZ_image(4, 1, CV_64FC1);
00267
00268
00269 for (int i=0; i<(int)p->size();i++)
00270 {
00271 pcl::PointXY pix = p->at(i);
00272 pcl::PointXYZ pt;
00273 pt.x = -(K1*pix.y + K2*pix.x + K3) / (K4*pix.y + K5*pix.x + K6);
00274 pt.y = (K7*pix.y + K8*pix.x + K9) / (K10*pix.y + K11*pix.x + K12);
00275 pt.z = -(A*pt.x + B*pt.y + D)/C;
00276
00277
00278 XYZ_plane.at<double>(0,0) = pt.x;
00279 XYZ_plane.at<double>(1,0) = pt.y;
00280 XYZ_plane.at<double>(2,0) = pt.z;
00281 XYZ_image = extrinsic*XYZ_plane;
00282
00283 if (XYZ_image.at<double>(2,0)>0)
00284 {
00285 valid_projections++;
00286 v->points.push_back(pt);
00287 }
00288 else
00289 {
00290 pt.x = NAN;
00291 pt.y = NAN;
00292 pt.z = NAN;
00293 v->points.push_back(pt);
00294 }
00295 }
00296
00297 if (0)
00298 {
00299 ROS_INFO("Projecting %d pixels. Valid projections = %d", (int)p->size(), valid_projections);
00300 }
00301
00302 return valid_projections;}
00303
00304 #endif
00305