close

pylon C and GenApi

The pylon C API builds upon GenApi, a software framework that provides a high-level API for generic access to all compliant digital cameras, hiding the peculiarities of the particular interface technology used. Accordingly, the application developer can focus on the functional aspects of the program to be developed. Due to the abstraction provided by GenApi, programs need not be adjusted to work with different types of camera interfaces.(例如使用area camera和linescan camera幾乎感覺一模一樣, 因為兩者的差異已經在GenAPI處理掉了, 使用者只需要專注在收到影像像素後的處理) Even applications can be addressed where different camera interfaces are used at the same time.The dependency of pylon C upon GenApi shows in some places, mostly where names of functions or other entities start with a GenApi prefix. Wherever this is the case, an element of the underlying GenApi layer is directly exposed to the pylon C user.

Objects and Handles

The pylon C API defines several data entities termed 'objects'. These are used to expose certain aspects of the pylon C functionality to the user. For example, there is a stream grabber object that serves the purpose of receiving image data streamed by a camera (which, in turn, is also represented by an object called a camera object).

Inside a program, every object is represented and uniquely identified by a handle.(程式碼中每個物件都會以一個唯一的handle來表示, 如此一來才能分辨是哪個物件) A function performing an action that involves an object is passed a handle for that object.Handles are type-safe, which is to say that handles representing different kinds of objects are of different types. Accordingly, the C language type system is able to detect errors such as passing a wrong kind of object to a function call.Furthermore, handles are unique in the sense that no two handles representing two different objects will ever be equal when they are compared. This is even true if the comparison is made between two handles of different types after they were forcefully cast to a common type.

Camera Objects

In pylon C, physical camera devices are represented by camera objects (sometimes also referred to as device objects). A camera object handle has the type of PYLON_DEVICE_HANDLE.

A camera object is used for:

  • Establishing communication with a camera (i.e., opening the camera object)
  • Accessing the camera's parameters (to query or change its configuration, see Parameters below)
  • Obtaining a stream grabber object used for grabbing images (see Stream Grabbers below)
  • Obtaining an event grabber object used for retrieving event messages (see Event Grabbers below)
  • Obtaining a chunk parser object used for analyzing a self-descriptive, structured data stream (see Chunk Parsers below)

Transport Layers

The term 'transport layer' is used as an abstraction for a physical interface such as FireWire, Gigabit Ethernet (GigE) or Camera Link. For each of these interfaces, there are drivers that provide access to camera devices. As an abstraction of these drivers, a transport layer provides the following functionality:

以下哪些情況會跟transport layers有關呢?

  • Device discovery (also called device enumeration)  一旦發現裝置會給予一個裝置編號0,1,2,....
  • Reading and writing camera registers
  • Grabbing images
  • Retrieving event messages
  • Configuring the transport layer itself (e.g. timeouts)
  • Creating camera objects
  • Deleting camera objects

pylon C currently includes three different transport layers:

  • PylonGigE for Gigabit Ethernet cameras using the GigE Vision protocol
  • Pylon1394 for IIDC 1394 compliant FireWire cameras
  • PylonCLSer for Camera Link cameras using the CL serial interface (limited to camera configuration only)

 

傳輸層(transport layer)嚴格來說是一個內部定義的觀念,並沒有所謂傳輸層物件, 但這個觀念對於理解裝置編號(device enumeration)以及資料傳輸會有幫助

A transport layer is strictly an internal concept of the pylon C API that application writers need not be concerned with, as there is no user-visible entity related to it. This means there is no 'transport layer object' in pylon C. As every camera has exactly one transport layer, it is, for all practical purposes, considered an integral part of the camera object. However, being aware of the transport layer concept may be useful for properly understanding device enumeration and communication.

 

Waiting

Typically, pylon C applications are event-driven. This means that such applications, or the threads running within them, will often wait for some condition to become true, for example, a buffer with image data to become available.

pylon C provides a generalized mechanism for applications to wait for externally generated events, based on the concepts of wait objects and wait object containers. Wait objects provide an abstraction layer for operating system-specific synchronization mechanisms. Events in pylon C include image data that become available at a stream grabber (see Retrieving Grabbed Images), or event data that become available at an event grabber. With wait objects, pylon C provides a mechanism for applications to wait for these events. Moreover, applications can create wait objects of their own that can be explicitly signaled.

等待物件容器(wait object containers)包含多個等待物件(wait objects)和等待函式(wait functions), 單一執行緒(thread)可以同時處理多個不同來源觸發事件

Wait objects can be grouped into wait object containers, and wait functions are provided by pylon C for the application to wait until either any one or all wait objects in a container are signaled. This way, events originating from multiple sources can be processed by a single thread.

Wait objects are represented by handles of the PYLON_WAITOBJECT_HANDLE type, while handles of the PYLON_WAITOBJECTS_HANDLE type represent wait object containers.

Stream Grabbers(串流擷取器)

