void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{       
    
    // Initiatlize Pylon
    Pylon::PylonAutoInitTerm auto_init_term;

    try
    {
        // Get the transport layer factory.
        Pylon::CTlFactory& tlFactory = Pylon::CTlFactory::GetInstance();
        
        // Get all attached devices
        Pylon::DeviceInfoList_t devices;
        tlFactory.EnumerateDevices(devices);

        
        // Create an array of instant cameras for the found devices
        Pylon::CInstantCameraArray cameras(devices.size());

        // Init output
        plhs[0] = mxCreateCellMatrix(cameras.GetSize(),2);
        
        // Find all names
        for(size_t i = 0; i < cameras.GetSize(); ++i)
        {
            cameras[i].Attach(tlFactory.CreateDevice(devices[i]));
            mxSetCell(plhs[0],i+cameras.GetSize(),mxCreateString(cameras[i].GetDeviceInfo().GetModelName()));
            mxSetCell(plhs[0],i,mxCreateDoubleScalar(i));
        }
        
    }
    catch (GenICam::GenericException &e)
    {
        // Error handling.
        mexErrMsgIdAndTxt("baslerDriver:Error:CameraError",e.GetDescription());
    }
    
    return;
}
예제 #2
0
CameraPtrList
BaslerCameraManager::detectCameras() {
	// wipe the list of already detected cameras
	_cameras = CameraPtrList();

	// Get the transport layer factory
	Pylon::CTlFactory& TlFactory = Pylon::CTlFactory::GetInstance();

	// Create the transport layer object needed to enumerate or
	// create a camera object of type Camera_t::DeviceClass()
	Pylon::ITransportLayer *pTl = TlFactory.CreateTl(BaslerCamera_t::DeviceClass());

	// Exit the application if the specific transport layer is not available
	if (!pTl)
		throw RuntimeError("BaslerCameraManager: Failed to create transport layer!");

	// Get all attached cameras and exit the application if no camera is found
	Pylon::DeviceInfoList_t devices;
	if (0 == pTl->EnumerateDevices(devices))
		return _cameras; // briefly, an empty list

	// Create the BaslerCamera instance for each attached camera
	for(Pylon::DeviceInfoList_t::iterator it = devices.begin(); it != devices.end(); it++)
	{
		// Create the camera object of the first available camera.
		// The camera object is used to set and get all available
		// camera features.
		try {
			BaslerCamera_t* cam = new BaslerCamera_t(pTl->CreateDevice(*it));
			_cameras.push_back(new BaslerCamera(cam->GetDeviceInfo().GetSerialNumber().c_str(), cam));
		} catch(GenICam::GenericException e) {
			throw RuntimeError(String("BaslerCameraManager: Error occurred while trying to create Camera object:\n") + e.what());
		}
	}

	return _cameras;
}
예제 #3
0
int main( int argc, char** argv )
{
    ::setenv( "PYLON_ROOT", STRINGIZED( BASLER_PYLON_DIR ), 0 );
    ::setenv( "GENICAM_ROOT_V2_1", STRINGIZED( BASLER_PYLON_GENICAM_DIR ), 0 );
    try
    {
        unsigned int id;
        std::string address;
        std::string setAttributes;
        unsigned int discard;
        boost::program_options::options_description description( "options" );
        unsigned int packet_size;
        unsigned int exposure;
        unsigned int gain;
        unsigned int offset_x;
        unsigned int offset_y;
        unsigned int width;
        unsigned int height;
        std::string frame_trigger;
        std::string line_trigger;
        unsigned int line_rate;
        double timeout_seconds;
        description.add_options()
            ( "help,h", "display help message" )
            ( "address", boost::program_options::value< std::string >( &address ), "camera ip address; default: connect to the first available camera" )
            ( "discard", "discard frames, if cannot keep up; same as --buffer=1" )
            ( "buffer", boost::program_options::value< unsigned int >( &discard )->default_value( 0 ), "maximum buffer size before discarding frames, default: unlimited" )
            ( "list-cameras", "output camera list and exit" )
            ( "fields,f", boost::program_options::value< std::string >( &options.fields )->default_value( "t,rows,cols,type" ), "header fields, possible values: t,rows,cols,type,size,counters" )
            ( "image-type", boost::program_options::value< std::string >( &options.type )->default_value( "3ub" ), "image type, e.g. '3ub'; also see --long-help for details" )
            ( "offset-x", boost::program_options::value< unsigned int >( &offset_x )->default_value( 0 ), "offset in pixels in the line" )
            ( "offset-y", boost::program_options::value< unsigned int >( &offset_y )->default_value( 0 ), "offset in lines in the frame" )
            ( "width", boost::program_options::value< unsigned int >( &width )->default_value( std::numeric_limits< unsigned int >::max() ), "line width in pixels; default: max" )
            ( "height", boost::program_options::value< unsigned int >( &height )->default_value( std::numeric_limits< unsigned int >::max() ), "number of lines in frame (in chunk mode always 1); default: max" )
            ( "frame-trigger", boost::program_options::value< std::string >( &frame_trigger ), "'line1', 'line2', 'line3', 'encoder'" ) //; if absent while --line-trigger present, same as --line-trigger" )
            ( "line-trigger", boost::program_options::value< std::string >( &line_trigger ), "'line1', 'line2', 'line3', 'encoder'" )
            ( "line-rate", boost::program_options::value< unsigned int >( &line_rate ), "line aquisition rate" )
            ( "encoder-ticks", boost::program_options::value< unsigned int >( &encoder_ticks ), "number of encoder ticks until the counter resets (reused for line number in frame in chunk mode)" )
            ( "header-only", "output header only" )
            ( "no-header", "output image data only" )
            ( "packet-size", boost::program_options::value< unsigned int >( &packet_size ), "mtu size on camera side, should be not greater than your lan and network interface set to" )
            ( "exposure", boost::program_options::value< unsigned int >( &exposure )->default_value( 100 ), "exposure" )
            ( "gain", boost::program_options::value< unsigned int >( &gain )->default_value( 100 ), "gain" )
            ( "timeout", boost::program_options::value< double >( &timeout_seconds )->default_value( 3.0 ), " frame acquisition timeout" )
            ( "test-colour", "output colour test image" )
            ( "verbose,v", "be more verbose" );
        boost::program_options::variables_map vm;
        boost::program_options::store( boost::program_options::parse_command_line( argc, argv, description), vm );
        boost::program_options::parsed_options parsed = boost::program_options::command_line_parser(argc, argv).options( description ).allow_unregistered().run();
        boost::program_options::notify( vm );
        if ( vm.count( "help" ) || vm.count( "long-help" ) )
        {
            std::cerr << "acquire images from a basler camera (for now gige only)" << std::endl;
            std::cerr << "output to stdout as serialized cv::Mat" << std::endl;
            std::cerr << std::endl;
            std::cerr << "usage: basler-cat [<options>] [<filters>]" << std::endl;
            std::cerr << std::endl;
            std::cerr << description << std::endl;
            if( vm.count( "long-help" ) )
            {
                std::cerr << std::endl;
                std::cerr << snark::cv_mat::filters::usage() << std::endl;
                std::cerr << std::endl;
                std::cerr << snark::cv_mat::serialization::options::type_usage() << std::endl;
            }
            std::cerr << std::endl;
            std::cerr << "note: there is a glitch or a subtle feature in basler line camera:" << std::endl;
            std::cerr << "      - power-cycle camera" << std::endl;
            std::cerr << "      - view colour images: it works" << std::endl;
            std::cerr << "      - view grey-scale images: it works" << std::endl;
            std::cerr << "      - view colour images: it still displays grey-scale" << std::endl;
            std::cerr << "      even in their native viewer you need to set colour image" << std::endl;
            std::cerr << "      repeatedly and with pure luck it works, but we have not" << std::endl;
            std::cerr << "      managed to do it in software; the remedy: power-cycle the camera" << std::endl;
            std::cerr << std::endl;
            return 1;
        }
        verbose = vm.count( "verbose" );
        if( verbose )
        {
            std::cerr << "basler-cat: PYLON_ROOT=" << ::getenv( "PYLON_ROOT" ) << std::endl;
            std::cerr << "basler-cat: GENICAM_ROOT_V2_1=" << ::getenv( "GENICAM_ROOT_V2_1" ) << std::endl;
            std::cerr << "basler-cat: initializing camera..." << std::endl;
        }
        Pylon::PylonAutoInitTerm auto_init_term;
        Pylon::CTlFactory& factory = Pylon::CTlFactory::GetInstance();
        Pylon::ITransportLayer* transport_layer( Pylon::CTlFactory::GetInstance().CreateTl( Pylon::CBaslerGigECamera::DeviceClass() ) );        
        if( !transport_layer )
        { 
            std::cerr << "basler-cat: failed to create transport layer" << std::endl;
            std::cerr << "            most likely PYLON_ROOT and GENICAM_ROOT_V2_1 environment variables not set" << std::endl;
            std::cerr << "            point them to your pylon installation, e.g:" << std::endl;
            std::cerr << "            export PYLON_ROOT=/opt/pylon" << std::endl;
            std::cerr << "            export GENICAM_ROOT_V2_1=/opt/pylon/genicam" << std::endl;
            return 1;
        }
        if( vm.count( "list-cameras" ) )
        {
            Pylon::DeviceInfoList_t devices;
            factory.EnumerateDevices( devices );
            for( unsigned int i = 0; i < devices.size(); ++i ) { std::cerr << devices[i].GetFullName() << std::endl; }
            return 0;
        }
        timeout = timeout_seconds * 1000.0;
        std::string filters = comma::join( boost::program_options::collect_unrecognized( parsed.options, boost::program_options::include_positional ), ';' );
        options.header_only = vm.count( "header-only" );
        options.no_header = vm.count( "no-header" );
        csv = comma::csv::options( argc, argv );
        bool chunk_mode =    csv.has_field( "counters" ) // quick and dirty
                          || csv.has_field( "adjusted-t" )
                          || csv.has_field( "line" )
                          || csv.has_field( "line-count" )
                          || csv.has_field( "ticks" )
                          || csv.has_field( "counters/adjusted-t" )
                          || csv.has_field( "counters/line" )
                          || csv.has_field( "counters/line-count" )
                          || csv.has_field( "counters/ticks" );
        if( chunk_mode )
        {
            if( vm.count( "encoder-ticks" ) == 0 ) { std::cerr << "basler-cat: chunk mode, please specify --encoder-ticks" << std::endl; return 1; }
            if( !filters.empty() ) { std::cerr << "basler-cat: chunk mode, cannot handle filters; use: basler-cat | cv-cat <filters> instead" << std::endl; return 1; }
            if( height != 1 && height != std::numeric_limits< unsigned int >::max() ) { std::cerr << "basler-cat: only --height=1 implemented in chunk mode" << std::endl; return 1; }
            height = 1;
            std::vector< std::string > v = comma::split( csv.fields, ',' );
            std::string format;
            for( unsigned int i = 0; i < v.size(); ++i )
            {
                if( v[i] == "t" ) { v[i] = "header/" + v[i]; format += "t"; }
                else if( v[i] == "rows" || v[i] == "cols" || v[i] == "size" || v[i] == "type" ) { v[i] = "header/" + v[i]; format += "ui"; }
                else if( v[i] == "adjusted-t" ) { v[i] = "counters/" + v[i]; format += "t"; }
                else if( v[i] == "line-count" || v[i] == "ticks" ) { v[i] = "counters/" + v[i]; format += "ul"; }
                else if( v[i] == "line" ) { v[i] = "counters/" + v[i]; format += "ui"; }
                else { std::cerr << "basler-cat: expected field, got '" << v[i] << "'" << std::endl; return 1; }
            }
            csv.fields = comma::join( v, ',' );
            csv.full_xpath = true;
            csv.format( format );
        }
        if( !vm.count( "buffer" ) && vm.count( "discard" ) ) { discard = 1; }
        Pylon::CBaslerGigECamera camera;
        if( vm.count( "address" ) )
        {
            Pylon::CBaslerGigEDeviceInfo info;
            info.SetIpAddress( address.c_str() );
            camera.Attach( factory.CreateDevice( info ) );
        }
        else
        {
            Pylon::DeviceInfoList_t devices;
            factory.EnumerateDevices( devices );
            if( devices.empty() ) { std::cerr << "basler-cat: no camera found" << std::endl; return 1; }
            std::cerr << "basler-cat: will connect to the first of " << devices.size() << " found device(s):" << std::endl;
            for( unsigned int i = 0; i < devices.size(); ++i ) { std::cerr << "    " << devices[i].GetFullName() << std::endl; }
            camera.Attach( transport_layer->CreateDevice( devices[0] ) );
        }
        if( verbose ) { std::cerr << "basler-cat: initialized camera" << std::endl; }
        if( verbose ) { std::cerr << "basler-cat: opening camera " << camera.GetDevice()->GetDeviceInfo().GetFullName() << "..." << std::endl; }
        camera.Open();
        if( verbose ) { std::cerr << "basler-cat: opened camera " << camera.GetDevice()->GetDeviceInfo().GetFullName() << std::endl; }
        Pylon::CBaslerGigECamera::StreamGrabber_t grabber( camera.GetStreamGrabber( 0 ) );
        grabber.Open();
        unsigned int channels;
        switch( options.get_header().type ) // quick and dirty
        {
            case CV_8UC1:
                channels = set_pixel_format_( camera, Basler_GigECamera::PixelFormat_Mono8 );
                break;
            case CV_8UC3:
                channels = set_pixel_format_( camera, Basler_GigECamera::PixelFormat_RGB8Packed );
                break;
            default:
                std::cerr << "basler-cat: type \"" << options.type << "\" not implemented or not supported by camera" << std::endl;
                return 1;
        }
        unsigned int max_width = camera.Width.GetMax();
        if( offset_x >= max_width ) { std::cerr << "basler-cat: expected --offset-x less than " << max_width << ", got " << offset_x << std::endl; return 1; }
        camera.OffsetX.SetValue( offset_x );
        width = ( ( unsigned long long )( offset_x ) + width ) < max_width ? width : max_width - offset_x;
        camera.Width.SetValue( width );
        unsigned int max_height = camera.Height.GetMax();
        //if( height < 512 ) { std::cerr << "basler-cat: expected height greater than 512, got " << height << std::endl; return 1; }
        
        // todo: is the colour line 2098 * 3 or ( 2098 / 3 ) * 3 ?
        //offset_y *= channels;
        //height *= channels;
        
        if( offset_y >= max_height ) { std::cerr << "basler-cat: expected --offset-y less than " << max_height << ", got " << offset_y << std::endl; return 1; }
        camera.OffsetY.SetValue( offset_y );
        height = ( ( unsigned long long )( offset_y ) + height ) < max_height ? height : ( max_height - offset_y );
        camera.Height.SetValue( height );
        if( verbose ) { std::cerr << "basler-cat: set width,height to " << width << "," << height << std::endl; }
        if( vm.count( "packet-size" ) ) { camera.GevSCPSPacketSize.SetValue( packet_size ); }
        // todo: giving up... the commented code throws, but failure to stop acquisition, if active
        //       seems to lead to the following scenario:
        //       - power-cycle camera
        //       - view colour images: it works
        //       - view grey-scale images: it works
        //       - view colour images: it still displays grey-scale
        //if( verbose ) { std::cerr << "basler-cat: getting aquisition status... (frigging voodoo...)" << std::endl; }
        //GenApi::IEnumEntry* acquisition_status = camera.AcquisitionStatusSelector.GetEntry( Basler_GigECamera::AcquisitionStatusSelector_AcquisitionActive );
        //if( acquisition_status && GenApi::IsAvailable( acquisition_status ) && camera.AcquisitionStatus() )
        //{
        //    if( verbose ) { std::cerr << "basler-cat: stopping aquisition..." << std::endl; }
        //    camera.AcquisitionStop.Execute();
        //    if( verbose ) { std::cerr << "basler-cat: aquisition stopped" << std::endl; }
        //}
        
        // todo: a hack for now
        GenApi::IEnumEntry* acquisitionStart = camera.TriggerSelector.GetEntry( Basler_GigECamera::TriggerSelector_AcquisitionStart );
        if( acquisitionStart && GenApi::IsAvailable( acquisitionStart ) )
        {
            camera.TriggerSelector.SetValue( Basler_GigECamera::TriggerSelector_AcquisitionStart );
            camera.TriggerMode.SetValue( frame_trigger.empty() ? Basler_GigECamera::TriggerMode_Off : Basler_GigECamera::TriggerMode_On );
        }
        GenApi::IEnumEntry* frameStart = camera.TriggerSelector.GetEntry( Basler_GigECamera::TriggerSelector_FrameStart );
        if( frameStart && GenApi::IsAvailable( frameStart ) )
        {
            //if( frame_trigger.empty() ) { frame_trigger = line_trigger; }
            if( frame_trigger.empty() )
            {
                camera.TriggerSelector.SetValue( Basler_GigECamera::TriggerSelector_FrameStart );
                camera.TriggerMode.SetValue( Basler_GigECamera::TriggerMode_Off );
            }
            else
            {
                camera.TriggerSelector.SetValue( Basler_GigECamera::TriggerSelector_FrameStart );
                camera.TriggerMode.SetValue( Basler_GigECamera::TriggerMode_On );
                Basler_GigECamera::TriggerSourceEnums t;
                if( frame_trigger == "line1" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_Line1 ); }
                if( frame_trigger == "line2" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_Line2 ); }
                if( frame_trigger == "line3" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_Line3 ); }
                else if( frame_trigger == "encoder" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_ShaftEncoderModuleOut ); }
                else { std::cerr << "basler-cat: frame trigger '" << frame_trigger << "' not implemented or invalid" << std::endl; return 1; }
                camera.TriggerActivation.SetValue( Basler_GigECamera::TriggerActivation_RisingEdge );
                camera.TriggerSelector.SetValue( Basler_GigECamera::TriggerSelector_LineStart );
                camera.TriggerMode.SetValue( Basler_GigECamera::TriggerMode_On );
                camera.TriggerActivation.SetValue( Basler_GigECamera::TriggerActivation_RisingEdge );
                if( frame_trigger == "encoder" )
                {
                    // todo: make configurable
                    camera.ShaftEncoderModuleLineSelector.SetValue( Basler_GigECamera::ShaftEncoderModuleLineSelector_PhaseA );
                    camera.ShaftEncoderModuleLineSource.SetValue( Basler_GigECamera::ShaftEncoderModuleLineSource_Line1 );
                    camera.ShaftEncoderModuleLineSelector.SetValue( Basler_GigECamera::ShaftEncoderModuleLineSelector_PhaseB );
                    camera.ShaftEncoderModuleLineSource.SetValue( Basler_GigECamera::ShaftEncoderModuleLineSource_Line2 );
                    camera.ShaftEncoderModuleCounterMode.SetValue( Basler_GigECamera::ShaftEncoderModuleCounterMode_FollowDirection );
                    camera.ShaftEncoderModuleMode.SetValue( Basler_GigECamera::ShaftEncoderModuleMode_ForwardOnly );
                    camera.ShaftEncoderModuleCounterMax.SetValue( encoder_ticks - 1 );
                    /// @todo compensate for mechanical jitter, if needed
                    ///       see Runner_Users_manual.pdf, 8.3, Case 2
                    camera.ShaftEncoderModuleReverseCounterMax.SetValue( 0 );
                    camera.ShaftEncoderModuleCounterReset.Execute();
                    camera.ShaftEncoderModuleReverseCounterReset.Execute();
                }
            }
        }
        GenApi::IEnumEntry* lineStart = camera.TriggerSelector.GetEntry( Basler_GigECamera::TriggerSelector_LineStart );
        if( lineStart && GenApi::IsAvailable( lineStart ) )
        {
            if( line_trigger.empty() )
            {
                camera.TriggerSelector.SetValue( Basler_GigECamera::TriggerSelector_LineStart );
                camera.TriggerMode.SetValue( Basler_GigECamera::TriggerMode_Off );
            }
            else
            {
                camera.TriggerSelector.SetValue( Basler_GigECamera::TriggerSelector_LineStart );
                camera.TriggerMode.SetValue( Basler_GigECamera::TriggerMode_On );
                Basler_GigECamera::TriggerSourceEnums t;
                if( line_trigger == "line1" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_Line1 ); }
                else if( line_trigger == "line2" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_Line2 ); }
                else if( line_trigger == "line3" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_Line3 ); }
                else if( line_trigger == "encoder" ) { camera.TriggerSource.SetValue( Basler_GigECamera::TriggerSource_ShaftEncoderModuleOut ); }
                else { std::cerr << "basler-cat: line trigger '" << line_trigger << "' not implemented or invalid" << std::endl; return 1; }
                camera.TriggerActivation.SetValue( Basler_GigECamera::TriggerActivation_RisingEdge );
                camera.TriggerSelector.SetValue( Basler_GigECamera::TriggerSelector_LineStart );
                camera.TriggerMode.SetValue( Basler_GigECamera::TriggerMode_On );
                camera.TriggerActivation.SetValue( Basler_GigECamera::TriggerActivation_RisingEdge );
            }
        }
        if( chunk_mode )
        {
            std::cerr << "basler-cat: setting chunk mode..." << std::endl;
            if( !GenApi::IsWritable( camera.ChunkModeActive ) ) { std::cerr << "basler-cat: camera does not support chunk features" << std::endl; camera.Close(); return 1; }
            camera.ChunkModeActive.SetValue( true );
            camera.ChunkSelector.SetValue( Basler_GigECameraParams::ChunkSelector_Framecounter );
            camera.ChunkEnable.SetValue( true );
            camera.ChunkSelector.SetValue( Basler_GigECameraParams::ChunkSelector_Timestamp );
            camera.ChunkEnable.SetValue( true );
            camera.ChunkSelector.SetValue( Basler_GigECameraParams::ChunkSelector_LineTriggerIgnoredCounter );
            camera.ChunkEnable.SetValue( true );
            camera.ChunkSelector.SetValue( Basler_GigECameraParams::ChunkSelector_FrameTriggerIgnoredCounter );
            camera.ChunkEnable.SetValue( true );
            camera.ChunkSelector.SetValue( Basler_GigECameraParams::ChunkSelector_LineTriggerEndToEndCounter );
            camera.ChunkEnable.SetValue( true );
            camera.ChunkSelector.SetValue( Basler_GigECameraParams::ChunkSelector_FrameTriggerCounter );
            camera.ChunkEnable.SetValue( true );
            camera.ChunkSelector.SetValue( Basler_GigECameraParams::ChunkSelector_FramesPerTriggerCounter );
            camera.ChunkEnable.SetValue( true );
            parser = camera.CreateChunkParser();
            if( !parser ) { std::cerr << "basler-cat: failed to create chunk parser" << std::endl; camera.Close(); return 1; }
            std::cerr << "basler-cat: set chunk mode" << std::endl;
        }
        camera.ExposureMode.SetValue( Basler_GigECamera::ExposureMode_Timed );
        if( vm.count( "exposure" ) ) { camera.ExposureTimeRaw.SetValue( exposure ); } // todo? auto exposure (see ExposureAutoEnums)
        if( vm.count( "gain" ) )
        { 
            camera.GainSelector.SetValue( Basler_GigECamera::GainSelector_All );
            camera.GainRaw.SetValue( gain );
            if( channels == 3 ) // todo: make configurable; also is not setting all not enough?
            {
                camera.GainSelector.SetValue( Basler_GigECamera::GainSelector_Red );
                camera.GainRaw.SetValue( gain );
                camera.GainSelector.SetValue( Basler_GigECamera::GainSelector_Green );
                camera.GainRaw.SetValue( gain );
                camera.GainSelector.SetValue( Basler_GigECamera::GainSelector_Blue );
                camera.GainRaw.SetValue( gain );
            }
        }
        if( vm.count( "line-rate" ) ) { camera.AcquisitionLineRateAbs.SetValue( line_rate ); }
        if( vm.count( "test-colour" ) ) { camera.TestImageSelector.SetValue( Basler_GigECamera::TestImageSelector_Testimage6 ); }
        else { camera.TestImageSelector.SetValue( Basler_GigECamera::TestImageSelector_Off ); }
        unsigned int payload_size = camera.PayloadSize.GetValue();
        if( verbose )
        { 
            std::cerr << "basler-cat: camera mtu size: " << camera.GevSCPSPacketSize.GetValue() << std::endl;
            std::cerr << "basler-cat: exposure: " << camera.ExposureTimeRaw.GetValue() << std::endl;
            std::cerr << "basler-cat: payload size: " << payload_size << std::endl;
        }
        std::vector< std::vector< char > > buffers( 2 ); // todo? make number of buffers configurable
        for( std::size_t i = 0; i < buffers.size(); ++i ) { buffers[i].resize( payload_size ); }
        grabber.MaxBufferSize.SetValue( buffers[0].size() );
        grabber.SocketBufferSize.SetValue( 127 );
        if( verbose )
        { 
            std::cerr << "basler-cat: socket buffer size: " << grabber.SocketBufferSize.GetValue() << std::endl;
            std::cerr << "basler-cat: max buffer size: " << grabber.MaxBufferSize.GetValue() << std::endl;
        }
        grabber.MaxNumBuffer.SetValue( buffers.size() ); // todo: use --buffer value for number of buffered images
        grabber.PrepareGrab(); // image size now must not be changed until FinishGrab() is called.
        std::vector< Pylon::StreamBufferHandle > buffer_handles( buffers.size() );
        for( std::size_t i = 0; i < buffers.size(); ++i )
        { 
            buffer_handles[i] = grabber.RegisterBuffer( &buffers[i][0], buffers[i].size() );
            grabber.QueueBuffer( buffer_handles[i], NULL );
        }
        if( chunk_mode )
        {
            snark::tbb::bursty_reader< ChunkPair > read( boost::bind( &capture_< ChunkPair >, boost::ref( camera ), boost::ref( grabber ) ), discard );
            tbb::filter_t< ChunkPair, void > write( tbb::filter::serial_in_order, boost::bind( &write_, _1 ) );
            snark::tbb::bursty_pipeline< ChunkPair > pipeline;
            camera.AcquisitionMode.SetValue( Basler_GigECamera::AcquisitionMode_Continuous );
            camera.AcquisitionStart.Execute(); // continuous acquisition mode        
            if( verbose ) { std::cerr << "basler-cat: running in chunk mode..." << std::endl; }
            pipeline.run( read, write );
            if( verbose ) { std::cerr << "basler-cat: shutting down..." << std::endl; }
            camera.AcquisitionStop();
            camera.DestroyChunkParser( parser );
        }
        else
        {
            snark::cv_mat::serialization serialization( options );
            snark::tbb::bursty_reader< Pair > reader( boost::bind( &capture_< Pair >, boost::ref( camera ), boost::ref( grabber ) ), discard );
            snark::imaging::applications::pipeline pipeline( serialization, filters, reader );
            camera.AcquisitionMode.SetValue( Basler_GigECamera::AcquisitionMode_Continuous );
            camera.AcquisitionStart.Execute(); // continuous acquisition mode        
            if( verbose ) { std::cerr << "basler-cat: running..." << std::endl; }
            pipeline.run();
            if( verbose ) { std::cerr << "basler-cat: shutting down..." << std::endl; }
            camera.AcquisitionStop();
        }
        if( verbose ) { std::cerr << "basler-cat: acquisition stopped" << std::endl; }
        is_shutdown = true;
        while( !done ) { boost::thread::sleep( boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds( 100 ) ); }
        grabber.FinishGrab();
        Pylon::GrabResult result;
        while( grabber.RetrieveResult( result ) ); // get all buffers back
        for( std::size_t i = 0; i < buffers.size(); ++i ) { grabber.DeregisterBuffer( buffer_handles[i] ); }
        grabber.Close();
        camera.Close();
        if( verbose ) { std::cerr << "basler-cat: done" << std::endl; }
        return 0;
    }
    catch( std::exception& ex ) { std::cerr << "basler-cat: " << ex.what() << std::endl; }
    catch( ... ) { std::cerr << "basler-cat: unknown exception" << std::endl; }
    return 1;
}
예제 #4
0
int main(int argc, char* argv[])
{
  // The exit code of the sample application
  int exitCode = 0;

  // Automagically call PylonInitialize and PylonTerminate to ensure the
  // pylon runtime system is initialized during the lifetime of this object.
  Pylon::PylonAutoInitTerm autoInitTerm;

  CTlFactory *_TlFactory = NULL;
  int nTransportLayers;
  TlInfoList_t transportLayers;
  TlInfoList::const_iterator tl_it;
  ITransportLayer* tl_;
  Pylon::DeviceInfoList_t devices;
  int nCameras = 0;
  Pylon::DeviceInfoList_t::const_iterator it;
  //CDeviceInfo devInfo;
  Camera_t::DeviceInfo_t devInfo;
  IPylonDevice *pDevice = NULL;
  Camera_t *bCamera;
  scoped_ptr<Camera_t> scoped_bCamera;

  //FIXME: this arguments haven't been checked
  Pylon::String_t pylon_camera_ip(argv[1]);
  Pylon::String_t devInfoSource(argv[2]);
  Pylon::String_t devInfoIterator("it");
  int devInfoOptions = 0;
  if (devInfoSource == "")
  {
    cout << "Second argument not specified, using default" << endl;
    devInfoSource = devInfoIterator;
  }
  if (devInfoSource == "it")
  {
    cout << "To build the objects, the iterator reference will be used" << endl;
    devInfoOptions = 1;
  }
  else if (devInfoSource == "devInfo")
  {
    cout << "To build the objects, the devInfo object will be used" << endl;
    devInfoOptions = 2;
  }
  else
  {
    cout << "invalid device information source" << endl;
    goto exit;
  }

goto continueNormal;

exit://Moved from the bottom to avoid declarations with
     //initialisations in the middle.
  cout << "exit(" << exitCode << ")" << endl;
  try
  {
    _TlFactory->ReleaseTl(tl_);
  }
  catch(exception& e)
  {
    cout << "couldn't release the transport layer" << endl;
  }
  try
  {
    scoped_bCamera.reset();
  }
  catch(exception& e)
  {
    cout << "couldn't reset the scoped_ptr" << endl;
  }
  cout << endl;
  return exitCode;

continueNormal:
  VersionInfo pylonVersionInfo;
  cout << endl << "Working with Pylon version " \
       << pylonVersionInfo.getMajor() << " (" \
       << pylonVersionInfo.getVersionString() << ")" << endl;

  cout << endl << "Get factory instance" << endl;
  _TlFactory = &CTlFactory::GetInstance();
  nTransportLayers = _TlFactory->EnumerateTls(transportLayers);
  cout << "Available "<< nTransportLayers <<" transport layers" << endl;
  for (tl_it = transportLayers.begin(); tl_it != transportLayers.end();tl_it++)
  {
    const Pylon::CTlInfo& tl_info = \
              static_cast<const Pylon::CTlInfo&>(*tl_it);
    cout << "\t- " << tl_info.GetFullName() << endl;
  }

  cout << endl << "Create a transport layer to access " \
      << Camera_t::DeviceClass() << " cameras" << endl;
  tl_ = _TlFactory->CreateTl( Camera_t::DeviceClass() );

  nCameras = tl_->EnumerateDevices( devices );
  cout << "Found " << nCameras << " cameras" << endl;
  if (nCameras == 0)
  {
    exitCode = -1;
    goto exit;
  }
  cout << "\tIterate searching " << pylon_camera_ip << " camera"
      << endl;
  for (it = devices.begin(); it != devices.end(); it++)
  {
    const Camera_t::DeviceInfo_t& gige_device_info = \
        static_cast<const Camera_t::DeviceInfo_t&>(*it);
    Pylon::String_t current_ip = gige_device_info.GetIpAddress();
    cout << "\t\t- Found a " << gige_device_info.GetModelName() << " (" \
        << gige_device_info.GetSerialNumber() << ")" \
        << " with ip " << current_ip << endl;
    if (current_ip == pylon_camera_ip)
    {
      cout << "\t\t\t** This is the camera wanted (" << current_ip << ") **"
          << endl;
      devInfo = gige_device_info;
      break;
    }
  }
  if (it == devices.end())
  {
    cout << "\t\tCamera not found" << endl;
    exitCode = -2;
    goto exit;
  }
  cout << endl << "Wanted camera information:" << endl;
  cout << "\t- FullName: \"" << devInfo.GetFullName() \
      << "\""<< endl;
  cout << "\t- SerialNumber: \"" << devInfo.GetSerialNumber() \
        << "\""<< endl;
  cout << "\t- ModelName: \"" << devInfo.GetModelName() \
      << "\""<< endl;
  cout << "\t- DeviceClass: \"" << devInfo.GetDeviceClass() \
      << "\""<< endl;
  cout << "\t- DeviceVersion: \"" << devInfo.GetDeviceVersion() \
      << "\""<< endl;
  cout << "\t- DeviceFactory: \"" << devInfo.GetDeviceFactory() \
      << "\""<< endl;
  cout << "\t- Interface: \"" << devInfo.GetInterface() \
      << "\""<< endl;

  cout << endl << "Connect to the Camera for further control" << endl;

  try
  {
    cout << "Build and attach in one step" << endl;

    if (devInfoOptions == 1)
    {
      bCamera = new Camera_t(_TlFactory->CreateDevice(*it));
    }
    else
    {
      bCamera = new Camera_t(_TlFactory->CreateDevice(devInfo));
    }
    scoped_bCamera.reset(bCamera);
  }
  catch(exception& e)
  {
    cout << "\tIt doesn't work!\n\t" << e.what() << endl \
         << "Try an alternative" << endl;
    try
    {
      cout << "\tFirst build..." << endl;
      bCamera = new Camera_t();
      scoped_ptr<Camera_t> camera(new Camera_t());
      scoped_bCamera.reset(bCamera);
      cout << "\tThen attach..." << endl;
      if (devInfoOptions == 1)
      {
        bCamera->Attach(_TlFactory->CreateDevice(*it));
      }
      else
      {
        bCamera->Attach(_TlFactory->CreateDevice(devInfo));
      }
    }
    catch(exception& e)
    {
      cout << "\t\tFailed!\n\t" << e.what() << endl;
      exitCode = -3;
      goto exit;
    }
  }

  if (scoped_bCamera.get() == NULL)
  {
    cout << "\t* Camera object points to NULL" << endl;
    exitCode = -4;
    goto exit;
  }
  else if (not scoped_bCamera.get()->IsAttached())
  {
    cout << "\t* Camera object build but not attached to a Device object" \
         << endl;
    exitCode = -5;
    goto exit;
  }

  pDevice = scoped_bCamera.get()->GetDevice();
  if (!pDevice)
  {
    cout << "\tPylon Device points to NULL" << endl;
    exitCode = -6;
    goto exit;
  }

  cout << endl << "Play with the build objects" << endl;
  cout << "\t- Pylon device has " << pDevice->GetNumStreamGrabberChannels() \
       << " stream grabber channels" << endl;
  Camera_t::TlParams_t TlParams(scoped_bCamera->GetTLNodeMap());
  cout << "\t- TL read timeout:" << dec << TlParams.ReadTimeout.GetValue() \
       << endl;
  cout << "\t- TL write timeout:" << dec << TlParams.WriteTimeout.GetValue() \
       << endl;
  cout << "\t- TL heartbeat timeout:" << dec \
       << TlParams.HeartbeatTimeout.GetValue() << endl;

  cout << "\t- Open Pylon Device" << endl;
  pDevice->Open();
  if (not scoped_bCamera.get()->IsOpen())
  {
    cout << "\t* Open the Device object didn't show the Camera Object open" \
         << endl;
    exitCode = -7;
    goto exit;
  }

  cout << endl << "Information requested directly to the camera:" << endl;
  cout << "\t\t- Firmware version: " \
          << scoped_bCamera.get()->DeviceFirmwareVersion.GetValue() << endl;

//close: //TODO: label to be used in the checks after the communication is open.
  cout << "\tClose Pylon Device" << endl;
  pDevice->Close();
  cout << "\tDetele Pylon Device object" << endl;
  _TlFactory->DestroyDevice(pDevice);
  goto exit;//with exitCode = 0, that means "everything went well"!
}