gc_stream.cc
Go to the documentation of this file.
00001 /*
00002  * This file is part of the rc_genicam_api package.
00003  *
00004  * Copyright (c) 2017 Roboception GmbH
00005  * All rights reserved
00006  *
00007  * Author: Heiko Hirschmueller
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright notice,
00013  * this list of conditions and the following disclaimer.
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  * this list of conditions and the following disclaimer in the documentation
00017  * and/or other materials provided with the distribution.
00018  *
00019  * 3. Neither the name of the copyright holder nor the names of its contributors
00020  * may be used to endorse or promote products derived from this software without
00021  * specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  * POSSIBILITY OF SUCH DAMAGE.
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/config.h>
00043 
00044 #include <rc_genicam_api/pixel_formats.h>
00045 
00046 #include <iostream>
00047 #include <fstream>
00048 #include <iomanip>
00049 
00050 namespace
00051 {
00052 
00057 std::string storeBuffer(const rcg::Buffer *buffer)
00058 {
00059   // prepare file name
00060 
00061   std::ostringstream name;
00062 
00063   double t=buffer->getTimestampNS()/1000000000.0;
00064 
00065   name << "image_" << std::setprecision(16) << t;
00066 
00067   // store image (see e.g. the sv tool of cvkit for show images)
00068 
00069   if (!buffer->getIsIncomplete() && buffer->getImagePresent())
00070   {
00071     int width=buffer->getWidth();
00072     int height=buffer->getHeight();
00073     const unsigned char *p=static_cast<const unsigned char *>(buffer->getBase())+buffer->getImageOffset();
00074 
00075     size_t px=buffer->getXPadding();
00076 
00077     uint64_t format=buffer->getPixelFormat();
00078     switch (format)
00079     {
00080       case Mono8: // store 8 bit monochrome image
00081       case Confidence8:
00082       case Error8:
00083         {
00084           if (format == Mono8)
00085           {
00086             name << "_mono.pgm";
00087           }
00088           else if (format == Confidence8)
00089           {
00090             name << "_conf.pgm";
00091           }
00092           else if (format == Error8)
00093           {
00094             name << "_err.pgm";
00095           }
00096 
00097           std::ofstream out(name.str(), std::ios::binary);
00098 
00099           out << "P5" << std::endl;
00100           out << width << " " << height << std::endl;
00101           out << 255 << "\n";
00102 
00103           std::streambuf *sb=out.rdbuf();
00104 
00105           for (int k=0; k<height && out.good(); k++)
00106           {
00107             for (int i=0; i<width; i++)
00108             {
00109               sb->sputc(*p++);
00110             }
00111 
00112             p+=px;
00113           }
00114 
00115           out.close();
00116         }
00117         break;
00118 
00119       case Coord3D_C16: // store 16 bit monochrome image
00120         {
00121           name << "_disp.pgm";
00122           std::ofstream out(name.str(), std::ios::binary);
00123 
00124           out << "P5" << std::endl;
00125           out << width << " " << height << std::endl;
00126           out << 65535 << "\n";
00127 
00128           std::streambuf *sb=out.rdbuf();
00129 
00130           // copy image data, pgm is always big endian
00131 
00132           if (buffer->isBigEndian())
00133           {
00134             for (int k=0; k<height && out.good(); k++)
00135             {
00136               for (int i=0; i<width; i++)
00137               {
00138                 sb->sputc(*p++);
00139                 sb->sputc(*p++);
00140               }
00141 
00142               p+=px;
00143             }
00144           }
00145           else
00146           {
00147             for (int k=0; k<height && out.good(); k++)
00148             {
00149               for (int i=0; i<width; i++)
00150               {
00151                 sb->sputc(p[1]);
00152                 sb->sputc(p[0]);
00153                 p+=2;
00154               }
00155 
00156               p+=px;
00157             }
00158           }
00159 
00160           out.close();
00161         }
00162         break;
00163 
00164       case YCbCr411_8: // convert and store as color image
00165         {
00166           name << "_color.ppm";
00167           std::ofstream out(name.str(), std::ios::binary);
00168 
00169           out << "P6" << std::endl;
00170           out << width << " " << height << std::endl;
00171           out << 255 << "\n";
00172 
00173           std::streambuf *sb=out.rdbuf();
00174 
00175           size_t pstep=(width>>2)*6+px;
00176           for (int k=0; k<height && out.good(); k++)
00177           {
00178             for (int i=0; i<width; i+=4)
00179             {
00180               uint8_t rgb[12];
00181               rcg::convYCbCr411toQuadRGB(rgb, p, i);
00182 
00183               for (int j=0; j<12; j++)
00184               {
00185                 sb->sputc(rgb[j]);
00186               }
00187             }
00188 
00189             p+=pstep;
00190           }
00191 
00192           out.close();
00193         }
00194         break;
00195 
00196       default:
00197         std::cerr << "storeBuffer(): Unknown pixel format: "
00198                   << GetPixelFormatName(static_cast<PfncFormat>(buffer->getPixelFormat()))
00199                   << std::endl;
00200         return std::string();
00201         break;
00202     }
00203   }
00204   else if (!buffer->getImagePresent())
00205   {
00206     std::cerr << "storeBuffer(): Received buffer without image" << std::endl;
00207     return std::string();
00208   }
00209   else if (buffer->getIsIncomplete())
00210   {
00211     std::cerr << "storeBuffer(): Received buffer without image" << std::endl;
00212     return std::string();
00213   }
00214 
00215   return name.str();
00216 }
00217 
00218 }
00219 
00220 int main(int argc, char *argv[])
00221 {
00222   try
00223   {
00224     if (argc >= 2)
00225     {
00226       // find specific device accross all systems and interfaces and open it
00227 
00228       std::shared_ptr<rcg::Device> dev=rcg::getDevice(argv[1]);
00229 
00230       if (dev)
00231       {
00232         dev->open(rcg::Device::CONTROL);
00233         std::shared_ptr<GenApi::CNodeMapRef> nodemap=dev->getRemoteNodeMap();
00234 
00235         // set values as given on the command line
00236 
00237         int n=1;
00238 
00239         int i=2;
00240         while (i < argc)
00241         {
00242           // split argument in key and value
00243 
00244           std::string key=argv[i++];
00245           std::string value;
00246 
00247           size_t k=key.find('=');
00248           if (k != std::string::npos)
00249           {
00250             value=key.substr(k+1);
00251             key=key.substr(0, k);
00252           }
00253 
00254           if (key == "n") // set number of images
00255           {
00256             n=std::max(1, std::stoi(value));
00257           }
00258           else // set key=value pair through GenICam
00259           {
00260             rcg::setString(nodemap, key.c_str(), value.c_str(), true);
00261           }
00262         }
00263 
00264         // open stream and get n images
00265 
00266         std::vector<std::shared_ptr<rcg::Stream> > stream=dev->getStreams();
00267 
00268         if (stream.size() > 0)
00269         {
00270           // opening first stream
00271 
00272           stream[0]->open();
00273           stream[0]->startStreaming(n);
00274 
00275           for (int k=0; k<n; k++)
00276           {
00277             // grab next image with timeout of 3 seconds
00278 
00279             const rcg::Buffer *buffer=stream[0]->grab(3000);
00280 
00281             if (buffer != 0)
00282             {
00283               std::string name=storeBuffer(buffer);
00284 
00285               if (name.size() > 0)
00286               {
00287                 std::cout << "Image '" << name << "' stored" << std::endl;
00288               }
00289             }
00290             else
00291             {
00292               std::cerr << "Cannot grab images" << std::endl;
00293               break;
00294             }
00295           }
00296 
00297           stream[0]->stopStreaming();
00298           stream[0]->close();
00299         }
00300         else
00301         {
00302           std::cerr << "No streams available" << std::endl;
00303         }
00304 
00305         dev->close();
00306       }
00307       else
00308       {
00309         std::cerr << "Device '" << argv[1] << "' not found!" << std::endl;
00310       }
00311     }
00312     else
00313     {
00314       // show help
00315 
00316       std::cout << argv[0] << " [interface-id>:]<device-id> [n=<n>] [<key>=<value>] ..." << std::endl;
00317       std::cout << std::endl;
00318       std::cout << "Stores n images from the specified device after applying the given values" << std::endl;
00319       std::cout << std::endl;
00320       std::cout << "<device-id>   Device from which data will be streamed" << std::endl;
00321       std::cout << "n=<n>         Number of images to receive. Default is 1" << std::endl;
00322       std::cout << "<key>=<value> Values set via GenICam before streaming images" << std::endl;
00323     }
00324   }
00325   catch (const std::exception &ex)
00326   {
00327     std::cerr << ex.what() << std::endl;
00328   }
00329 
00330   rcg::System::clearSystems();
00331 
00332   return 0;
00333 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:02