A camera object, as defined by the pylon C architecture, is capable of delivering one or more streams of image data (see below for an exception). To grab images from a stream, a stream grabber object is required. Stream grabber objects cannot be created directly by an application. They are managed by camera objects, which create and pass out stream grabbers. All stream grabbers expose the very same interface, regardless of the transport mechanism they use for data transfer. This means that for all transport layers, images are grabbed from streams in exactly the same way. The details of grabbing images are described in the Grabbing Images section below.

Note:
There may be cameras for which image data support is not implemented in pylon C. Device objects for cameras of this kind will have no stream grabber at all. Such device objects can still be used to access device parameters, grabbing, however, will not be possible. Throughout the remainder of this document it will be assumed that there is at least one image data channel available for every device object.

If a camera is capable of delivering multiple data streams, its device object will provide a stream grabber for each data stream. A device object can report the number of provided stream grabbers. Stream grabber objects are represented by handles of the PYLON_STREAMGRABBER_HANDLE type. Section Grabbing Images describes their use in detail.

Event Grabbers(事件擷取器)

例如[攝影機端]通知電腦影像擷取程序已經完成通知[程式端], 因此程式可以不需要一直等待影像資料傳輸, 而無法做其他事情(咬死)

In addition to sending image data streams, some cameras are capable of sending event messages to inform the application about certain conditions that arise. For example, a camera may send an event message when the image acquisition process is complete within the camera, but before the image data are actually transferred out of the camera. The application might need this information to know when it is safe to start a handling system that moves the next part into position for a subsequent acquisition, without having to wait for the image data to arrive.

Event grabber objects are used to receive event messages. Retrieving and processing event messages is described below in the Handling Camera Events section.

Event grabber objects are represented by handles of the PYLON_EVENTGRABBER_HANDLE type.

 

Chunk Parsers (資料解析器)

chunck模式可以提供串流額外的資訊如影格數和對應的時間(time stamp), 可以透過pylon C chunk進行上述關鍵字資訊提取

If the so-called chunk mode is activated, Basler cameras can send additional information appended to the image data. When chunk mode is enabled, the camera sends an extended data stream consisting of the image data combined with additional information, such as a frame number or a time stamp. The extended data stream is self-descriptive. pylon C chunk parser objects are used for parsing the extended data stream and for providing access to the additional information. Use of chunk parser objects is explained in the Chunk Parser: Accessing Chunk Features section.

Chunk parser objects are represented by handles of the PYLON_CHUNKPARSER_HANDLE type.

 

Parameters

參數設定分為可/不可讀或可/不可寫

The behavior of some kinds of objects (camera objects in particular) can be controlled by the application through a set of related parameters (sometimes also called features). Parameters are named entities having a value that may or may not be readable or writable by the application. Writing a new value to an object's parameter will generally modify the behavior of that object.

Every parameter has an associated type. There are currently six different types defined:

參數(parameter)可能的資料格式如下:

Integer格式: 如影像寬度, 高度

Float格式: 如曝光時間(秒)

boolean格式: 如是否致能(enable)外部觸發訊號

String格式: 攝影機種類(type designator)或是攝影機序號(serial number)

Enumeration格式:順序清單(ordered list), 其排序可以是根據英文字(text string)或索引編號(index)

Command格式:通知某個攝影機裝置進行某個動作

  • Integer - An integer parameter represents a feature that can be set by an integer number, such as a camera's image width or height in pixels. The current value of an integer parameter is augmented by a minimum and a maximum value, defining a range of allowed values for the parameter, and an increment that acts as a 'step width' for changes to the parameter's value. The set of all allowed values for an integer parameter can hence be expressed as x := {minimum} + N * {increment}, with N = 0,1,2 ..., x <= {maximum}.The current value, minimum, maximum, and increment can all be accessed as 64 bit values via functions provided by pylon C for this purpose.
  • Float - A float parameter represents a feature that can be set by a floating-point value, such as a camera's exposure time expressed in seconds. It resembles the integer parameter with two exceptions: all values are of the 'double' type (double precision floating point numbers as defined by the IEEE 754 standard), and there is no increment value. Hence, a float parameter is allowed to take any value from the interval {minimum} <= x <={maximum}.
  • Boolean - A boolean parameter represents a binary-valued feature, which, can be enabled or disabled. pylon C provides functions for checking the current state and setting the parameter. An example for a boolean parameter would be a 'switch' to enable or disable a particular feature, such as a camera's external trigger input.
  • String - The parameter's value is a text string like, for example, a camera's type designator or its serial number.
  • Enumeration - The parameter can take any value from a predefined set. The set of possible values is organized as an ordered list, such that any value can be identified by a both name (text string) and an index (integer number).
  • Command - A command parameter represents an executable feature, a provides a way of telling an object to perform a certain action. The operation thus triggered may need some time to execute, and will eventually terminate. An example is the 'perform white balance auto calibration' command that may be available for a color camera. A command parameter can be queried for its execution state (whether the command is still executing or has already terminated).

