72 std::cout <<
"gc_stream -h | [-c] [-f <fmt>] [-t] [<interface-id>:]<device-id> [n=<n>] [@<file>] [<key>=<value>] ..." << std::endl;
73 std::cout << std::endl;
74 std::cout <<
"Stores images from the specified device after applying the given optional GenICam parameters." << std::endl;
75 std::cout << std::endl;
76 std::cout <<
"Options:" << std::endl;
77 std::cout <<
"-h Prints help information and exits" << std::endl;
78 std::cout <<
"-c Print ChunkDataControl category for all received buffers" << std::endl;
79 std::cout <<
"-t Testmode, which does not store images and provides extended statistics" << std::endl;
80 std::cout <<
"-f pnm|png Format for storing images. Default is pnm" << std::endl;
81 std::cout << std::endl;
82 std::cout <<
"Parameters:" << std::endl;
83 std::cout <<
"<interface-id> Optional GenICam ID of interface for connecting to the device" << std::endl;
84 std::cout <<
"<device-id> GenICam device ID, serial number or user defined name of device" << std::endl;
85 std::cout <<
"n=<n> Optional number of images to be received (default is 1)" << std::endl;
86 std::cout <<
"@<file> Optional file with parameters as store with parameter 'gc_info -p ...'" << std::endl;
87 std::cout <<
"<key>=<value> Optional GenICam parameters to be changed in the given order" << std::endl;
89 std::cout << std::endl;
90 std::cout <<
"Streaming can be aborted by hitting the 'Enter' key." << std::endl;
98 std::string getDigitalIO(
const std::shared_ptr<GenApi::CNodeMapRef> &nodemap)
107 std::vector<std::string> io;
110 for (
int i=
static_cast<int>(io.size())-1; i>=0; i--)
112 rcg::setEnum(nodemap,
"LineSelector", io[i].c_str(),
true);
116 if (mode ==
"Input") in+=std::to_string((line_status>>i)&0x1);
117 if (mode ==
"Output") out+=std::to_string((line_status>>i)&0x1);
120 if (out.size() > 0 || in.size() > 0)
122 if (out.size() == 0) out.push_back(
'0');
123 if (in.size() == 0) in.push_back(
'0');
126 ret <<
"_" << out <<
"_" << in;
130 catch (
const std::exception &)
135 return std::string();
142 std::string storeBuffer(
rcg::ImgFmt fmt,
const std::shared_ptr<GenApi::CNodeMapRef> &nodemap,
143 const std::string &component,
const rcg::Buffer *buffer, uint32_t part,
144 size_t yoffset=0,
size_t height=0)
153 name <<
"image_" << t_sec <<
"." << std::setfill(
'0') << std::setw(9) << t_nsec;
155 if (component.size() > 0)
157 name <<
'_' << component;
162 name << getDigitalIO(nodemap);
167 std::string full_name;
171 full_name=
storeImage(name.
str(), fmt, image, yoffset, height);
175 std::cerr <<
"storeBuffer(): Received incomplete buffer" << std::endl;
179 std::cerr <<
"storeBuffer(): Received buffer without image" << std::endl;
193 std::string storeBufferAsDisparity(
const std::shared_ptr<GenApi::CNodeMapRef> &nodemap,
196 std::string dispname;
209 inv=
static_cast<int>(
rcg::getFloat(nodemap,
"ChunkScan3dInvalidDataValue"));
212 double scale=
rcg::getFloat(nodemap,
"ChunkScan3dCoordinateScale");
213 double offset=
rcg::getFloat(nodemap,
"ChunkScan3dCoordinateOffset");
222 name <<
"image_" << t_sec <<
"." << std::setfill(
'0') << std::setw(9) << t_nsec;
223 name <<
"_Disparity";
227 name << getDigitalIO(nodemap);
236 std::cerr <<
"storeBuffer(): Received incomplete buffer" << std::endl;
240 std::cerr <<
"storeBuffer(): Received buffer without image" << std::endl;
250 void storeParameter(
const std::shared_ptr<GenApi::CNodeMapRef> &nodemap,
251 const std::string &component,
const rcg::Buffer *buffer,
252 size_t height=0,
bool dispinfo=
false)
263 name <<
"image_" << t_sec <<
"." << std::setfill(
'0') << std::setw(9) << t_nsec;
265 if (component.size() > 0)
267 name <<
'_' << component;
272 name << getDigitalIO(nodemap);
273 name <<
"_param.txt";
277 rcg::setString(nodemap,
"ChunkComponentSelector", component.c_str());
283 double u=
rcg::getFloat(nodemap,
"ChunkScan3dPrincipalPointU");
284 double v=
rcg::getFloat(nodemap,
"ChunkScan3dPrincipalPointV");
285 double exp=
rcg::getFloat(nodemap,
"ChunkExposureTime")/1000000.0;
288 double scale=0, offset=0;
294 inv=
static_cast<int>(
rcg::getFloat(nodemap,
"ChunkScan3dInvalidDataValue"));
298 offset=
rcg::getFloat(nodemap,
"ChunkScan3dCoordinateOffset");
303 if (
width > 0 && height > 0 && f > 0 && t > 0)
307 out <<
"# Created by gc_stream" << std::endl;
308 out << std::fixed << std::setprecision(5);
309 out <<
"camera.A=[" << f <<
" 0 " << u <<
"; 0 " << f <<
" " << v <<
"; 0 0 1]" << std::endl;
310 out <<
"camera.height=" << height << std::endl;
311 out <<
"camera.width=" <<
width << std::endl;
312 out <<
"camera.exposure_time=" << exp << std::endl;
313 out <<
"camera.gain=" << gain << std::endl;
314 out <<
"rho=" << f*t << std::endl;
315 out <<
"t=" << t << std::endl;
319 float v=
static_cast<float>(
rcg::getFloat(nodemap,
"ChunkRcNoise", 0, 0,
true));
320 out <<
"camera.noise=" << v << std::endl;
322 catch (
const std::exception &)
327 float v=
static_cast<float>(
rcg::getFloat(nodemap,
"ChunkRcBrightness", 0, 0,
true));
328 out <<
"camera.brightness=" << v << std::endl;
330 catch (
const std::exception &)
335 float v=
static_cast<float>(
rcg::getFloat(nodemap,
"ChunkRcOut1Reduction", 0, 0,
true));
336 out <<
"camera.out1_reduction=" << v << std::endl;
338 catch (
const std::exception &)
341 for (
int i=0; i<4; i++)
345 rcg::setEnum(nodemap,
"ChunkLineSelector", (
"Out"+std::to_string(i)).c_str(),
true);
346 float v=
static_cast<float>(
rcg::getFloat(nodemap,
"ChunkRcLineRatio", 0, 0,
true));
347 out <<
"camera.out" << i <<
"_ratio=" << v << std::endl;
349 catch (
const std::exception &)
355 out <<
"disp.inv=" << inv << std::endl;
356 out <<
"disp.scale=" << scale << std::endl;
357 out <<
"disp.offset=" << offset << std::endl;
368 std::atomic<bool> user_interrupt(
false);
370 void interruptHandler(
int)
372 std::cout <<
"Stopping ..." << std::endl;
379 void checkUserInterrupt()
384 std::cout <<
"Stopping ..." << std::endl;
393 int main(
int argc,
char *argv[])
397 signal(SIGINT, interruptHandler);
401 bool print_chunk_data=
false;
408 while (i < argc && argv[i][0] ==
'-')
410 std::string param=argv[i];
417 else if (param ==
"-c")
419 print_chunk_data=
true;
422 else if (param ==
"-t")
427 else if (param ==
"-f")
433 std::string imgfmt=argv[i];
438 else if (imgfmt ==
"png")
444 throw std::invalid_argument(std::string(
"Invalid argument of '-f': ")+argv[i]);
451 throw std::invalid_argument(
"Argument expected after '-f'!");
456 throw std::invalid_argument(
"Unknown parameter: "+param);
470 std::shared_ptr<GenApi::CNodeMapRef> nodemap=dev->getRemoteNodeMap();
471 std::vector<std::pair<std::string, std::string> > chunk_param;
482 std::string key=argv[i++];
484 if (key.size() > 0 && key[0] ==
'@')
492 catch (
const std::exception &ex)
494 std::cerr <<
"Warning: Loading of parameters from file '" << key.substr(1) <<
495 "' failed at least partially" << std::endl;
496 std::cerr << ex.what() << std::endl;
505 size_t k=key.find(
'=');
506 if (k != std::string::npos)
508 value=key.substr(k+1);
509 key=key.substr(0, k);
514 n=std::max(1, std::stoi(value));
518 if (value.size() > 0)
524 catch (
const std::exception &)
529 if (key.compare(0, 5,
"Chunk") == 0)
531 chunk_param.push_back(std::pair<std::string, std::string>(key, value));
549 if (
rcg::setEnum(nodemap,
"ComponentSelector",
"IntensityCombined",
false) &&
552 if (
rcg::setEnum(nodemap,
"ComponentSelector",
"Intensity",
false) &&
557 std::cout << std::endl;
558 std::cout <<
"NOTE: Disabling component 'Intensity' as 'IntensityCombined' is enabled."
566 std::vector<std::string> component;
568 rcg::getEnum(nodemap,
"ComponentSelector", component,
false);
570 if (component.size() > 0)
572 std::cout << std::endl;
573 std::cout <<
"Available components (1 means enabled, 0 means disabled):" << std::endl;
574 std::cout << std::endl;
576 for (
size_t k=0; k<component.size(); k++)
578 rcg::setEnum(nodemap,
"ComponentSelector", component[k].c_str(),
true);
580 std::cout << component[k] <<
": ";
582 std::cout << std::endl;
585 std::cout << std::endl;
591 std::vector<std::shared_ptr<rcg::Stream> > stream=dev->getStreams();
593 if (stream.size() > 0)
597 std::thread thread_cui(checkUserInterrupt);
604 stream[0]->attachBuffers(
true);
605 stream[0]->startStreaming();
607 std::cout <<
"Package size: " <<
rcg::getString(nodemap,
"GevSCPSPacketSize") << std::endl;
610 std::cout <<
"Press 'Enter' to abort grabbing." << std::endl;
612 std::cout << std::endl;
614 int buffers_received=0;
615 int buffers_incomplete=0;
616 auto time_start=std::chrono::steady_clock::now();
619 for (
int k=0; k<n && !user_interrupt; k++)
624 while (retry > 0 && !user_interrupt)
630 if (buffers_received == 0)
632 time_start=std::chrono::steady_clock::now();
644 for (uint32_t part=0; part<npart; part++)
656 if (component ==
"Disparity" && fmt ==
rcg::PNM)
658 name=storeBufferAsDisparity(nodemap, buffer, part);
660 if (name.size() != 0)
662 std::cout <<
"Image '" << name <<
"' stored" << std::endl;
663 storeParameter(nodemap, component, buffer);
669 if (name.size() == 0)
671 if (component ==
"IntensityCombined" || component ==
"RawCombined")
676 std::string comp_name = component.substr(0, component.size() - 8);
679 name=storeBuffer(fmt, nodemap, comp_name, buffer, part, 0, h2);
683 std::cout <<
"Image '" << name <<
"' stored" << std::endl;
686 name=storeBuffer(fmt, nodemap, comp_name.append(
"Right"), buffer, part, h2, h2);
690 std::cout <<
"Image '" << name <<
"' stored" << std::endl;
695 name=storeBuffer(fmt, nodemap, component, buffer, part);
699 std::cout <<
"Image '" << name <<
"' stored" << std::endl;
707 if (component ==
"Intensity")
709 storeParameter(nodemap, component, buffer);
711 else if (component ==
"Disparity")
713 storeParameter(nodemap, component, buffer, 0,
true);
715 else if (component ==
"IntensityCombined" || component ==
"RawCombined")
717 std::string comp_name = component.substr(0, component.size() - 8);
719 storeParameter(nodemap, comp_name, buffer, h2,
false);
739 std::cout <<
"Received buffer with timestamp: " << t_sec <<
"."
740 << std::setfill(
'0') << std::setw(9) << t_nsec << std::endl;
745 auto current=std::chrono::system_clock::now();
747 static_cast<double>(std::chrono::duration_cast<std::chrono::nanoseconds>(current.time_since_epoch()).count())-
753 if (print_chunk_data)
757 for (
size_t i=0; i<chunk_param.size(); i++)
760 chunk_param[i].second.c_str(),
true);
765 std::cout << std::endl;
769 std::cout <<
"Cannot find node 'ChunkDataControl'" << std::endl;
772 std::cout << std::endl;
777 std::cerr <<
"Incomplete buffer received" << std::endl;
778 buffers_incomplete++;
783 std::cerr <<
"Cannot grab images" << std::endl;
791 auto time_stop=std::chrono::steady_clock::now();
793 stream[0]->stopStreaming();
798 std::cout << std::endl;
799 std::cout <<
"Received buffers: " << buffers_received << std::endl;
800 std::cout <<
"Incomplete buffers: " << buffers_incomplete << std::endl;
802 std::cout <<
"Buffers per second: " << std::setprecision(3)
803 << 1000.0*buffers_received/std::chrono::duration_cast<std::chrono::milliseconds>(time_stop-time_start).count()
810 if (buffers_received-buffers_incomplete > 0)
812 latency_ns/=buffers_received-buffers_incomplete;
815 std::cout <<
"Mean latency: " << std::setprecision(5) << latency_ns/1.0e6
816 <<
" ms" << std::endl;
822 if (buffers_incomplete == buffers_received)
829 std::cerr <<
"No streams available" << std::endl;
837 std::cerr <<
"Device '" << argv[i] <<
"' not found!" << std::endl;
847 catch (
const std::exception &ex)
849 std::cerr <<
"Exception: " << ex.what() << std::endl;
854 std::cerr <<
"Exception: " << ex.
what() << std::endl;
859 std::cerr <<
"Unknown exception!" << std::endl;