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
00033
00034
00035
00036 #include <rc_genicam_api/system.h>
00037 #include <rc_genicam_api/interface.h>
00038 #include <rc_genicam_api/device.h>
00039 #include <rc_genicam_api/stream.h>
00040 #include <rc_genicam_api/buffer.h>
00041 #include <rc_genicam_api/image.h>
00042 #include <rc_genicam_api/imagelist.h>
00043 #include <rc_genicam_api/config.h>
00044
00045 #include <rc_genicam_api/pixel_formats.h>
00046
00047 #include <iostream>
00048 #include <fstream>
00049 #include <iomanip>
00050 #include <cmath>
00051
00052 namespace
00053 {
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 void storePointCloud(double f, double t, double scale,
00073 std::shared_ptr<const rcg::Image> left,
00074 std::shared_ptr<const rcg::Image> disp,
00075 std::shared_ptr<const rcg::Image> conf=0,
00076 std::shared_ptr<const rcg::Image> error=0)
00077 {
00078
00079
00080 uint32_t width=disp->getWidth();
00081 uint32_t height=disp->getHeight();
00082 bool bigendian=disp->isBigEndian();
00083 int ds=(left->getWidth()+disp->getWidth()-1)/disp->getWidth();
00084
00085
00086
00087 f*=width;
00088
00089
00090
00091 const uint8_t *dps=disp->getPixels();
00092 size_t dstep=disp->getWidth()*sizeof(uint16_t)+disp->getXPadding();
00093
00094
00095
00096 int n=0;
00097 for (uint32_t k=0; k<height; k++)
00098 {
00099 int j=0;
00100 for (uint32_t i=0; i<width; i++)
00101 {
00102 if ((dps[j]|dps[j+1]) != 0) n++;
00103 j+=2;
00104 }
00105
00106 dps+=dstep;
00107 }
00108
00109 dps=disp->getPixels();
00110
00111
00112
00113 const uint8_t *cps=0, *eps=0;
00114 size_t cstep=0, estep=0;
00115
00116 if (conf)
00117 {
00118 cps=conf->getPixels();
00119 cstep=conf->getWidth()*sizeof(uint8_t)+conf->getXPadding();
00120 }
00121
00122 if (error)
00123 {
00124 eps=error->getPixels();
00125 estep=error->getWidth()*sizeof(uint8_t)+error->getXPadding();
00126 }
00127
00128
00129
00130 std::ostringstream name;
00131 double timestamp=left->getTimestampNS()/1000000000.0;
00132 name << "rc_vizard_" << std::setprecision(16) << timestamp << ".ply";
00133
00134 std::ofstream out(name.str());
00135
00136 out << "ply" << std::endl;
00137 out << "format ascii 1.0" << std::endl;
00138 out << "comment Created with gc_pointcloud from Roboception GmbH" << std::endl;
00139 out << "comment Camera [1 0 0; 0 1 0; 0 0 1] [0 0 0]" << std::endl;
00140 out << "element vertex " << n << std::endl;
00141 out << "property float32 x" << std::endl;
00142 out << "property float32 y" << std::endl;
00143 out << "property float32 z" << std::endl;
00144 out << "property float32 scan_size" << std::endl;
00145
00146 if (cps != 0)
00147 {
00148 out << "property float32 scan_conf" << std::endl;
00149 }
00150
00151 if (eps != 0)
00152 {
00153 out << "property float32 scan_error" << std::endl;
00154 }
00155
00156 out << "property uint8 diffuse_red" << std::endl;
00157 out << "property uint8 diffuse_green" << std::endl;
00158 out << "property uint8 diffuse_blue" << std::endl;
00159 out << "end_header" << std::endl;
00160
00161
00162
00163 for (uint32_t k=0; k<height; k++)
00164 {
00165 for (uint32_t i=0; i<width; i++)
00166 {
00167
00168
00169 double d;
00170 if (bigendian)
00171 {
00172 uint32_t j=i<<1;
00173 d=scale*((dps[j]<<8)|dps[j+1]);
00174 }
00175 else
00176 {
00177 uint32_t j=i<<1;
00178 d=scale*((dps[j+1]<<8)|dps[j]);
00179 }
00180
00181
00182
00183 if (d > 0)
00184 {
00185
00186
00187 double x=(i+0.5-0.5*width)*t/d;
00188 double y=(k+0.5-0.5*height)*t/d;
00189 double z=f*t/d;
00190
00191
00192
00193 double x2=(i-0.5*width)*t/d;
00194 double size=2*1.4*std::abs(x2-x);
00195
00196
00197
00198 uint8_t rgb[3];
00199 rcg::getColor(rgb, left, ds, i, k);
00200
00201
00202
00203 out << x << " " << y << " " << z << " " << size << " ";
00204
00205 if (cps != 0)
00206 {
00207 out << cps[i]/255.0 << " ";
00208 }
00209
00210 if (eps != 0)
00211 {
00212 out << eps[i]*scale*f*t/(d*d) << " ";
00213 }
00214
00215 out << static_cast<int>(rgb[0]) << " ";
00216 out << static_cast<int>(rgb[1]) << " ";
00217 out << static_cast<int>(rgb[2]) << std::endl;
00218 }
00219 }
00220
00221 dps+=dstep;
00222 cps+=cstep;
00223 eps+=estep;
00224 }
00225
00226 out.close();
00227 }
00228
00229 }
00230
00231 int main(int argc, char *argv[])
00232 {
00233 try
00234 {
00235 if (argc >= 2)
00236 {
00237
00238
00239 std::shared_ptr<rcg::Device> dev=rcg::getDevice(argv[1]);
00240
00241 if (dev)
00242 {
00243 dev->open(rcg::Device::CONTROL);
00244 std::shared_ptr<GenApi::CNodeMapRef> nodemap=dev->getRemoteNodeMap();
00245
00246
00247
00248 double f=rcg::getFloat(nodemap, "FocalLengthFactor", 0, 0, false);
00249 double t=rcg::getFloat(nodemap, "Baseline", 0, 0, true);
00250 double scale=rcg::getFloat(nodemap, "Scan3dCoordinateScale", 0, 0, true);
00251
00252
00253
00254 rcg::checkFeature(nodemap, "Scan3dOutputMode", "DisparityC");
00255 rcg::checkFeature(nodemap, "Scan3dCoordinateOffset", "0");
00256 rcg::checkFeature(nodemap, "Scan3dInvalidDataFlag", "1");
00257 rcg::checkFeature(nodemap, "Scan3dInvalidDataValue", "0");
00258
00259
00260
00261 rcg::setEnum(nodemap, "PixelFormat", "YCbCr411_8", false);
00262
00263
00264
00265 {
00266 std::vector<std::string> component;
00267
00268 rcg::getEnum(nodemap, "ComponentSelector", component, true);
00269
00270 for (size_t i=0; i<component.size(); i++)
00271 {
00272 rcg::setEnum(nodemap, "ComponentSelector", component[i].c_str(), true);
00273
00274 bool enable=(component[i] == "Intensity" || component[i] == "Disparity" ||
00275 component[i] == "Confidence" || component[i] == "Error");
00276 rcg::setBoolean(nodemap, "ComponentEnable", enable, true);
00277 }
00278 }
00279
00280
00281
00282 std::vector<std::shared_ptr<rcg::Stream> > stream=dev->getStreams();
00283
00284 if (stream.size() > 0)
00285 {
00286
00287
00288 stream[0]->open();
00289 stream[0]->startStreaming();
00290
00291
00292
00293
00294 rcg::ImageList left_list(25);
00295 rcg::ImageList disp_list(25);
00296 rcg::ImageList conf_list(25);
00297 rcg::ImageList error_list(25);
00298
00299 bool run=true;
00300 int async=0, maxasync=50;
00301
00302 while (run && async < maxasync)
00303 {
00304 async++;
00305
00306
00307
00308 const rcg::Buffer *buffer=stream[0]->grab(500);
00309 if (buffer != 0)
00310 {
00311
00312
00313 if (!buffer->getIsIncomplete() && buffer->getImagePresent())
00314 {
00315
00316
00317 uint64_t pixelformat=buffer->getPixelFormat();
00318 if (pixelformat == Mono8 || pixelformat == YCbCr411_8)
00319 {
00320 left_list.add(buffer);
00321 }
00322 else if (pixelformat == Coord3D_C16)
00323 {
00324 disp_list.add(buffer);
00325 }
00326 else if (pixelformat == Confidence8)
00327 {
00328 conf_list.add(buffer);
00329 }
00330 else if (pixelformat == Error8)
00331 {
00332 error_list.add(buffer);
00333 }
00334
00335
00336
00337
00338 uint64_t timestamp=buffer->getTimestampNS();
00339
00340 std::shared_ptr<const rcg::Image> left=left_list.find(timestamp);
00341 std::shared_ptr<const rcg::Image> disp=disp_list.find(timestamp);
00342 std::shared_ptr<const rcg::Image> conf=conf_list.find(timestamp);
00343 std::shared_ptr<const rcg::Image> error=error_list.find(timestamp);
00344
00345 if (left && disp && conf && error)
00346 {
00347
00348
00349 storePointCloud(f, t, scale, left, disp, conf, error);
00350
00351
00352
00353
00354 async=0;
00355 left_list.removeOld(timestamp);
00356 disp_list.removeOld(timestamp);
00357 conf_list.removeOld(timestamp);
00358 error_list.removeOld(timestamp);
00359
00360
00361
00362
00363 run=false;
00364 }
00365 }
00366 }
00367 else
00368 {
00369 std::cerr << "Cannot grab images" << std::endl;
00370 break;
00371 }
00372 }
00373
00374
00375
00376 if (async >= maxasync && run)
00377 {
00378 std::cerr << "Cannot grab synchronized left and disparity image" << std::endl;
00379 }
00380
00381
00382
00383 stream[0]->stopStreaming();
00384 stream[0]->close();
00385 }
00386 else
00387 {
00388 std::cerr << "No streams available" << std::endl;
00389 }
00390
00391
00392
00393 dev->close();
00394 }
00395 else
00396 {
00397 std::cerr << "Device '" << argv[1] << "' not found!" << std::endl;
00398 }
00399 }
00400 else
00401 {
00402
00403
00404 std::cout << argv[0] << " [interface-id>:]<device-id>" << std::endl;
00405 std::cout << std::endl;
00406 std::cout << "Gets the first synchronized image set consisting of left, disparity, confidence" << std::endl;
00407 std::cout << "and error image, creates a point cloud and stores it in ply ascii format" << std::endl;
00408 std::cout << "in the current directory." << std::endl;
00409 std::cout << std::endl;
00410 std::cout << "<device-id> Device from which images will taken" << std::endl;
00411 }
00412 }
00413 catch (const std::exception &ex)
00414 {
00415 std::cerr << ex.what() << std::endl;
00416 }
00417
00418 rcg::System::clearSystems();
00419
00420 return 0;
00421 }