Every parameter also has an associated access mode that determines the kind of access allowed. There are currently four access modes defined:

  • Implemented - A parameter with the given name actually exists, because the object does implement the related feature. Some features are only available for certain devices and not for others. For example, a monochrome camera will not have a white balance feature, and consequently will not have a parameter named "WhiteBalance".
  • Available - Depending on the object's state, a parameter may be temporarily unavailable. For example, a camera parameter related to external triggering may not be available while the camera is in free run mode. 'Available' implies 'implemented'.
  • Readable - A parameter's value can be read. 'Readable' implies 'available'.
  • Writable - A parameter's value can be changed (set). 'Writable' implies 'available'.

Parameters can be both readable and writable at the same time.

Image Terminology Issues

影像專有名詞:

影像擷取(image acquisition: 攝影機內部產生單張影像的動作

影像資料傳輸(image data transfer): 影像資料從攝影機端搬到電腦端

影像擷取中(image grabbing): 是影像資料寫入電腦端的記憶體

Throughout this document, a distinction is made between image acquisition, image data transfer, and image grabbing. It is essential to understand the exact meaning of these terms.

The operations performed internally by the camera to produce a single image are collectively termed image acquisition. This includes, among other things, controlling exposure of the image sensor and sensor read-out. This process eventually results in the camera being ready to transfer image data out of the camera to the computer. Image data transfer designates the transfer of the aquired data from the camera's memory to the computer through the camera's interface, e.g. FireWire or Gigabit Ethernet. The process of writing the image data to the computer's main memory is referred to as image grabbing.

Programming the pylon C API

Debugging pylon Applications Using GigE Cameras

使用GigE攝影機進行除錯(debugging), 建議設定較長的timeout設定值, 以避免debug時間延遲造成斷線情況發生

When debugging a pylon application using GigE cameras you may encounter heartbeat timeouts. The application must send special network packets to the camera in defined intervals. If the camera doesn't receive these heartbeats it will consider the connection as broken and won't accept any commands from the application. This requires setting the heartbeat timeout of a camera to a higher value when debugging. The build topics section shows how to do this.

Initialization/Uninitialization of the pylon C Runtime Library

The pylon C runtime system must be initialized before use. A pylon based application must call the PylonInitialize() function before using any other functions of the pylon C runtime system.

/* Before using any pylon methods, the pylon runtime must be initialized. */
初始化攝影裝置前
PylonInitialize();

Before an application exits, it must call the PylonTerminate() function to free resources allocated by the pylon C runtime system.

/* ... Shut down the pylon runtime system. Don't call any pylon method after 
   calling PylonTerminate(). */

停止裝置離開程式前,記得先PylonTerminate()

PylonTerminate();

Error Handling

All pylon C API functions return a value of the GENAPIC_RESULT (see Error Codes) type, defined in GenApiCError.h. The return value is GENAPI_E_OK if the function completed normally without detecting any errors. Otherwise, an error code is returned. This will either be one of the GENAPI_E_XXX error codes defined in GenApiCError.h, if the error is detected in the GenApi layer that forms the basis of pylon C, or one of the PYLON_E_XXX error codes defined in PylonCError.h.

In addition to returning an error code, pylon C functions set up a textual error description that applications can retrieve. It consists of two parts that can be accessed via GenApiGetLastErrorMessage() and GenApiGetLastErrorDetail(). The string returned by GenApiGetLastErrorMessage() contains a concise description of the most recent error, suitable to be displayed to the user as part of an error message. Additional error information is returned by GenApiGetLastErrorDetail(); this error information is intended to aid in identifying the conditions that caused the error.

 

This is what a typical error handler might look like:

/* This function demonstrates how to retrieve the error message for the last failed 
   function call. */
void printErrorAndExit( GENAPIC_RESULT errc )
{
    char *errMsg;
    size_t length;

    /* Retrieve the error message. 
    ... First find out how big the buffer must be, */
    GenApiGetLastErrorMessage( NULL, &length );
    errMsg = (char*) malloc( length );
    /* ... and retrieve the message. */
    GenApiGetLastErrorMessage( errMsg, &length );

    fprintf( stderr, "%s (%#08x).\n", errMsg, errc);
    free( errMsg);

    /* Retrieve the more details about the error 
    ... First find out how big the buffer must be, */
    GenApiGetLastErrorDetail( NULL, &length );
    errMsg = (char*) malloc( length );
    /* ... and retrieve the message. */
    GenApiGetLastErrorDetail( errMsg, &length );

    fprintf( stderr, "%s\n", errMsg);
    free( errMsg);
    
    PylonTerminate();  /* Releases all pylon resources */
    pressEnterToExit();

    exit(EXIT_FAILURE);
}


All programming examples use a macro to check for error conditions and conditionally invoke the above error handler:

#define CHECK( errc ) if ( GENAPI_E_OK != errc ) printErrorAndExit( errc )

Enumerating and Creating Camera Objects

In pylon C, camera devices are managed by means of 'camera objects'. A camera object is a software abstraction and is represented by a handle of the PYLON_DEVICE_HANDLE type. Available devices are discovered dynamically, using facilities provided by the transport layer.

裝置搜尋(device discorvery)

1. PylonEnumerateDevices() 回傳所有(不同/相同)介面的裝置數量(numDevices)

2. PylonCreateDeviceByIndex( 0, &hDev ) 取得個裝置編號0 訊息

Device discovery (aka enumeration) is a two-step process. In the first step, the PylonEnumerateDevices() function returns, in its numDevices argument,the total number of camera devices detected for all interfaces. Assuming this value is N, you can then access every camera using a numeric index from the range [0 .. N-1]. In the second step, PylonGetDeviceInfo() is called for every index value in turn. By looking at the fields of the PylonDeviceInfo_t struct, every individual camera can be identified. A call to PylonGetDeviceInfoHandle() then translates the device index to a PYLON_DEVICE_INFO_HANDLE that can be used to query device properties. Finally, a device object (represented by a PYLON_DEVICE_HANDLE) can be created by calling PylonCreateDeviceByIndex(). A PYLON_DEVICE_HANDLE is required for all operations involving a device.

The code snippet below illustrates device enumeration and creation:

/* Enumerate all camera devices. You must call 
PylonEnumerateDevices() before creating a device. */
res = PylonEnumerateDevices( &numDevices );
CHECK(res);
if ( 0 == numDevices )
{
    fprintf( stderr, "No devices found.\n" );
    PylonTerminate();
    pressEnterToExit();
    exit(EXIT_FAILURE);
}

/* Get a handle for the first device found.  */
res = PylonCreateDeviceByIndex( 0, &hDev );
CHECK(res);

If an application is done using a device, the device handle must be destroyed:

/* ...The device is no longer used, destroy it. */
res = PylonDestroyDevice ( hDev );
CHECK(res);

Opening and Closing a Camera

PyloneDeviceOpen() 類似讀寫檔案前開啟fopen()

PylonDeviceClose()   類似讀寫檔案後關閉fclose()

Before access to camera parameters is possible, the transport layer must be initialized and a connection to the physical camera device must be established. This is achieved by calling the PylonDeviceOpen() function.

/* Before using the device, it must be opened. Open it for configuring
parameters and for grabbing images. */
res = PylonDeviceOpen( hDev, PYLONC_ACCESS_MODE_CONTROL | PYLONC_ACCESS_MODE_STREAM );
CHECK(res);

To release the connection to a device, and to free all related resources, call the PylonDeviceClose() function.

/* ... Close and release the pylon device. The stream grabber becomes invalid
   after closing the pylon device. Don't call stream grabber related methods after 
   closing or releasing the device. */
res = PylonDeviceClose( hDev );
CHECK(res);

Camera Configuration


例如
1. 查詢裝置是否有"寬度"屬性: 可
利用PylonDeviceFeatureIsImplemented(hDev, "Width")
2. 查詢是否可取值PylonDeviceFeatureIsAvailable(hDev, "BinningVertical")

3. 查詢裝置的"寬度"屬性值是否可讀? PylonDeviceFeatureIsReadable(hDev, "Width");
4. 查詢裝置的"寬度"屬性值是否可寫? PylonDeviceFeatureIsWritable( hDev, "Width")

This section describes how a camera object is used to configure camera device parameters. For a discussion of all relevant concepts, see Parameters. Parameters are identified by their names. After opening the pylon Viewer, you can easily browse through all parameters that are available for a particular type of camera. This is described in more detail under Browsing Parameters.

All functions that work on parameters respect accessibility. If the desired kind of access is not (currently) possible, error messages are returned accordingly. It is also possible to check for sufficient accessibility beforehand, using one of the following functions: PylonDeviceFeatureIsImplemented(), PylonDeviceFeatureIsAvailable(), PylonDeviceFeatureIsReadable(), or PylonDeviceFeatureIsWritable().

/* This function demonstrates how to check the presence, readability, and writability
   of a feature. */
void demonstrateAccessibilityCheck( PYLON_DEVICE_HANDLE hDev )
{
    _Bool val;  /* Output of the check functions */

    /* Check to see if a feature is implemented at all. */
    val = PylonDeviceFeatureIsImplemented(hDev, "Width");       
    printf("The 'Width' feature %s implemented\n", val ? "is" : "isn't");
    val = PylonDeviceFeatureIsImplemented(hDev, "MyCustomFeature");
    printf("The 'MyCustomFeature' feature %s implemented\n", val ? "is" : "isn't");


    /* Although a feature is implemented by the device, it might not be available
       with the device in its current state. Check to see if the feature is currently 
       available. The PylonDeviceFeatureIsAvailable sets val to 0 if either the feature
       is not implemented or if the feature is not currently available. */

    val = PylonDeviceFeatureIsAvailable(hDev, "BinningVertical");
    printf("The 'BinningVertical' feature %s available\n", val ? "is" : "isn't");

    /* If a feature is available, it could be read-only, write-only, or both
       readable and writable. Use the PylonDeviceFeatureIsReadable() and the
       PylonDeviceFeatureIsWritable() functions(). It is safe to call these functions
       for features that are currently not available or not implemented by the device.
       A feature that is not available or not implemented is neither readable nor writable.
       The readability and writability of a feature can change depending on the current 
       state of the device. For example, the Width parameter might not be writable when
       the camera is acquiring images. */

    
    val = PylonDeviceFeatureIsReadable(hDev, "Width");
    printf("The 'Width' feature %s readable\n", val ? "is" : "isn't");
    val = PylonDeviceFeatureIsImplemented( hDev, "MyCustomFeature");
    printf("The 'MyCustomFeature' feature %s readable\n", val ? "is" : "isn't");

    val = PylonDeviceFeatureIsWritable( hDev, "Width");
    printf("The 'Width' feature %s writable\n", val ? "is" : "isn't");

    printf("\n");
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.取得允許設定最大值 PylonDeviceGetIntegerFeatureMin( hDev, featureName, &min );  /* Get the minimum value. */
2.取得允許設定最小值 PylonDeviceGetIntegerFeatureMax( hDev, featureName, &max );  /* Get the maximum value. */
3.取得目前增量值       PylonDeviceGetIntegerFeatureInc( hDev, featureName, &incr);  /* Get the increment value. */
4.取得目前設定值       PylonDeviceGetIntegerFeature( hDev, featureName, &val );     /* Get the current value. */
5.設定目前設定值 PylonDeviceSetIntegerFeature(hDev, featureName, min + (max - min) / incr / 2 * incr );

The next code snippet demonstrates how to read and set an integer parameter:

/* This function demonstrates how to handle integer camera parameters. */
void demonstrateIntFeature( PYLON_DEVICE_HANDLE hDev )
{
    static const char   featureName[] = "Width";  /* Name of the feature used in this sample: AOI Width */
    int64_t             val, min, max, incr;      /* Properties of the feature */
    GENAPIC_RESULT      res;                      /* Return value */ 


    if ( PylonDeviceFeatureIsReadable(hDev, featureName) )
    {
        /* 
          Query the current value, the allowed value range, and the increment of the feature. 
          For some integer features, you are not allowed to set every value within the 
          value range. For example, for some cameras the Width parameter must be a multiple 
          of 2. These constraints are expressed by the increment value. Valid values 
          follow the rule: val >= min && val <= max && val == min + n * inc. */
        res = PylonDeviceGetIntegerFeatureMin( hDev, featureName, &min );  /* Get the minimum value. */
        CHECK(res); 
        res = PylonDeviceGetIntegerFeatureMax( hDev, featureName, &max );  /* Get the maximum value. */
        CHECK(res);
        res = PylonDeviceGetIntegerFeatureInc( hDev, featureName, &incr);  /* Get the increment value. */
        CHECK(res);
        res = PylonDeviceGetIntegerFeature( hDev, featureName, &val );     /* Get the current value. */
        CHECK(res);

#if __STDC_VERSION__ >= 199901L
        printf("%s: min= %lld  max= %lld  incr=%lld  Value=%lld\n", featureName, min, max, incr, val );
#else
        printf("%s: min= %I64d  max= %I64d  incr=%I64d  Value=%I64d\n", featureName, min, max, incr, val );
#endif

        if ( PylonDeviceFeatureIsWritable(hDev, featureName) )
        {
            /* Set the Width half-way between minimum and maximum. */
            res = PylonDeviceSetIntegerFeature( hDev, featureName, min + (max - min) / incr / 2 * incr );
            CHECK(res);
        }
        else
            fprintf(stderr, "The %s feature is not writable.\n", featureName );
    }
    else
        fprintf(stderr, "The %s feature is not readable.\n", featureName );
}

32 bit variants of the integer access functions are also provided for convenience. These allow to handle the common case where all values are known to be 32 bit entities more easily:

/* The integer functions illustrated above take 64 bit integers as output parameters. There are variants
   of the integer functions that accept 32 bit integers instead. The Get.... functions return
   an error when the value returned by the device doesn't fit into a 32 bit integer. */
void demonstrateInt32Feature( PYLON_DEVICE_HANDLE hDev )
{
    static const char   featureName[] = "Height";  /* Name of the feature used in this sample: AOI height */
    int32_t             val, min, max, incr;       /* Properties of the feature */
    GENAPIC_RESULT      res;                       /* Return value */ 


    if ( PylonDeviceFeatureIsReadable(hDev, featureName) )
    {
        /* 
           Query the current value, the allowed value range, and the increment of the feature. 
           For some integer features, you are not allowed to set every value within the 
           value range. For example, for some cameras the Width parameter must be a multiple 
           of 2. These constraints are expressed by the increment value. Valid values 
           follow the rule: val >= min && val <= max && val == min + n * inc. */
        res = PylonDeviceGetIntegerFeatureMinInt32( hDev, featureName, &min );  /* Get the minimum value. */
        CHECK(res); 
        res = PylonDeviceGetIntegerFeatureMaxInt32( hDev, featureName, &max );  /* Get the maximum value. */
        CHECK(res);
        res = PylonDeviceGetIntegerFeatureIncInt32( hDev, featureName, &incr);  /* Get the increment value. */
        CHECK(res);
        res = PylonDeviceGetIntegerFeatureInt32( hDev, featureName, &val );     /* Get the current value. */
        CHECK(res);
        printf("%s: min= %d  max= %d  incr=%d  Value=%d\n", featureName, min, max, incr, val );

        if ( PylonDeviceFeatureIsWritable(hDev, featureName) )
        {
            /* Set the value to half its maximum  */
            res = PylonDeviceSetIntegerFeatureInt32( hDev, featureName, min + (max - min) / incr / 2 * incr );
            CHECK(res);
        }
        else
            fprintf(stderr, "The %s feature is not writable.\n", featureName );
    }
    else
        fprintf(stderr, "The %s feature is not readable.\n", featureName );
}

Setting float parameters is similar, but there is no increment:

/* Some features are floating point features. This function illustrates how to set and get floating
   point parameters. */
void demonstrateFloatFeature( PYLON_DEVICE_HANDLE hDev )
{
    static const char   featureName[] = "Gamma";  /* The name of the feature used */
    _Bool                isWritable;               /* Is the feature writable? */
    double              min, max, value;          /* Value range and current value */
    GENAPIC_RESULT      res;                      /* Return value */ 

    if ( PylonDeviceFeatureIsReadable(hDev, featureName) )
    {
        /* Query the value range and the current value. */
        res = PylonDeviceGetFloatFeatureMin( hDev, featureName, &min);
        CHECK(res);
        res = PylonDeviceGetFloatFeatureMax( hDev, featureName, &max);
        CHECK(res);
        res = PylonDeviceGetFloatFeature( hDev, featureName, &value );
        CHECK(res);

        printf("%s: min = %4.2f, max = %4.2f, value = %4.2f\n", featureName, min, max, value );

        /* Set the value to half its maximum. */
        isWritable = PylonDeviceFeatureIsWritable(hDev, featureName);
        if ( isWritable )
        {
            value = 0.5 * ( min + max ); 
            printf("Setting %s to %4.2f\n", featureName, value );
            res = PylonDeviceSetFloatFeature( hDev, featureName, value );
            CHECK(res);
        }
        else
            fprintf(stderr, "The %s feature is not writable.\n", featureName );
    }
    else
        fprintf(stderr, "The %s feature is not readable.\n", featureName );
}

Setting boolean parameters is even simpler:

/* Some features are boolean features that can be switched on and off. 
   This function illustrates how to access boolean features. */
void demonstrateBooleanFeature( PYLON_DEVICE_HANDLE hDev )
{
    static const char   featureName[] = "GammaEnable"; /* The name of the feature */
    _Bool                isWritable;                    /* Is the feature writable? */
    _Bool                value;                         /* The value of the feature */
    GENAPIC_RESULT      res;                           /* Return value */ 

    /* Check to see if the feature is writable. */
    isWritable = PylonDeviceFeatureIsWritable(hDev, featureName);

    if ( isWritable )
    {
        /* Retrieve the current state of the feature. */
        res = PylonDeviceGetBooleanFeature( hDev, featureName, &value);
        CHECK(res);
        printf("The %s features is %s\n", featureName, value ? "on" : "off" );

        /* Set a new value. */
        value = (_Bool) !value;  /* New value */
        printf("Switching the %s feature %s\n", featureName, value ? "on" : "off" );
        res = PylonDeviceSetBooleanFeature( hDev, featureName, value );
        CHECK(res);

    }
    else
        printf("The %s feature isn't writable\n", featureName );
}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1. 取得攝影機像素格式:                         PylonDeviceFeatureToString( hDev, "PixelFormat", value, &len );
2. 判斷攝影機像素格式是否支援 xxx格式: PylonDeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8")
3. 判斷像素格式參數是否可以寫入: PylonDeviceFeatureIsWritable(hDev, "PixelFormat")
4. 設定像素格式參數"Mono16": PylonDeviceFeatureFromString( hDev, "PixelFormat", "Mono16" )
5. 設定像素格式參數"YUV422Packed": PylonDeviceFeatureFromString( hDev, "PixelFormat", "YUV422Packed" )

An enumeration parameter can only be set to one of the members of a predefined set:

/* There are camera features that behave like enumerations. These features can take a value from a fixed 
   set of possible values. One example is the pixel format feature. This function illustrates how to deal with 
   enumeration features. 

*/
void demonstrateEnumFeature( PYLON_DEVICE_HANDLE hDev )
{
    char                value[64];                     /* The current value of the feature */
    size_t              len;                           /* The length of the string */
    GENAPIC_RESULT      res;                           /* Return value */ 
    _Bool                isWritable, 
                        supportsMono8,
                        supportsYUV422Packed,
                        supportsMono16;


    /* The allowed values for an enumeration feature are represented as strings. Use the 
    PylonDeviceFeatureFromString() and PylonDeviceFeatureToString() methods for setting and getting
    the value of an enumeration feature. */


    /* Get the current value of the enumeration feature. */
    len = sizeof(value);
    res = PylonDeviceFeatureToString( hDev, "PixelFormat", value, &len );
    CHECK(res);

    printf("PixelFormat: %s\n", value);

    /*
      For an enumeration feature, the pylon Viewer's "Feature Documentation" window lists the the
      names of the possible values. Some of the values might not be supported by the device. 
      To check if a certain "SomeValue" value for a "SomeFeature" feature can be set, call the 
      PylonDeviceFeatureIsAvailable() function with "EnumEntry_SomeFeature_SomeValue" as an argument. 
    */
    /* Check to see if the Mono8 pixel format can be set. */
    supportsMono8 = PylonDeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8");
    printf("Mono8 %s a supported value for the PixelFormat feature\n", supportsMono8 ? "is" : "isn't");
    
    /* Check to see if the YUV422Packed pixel format can be set. */
    supportsYUV422Packed = PylonDeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_YUV422Packed");
    printf("YUV422Packed %s a supported value for the PixelFormat feature\n", supportsYUV422Packed ? "is" : "isn't");

    /* Check to see if the Mono16 pixel format can be set. */
    supportsMono16 = PylonDeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono16");
    printf("Mono16 %s a supported value for the PixelFormat feature\n", supportsMono16 ? "is" : "isn't");


    /* Before writing a value, we recommend checking to see if the enumeration feature is
       currently writable. */ 
    isWritable = PylonDeviceFeatureIsWritable(hDev, "PixelFormat");
    if ( isWritable )
    {
        /* The PixelFormat feature is writable, set it to one of the supported values. */
        if ( supportsMono16 )
        {
            printf("Setting PixelFormat to Mono16\n");
            res = PylonDeviceFeatureFromString( hDev, "PixelFormat", "Mono16" );
            CHECK(res);
        }
        else if ( supportsYUV422Packed )
        {
            printf("Setting PixelFormat to YUV422Packed\n");
            res = PylonDeviceFeatureFromString( hDev, "PixelFormat", "YUV422Packed" );
            CHECK(res);
        }
        else if ( supportsMono8 )
        {
            printf("Setting PixelFormat to Mono8\n");
            res = PylonDeviceFeatureFromString( hDev, "PixelFormat", "Mono8" );
            CHECK(res);
        }

        /* Reset the PixelFormat feature to its previous value. */
        PylonDeviceFeatureFromString( hDev, "PixelFormat", value );
    }
    
}

----------------------------------------------------------------------------------------------------------------------------------------------------
1.參數設定為預設值:            PylonDeviceFeatureFromString( hDev, "UserSetSelector", "Default" )
2.執行"UserSetLoad"命令: PylonDeviceExecuteCommandFeature( hDev, "UserSetLoad" )

The next code snippet demonstrates use of a command parameter:

/* There are camera features, such as starting image acquisition, that represent a command. 
   This function that loads the factory settings, illustrates how to execute a command feature.  */
void demonstrateCommandFeature( PYLON_DEVICE_HANDLE hDev )
{
    GENAPIC_RESULT      res;  /* Return value. */ 

    /* Before executing the user set load command, the user set selector must be
       set to the default set. Since we are focusing on the command feature, 
       we skip the recommended steps for checking the availability of the user set 
       related features and values. */

    /* Choose the default configuration set (with one of the factory setups chosen). */
    res = PylonDeviceFeatureFromString( hDev, "UserSetSelector", "Default" );
    CHECK(res);

    /* Execute the user set load command. */
    printf("Loading the default set.\n");
    res = PylonDeviceExecuteCommandFeature( hDev, "UserSetLoad" );
    CHECK(res);
}

---------------------------------------------------------------------------------------------------------------------------------------
1. 取得某個參數(如Width)的屬性值(以string呈現): PylonDeviceFeatureToString( hDev, featureName, NULL, &len )

All kinds of parameters can be accessed as strings, as demonstrated by the following code snippet:

/*
  Regardless of the parameter's type, any parameter value can be retrieved as a string. Each parameter
  can be set by passing in a string correspondingly. This function illustrates how to set and get the 
  Width parameter as string. As demonstrated above, the Width parameter is of the integer type.  
  */
void demonstrateFromStringToString( PYLON_DEVICE_HANDLE hDev )
{
    static const char   featureName[] = "Width";   /* The name of the feature */

    size_t              len;
    char*               buf;
    char                smallBuf[1];
    char                properBuf[32];
    GENAPIC_RESULT      res;                       /* Return value */ 

    /* Get the value of a feature as a string. Normally getting the value consits of 3 steps: 
       1.) Determine the required buffer size.
       2.) Allocate the buffer. 
       3.) Retrieve the value. */
    /* ... Get the required buffer size. The size is queried by
           passing a NULL pointer as a pointer to the buffer. */
    res = PylonDeviceFeatureToString( hDev, featureName, NULL, &len );
    CHECK(res);
    /* ... Len is set to the required buffer size (terminating zero included).
           Allocate the memory and retrieve the string. */
    buf = (char*) alloca( len );
    res = PylonDeviceFeatureToString( hDev, featureName, buf, &len );
    CHECK( res );
    
    printf("%s: %s\n", featureName, buf );

    /* You are not necessarily required to query the buffer size in advance. If the buffer is
       big enough, passing in a buffer and a pointer to its length will work. 
       When the buffer is too small, an error is returned. */

    /* Passing in a buffer that is too small */
    len = sizeof (smallBuf);
    res = PylonDeviceFeatureToString( hDev, featureName, smallBuf, &len );
    if ( res == GENAPI_E_INSUFFICIENT_BUFFER )
    {
        /* The buffer was too small. The required size is indicated by len. */
        printf("Buffer is too small for the value of '%s'. The required buffer size is %d\n", featureName, len );
    }
    else
        CHECK(res);  /* Unexpected return value */

    /* Passing in a buffer with sufficient size. */
    len = sizeof (properBuf );
    res = PylonDeviceFeatureToString( hDev, featureName, properBuf, &len );
    CHECK(res);


    /* A feature can be set as a string using the PylonDeviceFeatureFromString() function. 
       If the content of a string can not be converted to the type of the feature, an 
       error is returned. */
    res = PylonDeviceFeatureFromString( hDev, featureName, "fourty-two"); /* Can not be converted to an integer */
    if ( res != GENAPI_E_OK )
    {
        /* Print out an error message. */
        size_t l;
        char *msg;
        GenApiGetLastErrorMessage( NULL, &l ); /* Retrieve buffer size for the error message */
        msg = (char *)malloc(l);             /* Provide memory */ 
        GenApiGetLastErrorMessage( msg, &l );  /* Retrieve the message */
        printf("%s\n", msg );
        free(msg);
    }
}

----------------------------------------------------------------------------------------------------------------------------------------------------------

Grabbing Images (電腦端非攝影機端)

1. 取得單張影格 res = PylonDeviceGrabSingleFrame( hDev, 0, imgBuf, payloadSize, &grabResult, &bufferReady, 500 )

2. 取得單張影格PylonDeviceGrabSingleFrame()雖然簡單但比較沒有效率, 如果需要連續擷取需透過stream grabber objects來達到最大FPS

Grabbing Using the PylonDeviceGrabSingleFrame() Function

The easiest way to grab an image using pylon C API is to call the PylonDeviceGrabSingleFrame() function. First, set up the camera using the methods described in Camera Configuration. Then call PylonDeviceGrabSingleFrame() to grab the image. It will adjust all neccessary parameters and grab an image into the buffer passed. This is shown in the following code snippet:

PylonGrabResult_t grabResult;
_Bool bufferReady;

/* Grab one single frame from stream channel 0. The 
camera is set to single frame acquisition mode.
Wait up to 500 ms for the image to be grabbed. */
res = PylonDeviceGrabSingleFrame( hDev, 0, imgBuf, payloadSize, 
    &grabResult, &bufferReady, 500 );
if ( GENAPI_E_OK == res && !bufferReady )
{
    /* Timeout occurred. */
    printf("Frame %d: timeout\n", i+1);
}
CHECK(res);

/* Check to see if the image was grabbed successfully. */
if ( grabResult.Status == Grabbed )
{
    /* Success. Perform image processing. */
    getMinMax( imgBuf, grabResult.SizeX, grabResult.SizeY, &min, &max );
    printf("Grabbed frame #%2d. Min. gray value = %3u, Max. gray value = %3u\n", i+1, min, max);

    /* Display image */
    res = PylonImageWindowDisplayImageGrabResult(0, &grabResult);
    CHECK(res);
}
else if ( grabResult.Status == Failed )
{
    fprintf( stderr,  "Frame %d wasn't grabbed successfully.  Error code = 0x%08X\n",
        i+1, grabResult.ErrorCode );
}
Note:
Even though using PylonDeviceGrabSingleFrame() is quite easy there are some limitations. It will, for instance, involve much set up and shutdown work for each invocation of the function, thus causing considerable overhead and execution time.
If you need more flexibility or want to achieve the maximum possible frame rate you'll need to grab using stream grabber objects (see Grabbing Using Stream Grabber Objects). This will allow maximum control over the grab process
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 me1237guy 的頭像
    me1237guy

    天天向上

    me1237guy 發表在 痞客邦 留言(6) 人氣()