Esempio n. 1
0
        /* This function demonstrates how to handle integer camera parameters. */
        private static void demonstrateIntFeature(PYLON_DEVICE_HANDLE hDev)
        {
            string featureName = "Width";  /* Name of the feature used in this sample: AOI Width. */
            long   val, min, max, incr;    /* Properties of the feature. */

            /*
             * 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.
             *
             * To help clarify this sample, we don't check for the feature accessibility as demonstrated
             * in the demonstrateAccessibility() function.
             */
            min  = Pylon.DeviceGetIntegerFeatureMin(hDev, featureName); /* Get the minimum value. */
            max  = Pylon.DeviceGetIntegerFeatureMax(hDev, featureName); /* Get the maximum value. */
            incr = Pylon.DeviceGetIntegerFeatureInc(hDev, featureName); /* Get the increment value. */
            val  = Pylon.DeviceGetIntegerFeature(hDev, featureName);    /* Get the current value. */

            Console.WriteLine("{0}: min= {1}  max= {2}  incr={3}  Value={4}", featureName, min, max, incr, val);

            /* Set the Width to its maximum allowed value. */
            Pylon.DeviceSetIntegerFeature(hDev, featureName, max);
            Console.WriteLine("The {0} was set to {1}.", featureName, max);
        }
Esempio n. 2
0
        /// <summary>
        /// Configure device and report frame format that will be used during streaming.
        /// This method must return a proper ImageDescriptor so we can pre-allocate buffers.
        /// </summary>
        public ImageDescriptor Prepare()
        {
            Open();

            if (deviceHandle == null || !deviceHandle.IsValid)
            {
                return(ImageDescriptor.Invalid);
            }

            firstOpen = false;

            // Get the configured framerate for recording support.
            if (Pylon.DeviceFeatureIsReadable(deviceHandle, "ResultingFrameRateAbs"))
            {
                resultingFramerate = (float)Pylon.DeviceGetFloatFeature(deviceHandle, "ResultingFrameRateAbs");
            }
            else if (Pylon.DeviceFeatureIsReadable(deviceHandle, "ResultingFrameRate"))
            {
                resultingFramerate = (float)Pylon.DeviceGetFloatFeature(deviceHandle, "ResultingFrameRate");
            }

            SpecificInfo specific           = summary.Specific as SpecificInfo;
            string       streamFormatSymbol = specific.StreamFormat;

            bool hasWidth                  = Pylon.DeviceFeatureIsReadable(deviceHandle, "Width");
            bool hasHeight                 = Pylon.DeviceFeatureIsReadable(deviceHandle, "Height");
            bool hasPixelFormat            = Pylon.DeviceFeatureIsReadable(deviceHandle, "PixelFormat");
            bool canComputeImageDescriptor = hasWidth && hasHeight && hasPixelFormat;

            if (!canComputeImageDescriptor)
            {
                return(ImageDescriptor.Invalid);
            }

            int    width       = (int)Pylon.DeviceGetIntegerFeature(deviceHandle, "Width");
            int    height      = (int)Pylon.DeviceGetIntegerFeature(deviceHandle, "Height");
            string pixelFormat = Pylon.DeviceFeatureToString(deviceHandle, "PixelFormat");

            // Note: the image provider will perform the Bayer conversion itself and only output two formats.
            // - Y800 for anything monochrome.
            // - RGB32 for anything color.
            EPylonPixelType pixelType = Pylon.PixelTypeFromString(pixelFormat);

            if (pixelType == EPylonPixelType.PixelType_Undefined)
            {
                return(ImageDescriptor.Invalid);
            }

            bool        monochrome = Pylon.IsMono(pixelType) && !Pylon.IsBayer(pixelType);
            ImageFormat format     = monochrome ? format = ImageFormat.Y800 : ImageFormat.RGB32;

            int  bufferSize = ImageFormatHelper.ComputeBufferSize(width, height, format);
            bool topDown    = true;

            return(new ImageDescriptor(format, width, height, topDown, bufferSize));
        }
Esempio n. 3
0
 public long get_integerParam(string featureName)
 {
     if (Pylon.DeviceFeatureIsAvailable(m_hDevice, featureName))
     {
         return(Pylon.DeviceGetIntegerFeature(m_hDevice, featureName));
     }
     else
     {
         return(-1);
     }
 }
Esempio n. 4
0
        /* Prepares everything for grabbing. */
        protected void SetupGrab()
        {
            /* Clear the grab result queue. This is not done when cleaning up to still be able to provide the
             * images, e.g. in single frame mode.*/
            lock (m_lockObject) /* Lock the grab result queue to avoid that two threads modify the same data. */
            {
                m_grabbedBuffers.Clear();
            }

            /* Set the acquisition mode */
            if (m_grabOnce)
            {
                /* We will use the single frame mode, to take one image. */
                Pylon.DeviceFeatureFromString(m_hDevice, "AcquisitionMode", "SingleFrame");
            }
            else
            {
                /* We will use the Continuous frame mode, i.e., the camera delivers
                 * images continuously. */
                Pylon.DeviceFeatureFromString(m_hDevice, "AcquisitionMode", "Continuous");
            }

            /* Clear the grab buffers to assure proper operation (because they may
             * still be filled if the last grab has thrown an exception). */
            foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in m_buffers)
            {
                pair.Value.Dispose();
            }
            m_buffers.Clear();

            /* Determine the required size of the grab buffer. */
            uint payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(m_hDevice, "PayloadSize"));

            /* We must tell the stream grabber the number and size of the m_buffers
             *  we are using. */
            /* .. We will not use more than NUM_m_buffers for grabbing. */
            Pylon.StreamGrabberSetMaxNumBuffer(m_hGrabber, m_numberOfBuffersUsed);

            /* .. We will not use m_buffers bigger than payloadSize bytes. */
            Pylon.StreamGrabberSetMaxBufferSize(m_hGrabber, payloadSize);

            /*  Allocate the resources required for grabbing. After this, critical parameters
            *   that impact the payload size must not be changed until FinishGrab() is called. */
            Pylon.StreamGrabberPrepareGrab(m_hGrabber);

            /* Before using the m_buffers for grabbing, they must be registered at
             * the stream grabber. For each buffer registered, a buffer handle
             * is returned. After registering, these handles are used instead of the
             * buffer objects pointers. The buffer objects are held in a dictionary,
             * that provides access to the buffer using a handle as key.
             */
            for (uint i = 0; i < m_numberOfBuffersUsed; ++i)
            {
                PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(m_hGrabber, ref buffer);
                m_buffers.Add(handle, buffer);
            }

            /* Feed the m_buffers into the stream grabber's input queue. For each buffer, the API
             * allows passing in an integer as additional context information. This integer
             * will be returned unchanged when the grab is finished. In our example, we use the index of the
             * buffer as context information. */
            foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in m_buffers)
            {
                Pylon.StreamGrabberQueueBuffer(m_hGrabber, pair.Key, 0);
            }

            /* The stream grabber is now prepared. As soon the camera starts acquiring images,
             * the image data will be grabbed into the provided m_buffers.  */

            /* Set the handle of the image converter invalid to assure proper operation (because it may
             * still be valid if the last grab has thrown an exception). */
            m_hConverter.SetInvalid();

            /* Let the camera acquire images. */
            Pylon.DeviceExecuteCommandFeature(m_hDevice, "AcquisitionStart");
        }
Esempio n. 5
0
        const uint GIGE_PROTOCOL_OVERHEAD = 36;   /* Total number of bytes of protocol overhead. */

        static void Main(string[] args)
        {
            PYLON_DEVICE_HANDLE[] hDev = new PYLON_DEVICE_HANDLE[NUM_DEVICES];        /* Handles for the pylon devices. */
            for (int deviceIndex = 0; deviceIndex < NUM_DEVICES; ++deviceIndex)
            {
                hDev[deviceIndex] = new PYLON_DEVICE_HANDLE();
            }
            try
            {
                uint numDevicesAvail;            /* Number of the available devices. */
                bool isAvail;                    /* Used for checking feature availability. */
                bool isReady;                    /* Used as an output parameter. */
                int  i;                          /* Counter. */
                int  deviceIndex;                /* Index of device used in the following variables. */
                PYLON_WAITOBJECTS_HANDLE wos;    /* Wait objects. */
                int nGrabs;                      /* Counts the number of grab iterations. */
                PYLON_WAITOBJECT_HANDLE woTimer; /* Timer wait object. */

                /* These are camera specific variables: */
                PYLON_STREAMGRABBER_HANDLE[] hGrabber = new PYLON_STREAMGRABBER_HANDLE[NUM_DEVICES];                                                                   /* Handle for the pylon stream grabber. */
                PYLON_WAITOBJECT_HANDLE[]    hWait    = new PYLON_WAITOBJECT_HANDLE[NUM_DEVICES];                                                                      /* Handle used for waiting for a grab to be finished. */
                uint[] payloadSize             = new uint[NUM_DEVICES];                                                                                                /* Size of an image frame in bytes. */
                PylonGrabResult_t[] grabResult = new PylonGrabResult_t[NUM_DEVICES];                                                                                   /* Stores the result of a grab operation. */
                uint[] nStreams = new uint[NUM_DEVICES];                                                                                                               /* The number of streams provided by the device. */
                Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >[] buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > [NUM_DEVICES]; /* Holds handles and buffers used for grabbing. */

#if DEBUG
                /* This is a special debug setting needed only for GigE cameras.
                 * See 'Building Applications with pylon' in the Programmer's Guide. */
                Environment.SetEnvironmentVariable("PYLON_GIGE_HEARTBEAT", "300000" /*ms*/);
#endif

                /* Before using any pylon methods, the pylon runtime must be initialized. */
                Pylon.Initialize();

                /* Enumerate all camera devices. You must call
                 * PylonEnumerateDevices() before creating a device. */
                numDevicesAvail = Pylon.EnumerateDevices();

                if (numDevicesAvail < NUM_DEVICES)
                {
                    Console.Error.WriteLine("Found {0} devices. At least {1} devices needed to run this sample.", numDevicesAvail, NUM_DEVICES);
                    throw new Exception("Not enough devices found.");
                }

                /* Create wait objects. This must be done outside of the loop. */
                wos = Pylon.WaitObjectsCreate();

                /* In this sample, we want to grab for a given amount of time, then stop.
                 * Create a timer that tiggers an AutoResetEvent, wrap the AutoResetEvent in a pylon C.NET wait object, and add it to
                 * the wait object set. */
                AutoResetEvent       timoutEvent          = new AutoResetEvent(false);             /* The timeout event to wait for. */
                TimerCallbackWrapper timerCallbackWrapper = new TimerCallbackWrapper(timoutEvent); /* Receives the timer callback and sets the timeout event. */
                Timer timer = new Timer(timerCallbackWrapper.TimerCallback);                       /* The timeout timer. */

                woTimer = Pylon.WaitObjectFromW32(timoutEvent.SafeWaitHandle, true);

                Pylon.WaitObjectsAdd(wos, woTimer);

                /* Open cameras and set parameters. */
                for (deviceIndex = 0; deviceIndex < NUM_DEVICES; ++deviceIndex)
                {
                    /* Get handles for the devices. */
                    hDev[deviceIndex] = Pylon.CreateDeviceByIndex((uint)deviceIndex);

                    /* Before using the device, it must be opened. Open it for configuring
                     * parameters and for grabbing images. */
                    Pylon.DeviceOpen(hDev[deviceIndex], Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);

                    /* Print out the name of the camera we are using. */
                    {
                        bool isReadable = Pylon.DeviceFeatureIsReadable(hDev[deviceIndex], "DeviceModelName");
                        if (isReadable)
                        {
                            string name = Pylon.DeviceFeatureToString(hDev[deviceIndex], "DeviceModelName");
                            Console.WriteLine("Using camera '{0}'", name);
                        }
                    }

                    /* Set the pixel format to Mono8, where gray values will be output as 8 bit values for each pixel. */
                    /* ... Check first to see if the device supports the Mono8 format. */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev[deviceIndex], "EnumEntry_PixelFormat_Mono8");
                    if (!isAvail)
                    {
                        /* Feature is not available. */
                        throw new Exception("Device doesn't support the Mono8 pixel format.");
                    }

                    /* ... Set the pixel format to Mono8. */
                    Pylon.DeviceFeatureFromString(hDev[deviceIndex], "PixelFormat", "Mono8");


                    /* Disable acquisition start trigger if available */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev[deviceIndex], "EnumEntry_TriggerSelector_AcquisitionStart");
                    if (isAvail)
                    {
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerSelector", "AcquisitionStart");
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerMode", "Off");
                    }

                    /* Disable frame burst start trigger if available */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev[deviceIndex], "EnumEntry_TriggerSelector_FrameBurstStart");
                    if (isAvail)
                    {
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerSelector", "FrameBurstStart");
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerMode", "Off");
                    }

                    /* Disable frame start trigger if available */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev[deviceIndex], "EnumEntry_TriggerSelector_FrameStart");
                    if (isAvail)
                    {
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerSelector", "FrameStart");
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerMode", "Off");
                    }

                    /* We will use the Continuous frame mode, i.e., the camera delivers
                     * images continuously. */
                    Pylon.DeviceFeatureFromString(hDev[deviceIndex], "AcquisitionMode", "Continuous");

                    PYLON_DEVICE_INFO_HANDLE hDi = Pylon.GetDeviceInfoHandle((uint)deviceIndex);
                    string deviceClass           = Pylon.DeviceInfoGetPropertyValueByName(hDi, Pylon.cPylonDeviceInfoDeviceClassKey);
                    if (deviceClass == "BaslerGigE")
                    {
                        /* For GigE cameras, we recommend increasing the packet size for better
                         * performance. When the network adapter supports jumbo frames, set the packet
                         * size to a value > 1500, e.g., to 8192. In this sample, we only set the packet size
                         * to 1500.
                         *
                         * We also set the Inter-Packet and the Frame Transmission delay
                         * so the switch can line up packets better.
                         */

                        Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "GevSCPSPacketSize", GIGE_PACKET_SIZE);
                        Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "GevSCPD", (GIGE_PACKET_SIZE + GIGE_PROTOCOL_OVERHEAD) * (NUM_DEVICES - 1));
                        Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "GevSCFTD", (GIGE_PACKET_SIZE + GIGE_PROTOCOL_OVERHEAD) * deviceIndex);
                    }
                    else if (deviceClass == "Basler1394")
                    {
                        /* For FireWire we just set the PacketSize node to limit the bandwidth we're using. */

                        /* We first divide the available bandwidth (4915 for FW400, 9830 for FW800)
                         * by the number of devices we are using. */
                        long newPacketSize         = 4915 / NUM_DEVICES;
                        long recommendedPacketSize = 0;

                        /* Get the recommended packet size from the camera. */
                        recommendedPacketSize = Pylon.DeviceGetIntegerFeature(hDev[deviceIndex], "RecommendedPacketSize");

                        if (newPacketSize < recommendedPacketSize)
                        {
                            /* Get the increment value for the packet size.
                             * We must make sure that the new value we're setting is divisible by the increment of that feature. */
                            long packetSizeInc = 0;
                            packetSizeInc = Pylon.DeviceGetIntegerFeatureInc(hDev[deviceIndex], "PacketSize");

                            /* Adjust the new packet size so is divisible by its increment. */
                            newPacketSize -= newPacketSize % packetSizeInc;
                        }
                        else
                        {
                            /* The recommended packet size should always be valid. No need to check against the increment. */
                            newPacketSize = recommendedPacketSize;
                        }

                        /* Set the new packet size. */
                        Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "PacketSize", newPacketSize);
                        Console.WriteLine("Using packetsize: {0}", newPacketSize);
                    }
                }


                /* Allocate and register buffers for grab. */
                for (deviceIndex = 0; deviceIndex < NUM_DEVICES; ++deviceIndex)
                {
                    /* Determine the required size for the grab buffer. */
                    payloadSize[deviceIndex] = checked ((uint)Pylon.DeviceGetIntegerFeature(hDev[deviceIndex], "PayloadSize"));

                    /* Image grabbing is done using a stream grabber.
                     * A device may be able to provide different streams. A separate stream grabber must
                     * be used for each stream. In this sample, we create a stream grabber for the default
                     * stream, i.e., the first stream ( index == 0 ).
                     */

                    /* Get the number of streams supported by the device and the transport layer. */
                    nStreams[deviceIndex] = Pylon.DeviceGetNumStreamGrabberChannels(hDev[deviceIndex]);

                    if (nStreams[deviceIndex] < 1)
                    {
                        throw new Exception("The transport layer doesn't support image streams.");
                    }

                    /* Create and open a stream grabber for the first channel. */
                    hGrabber[deviceIndex] = Pylon.DeviceGetStreamGrabber(hDev[deviceIndex], 0);

                    Pylon.StreamGrabberOpen(hGrabber[deviceIndex]);


                    /* Get a handle for the stream grabber's wait object. The wait object
                     * allows waiting for buffers to be filled with grabbed data. */
                    hWait[deviceIndex] = Pylon.StreamGrabberGetWaitObject(hGrabber[deviceIndex]);

                    /* Add the stream grabber's wait object to our wait objects.
                     * This is needed to be able to wait until all cameras have
                     * grabbed an image in our grab loop below. */
                    Pylon.WaitObjectsAdd(wos, hWait[deviceIndex]);

                    /* We must tell the stream grabber the number and size of the buffers
                     *  we are using. */
                    /* .. We will not use more than NUM_BUFFERS for grabbing. */
                    Pylon.StreamGrabberSetMaxNumBuffer(hGrabber[deviceIndex], NUM_BUFFERS);

                    /* .. We will not use buffers bigger than payloadSize bytes. */
                    Pylon.StreamGrabberSetMaxBufferSize(hGrabber[deviceIndex], payloadSize[deviceIndex]);

                    /*  Allocate the resources required for grabbing. After this, critical parameters
                    *   that impact the payload size must not be changed until FinishGrab() is called. */
                    Pylon.StreamGrabberPrepareGrab(hGrabber[deviceIndex]);

                    /* Before using the buffers for grabbing, they must be registered at
                     * the stream grabber. For each registered buffer, a buffer handle
                     * is returned. After registering, these handles are used instead of the
                     * buffer objects pointers. The buffer objects are held in a dictionary,
                     * that provides access to the buffer using a handle as key.
                     */
                    buffers[deviceIndex] = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();
                    for (i = 0; i < NUM_BUFFERS; ++i)
                    {
                        PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize[deviceIndex], true);
                        PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber[deviceIndex], ref buffer);
                        buffers[deviceIndex].Add(handle, buffer);
                    }

                    /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
                     * allows passing in an integer as additional context information. This integer
                     * will be returned unchanged when the grab is finished. In our example, we use the index of the
                     * buffer as context information. */
                    i = 0;
                    foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers[deviceIndex])
                    {
                        Pylon.StreamGrabberQueueBuffer(hGrabber[deviceIndex], pair.Key, i++);
                    }
                }

                /* The stream grabber is now prepared. As soon the camera starts acquiring images,
                 * the image data will be grabbed into the provided buffers.  */
                for (deviceIndex = 0; deviceIndex < NUM_DEVICES; ++deviceIndex)
                {
                    /* Let the camera acquire images. */
                    Pylon.DeviceExecuteCommandFeature(hDev[deviceIndex], "AcquisitionStart");
                }

                /* Set the timer to 5 s and start it. */
                timer.Change(5000, Timeout.Infinite);

                /* Counts the number of grabbed images. */
                nGrabs = 0;

                /* Grab until the timer expires. */
                for (;;)
                {
                    int  bufferIndex; /* Index of the buffer. */
                    Byte min, max;
                    uint woIndex;

                    /* Wait for the next buffer to be filled. Wait up to 1000 ms. */
                    isReady = Pylon.WaitObjectsWaitForAny(wos, 1000, out woIndex);

                    if (!isReady)
                    {
                        /* Timeout occurred. */
                        throw new Exception("Grab timeout occurred.");
                    }

                    /* If the timer has expired, exit the grab loop. */
                    if (woIndex == 0)
                    {
                        Console.Error.WriteLine("Grabbing completed successfully.");
                        break;  /* Timer expired. */
                    }

                    /* Account for the timer. */
                    --woIndex;

                    /* Since the wait operation was successful, the result of at least one grab
                     * operation is available. Retrieve it. */
                    isReady = Pylon.StreamGrabberRetrieveResult(hGrabber[woIndex], out grabResult[woIndex]);

                    if (!isReady)
                    {
                        /* Oops. No grab result available? We should never have reached this point.
                         * Since the wait operation above returned without a timeout, a grab result
                         * should be available. */
                        throw new Exception("Failed to retrieve a grab result.");
                    }

                    /* Get the buffer index from the context information. */
                    bufferIndex = grabResult[woIndex].Context;

                    /* Check to see if the image was grabbed successfully. */
                    if (grabResult[woIndex].Status == EPylonGrabStatus.Grabbed)
                    {
                        /*  Success. Perform image processing. Since we passed more than one buffer
                         * to the stream grabber, the remaining buffers are filled in the background while
                         * we do the image processing. The processed buffer won't be touched by
                         * the stream grabber until we pass it back to the stream grabber. */

                        PylonBuffer <Byte> buffer;        /* Reference to the buffer attached to the grab result. */

                        /* Get the buffer from the dictionary. Since we also got the buffer index,
                         * we could alternatively use an array, e.g. buffers[bufferIndex]. */
                        if (!buffers[woIndex].TryGetValue(grabResult[woIndex].hBuffer, out buffer))
                        {
                            /* Oops. No buffer available? We should never have reached this point. Since all buffers are
                             * in the dictionary. */
                            throw new Exception("Failed to find the buffer associated with the handle returned in grab result.");
                        }

                        /* Perform processing. */
                        getMinMax(buffer.Array, grabResult[woIndex].SizeX, grabResult[woIndex].SizeY, out min, out max);
                        Console.WriteLine("Grabbed frame {0} from camera {1} into buffer {2}. Min. val={3}, Max. val={4}",
                                          nGrabs, woIndex, bufferIndex, min, max);

                        /* Display image */
                        Pylon.ImageWindowDisplayImage <Byte>(woIndex, buffer, grabResult[woIndex]);
                    }
                    else if (grabResult[woIndex].Status == EPylonGrabStatus.Failed)
                    {
                        Console.Error.WriteLine("Frame {0} wasn't grabbed successfully.  Error code = {1}",
                                                nGrabs, grabResult[woIndex].ErrorCode);
                    }

                    /* Once finished with the processing, requeue the buffer to be filled again. */
                    Pylon.StreamGrabberQueueBuffer(hGrabber[woIndex], grabResult[woIndex].hBuffer, bufferIndex);

                    nGrabs++;
                }

                /* Clean up. */
                /* Stop the image aquisition on the cameras. */
                for (deviceIndex = 0; deviceIndex < NUM_DEVICES; ++deviceIndex)
                {
                    /*  ... Stop the camera. */
                    Pylon.DeviceExecuteCommandFeature(hDev[deviceIndex], "AcquisitionStop");
                }

                // Remove all wait objects from WaitObjects.
                Pylon.WaitObjectsRemoveAll(wos);
                Pylon.WaitObjectDestroy(woTimer);
                Pylon.WaitObjectsDestroy(wos);

                for (deviceIndex = 0; deviceIndex < NUM_DEVICES; ++deviceIndex)
                {
                    /* ... We must issue a cancel call to ensure that all pending buffers are put into the
                     * stream grabber's output queue. */
                    Pylon.StreamGrabberCancelGrab(hGrabber[deviceIndex]);

                    /* ... The buffers can now be retrieved from the stream grabber. */
                    do
                    {
                        isReady = Pylon.StreamGrabberRetrieveResult(hGrabber[deviceIndex], out grabResult[deviceIndex]);
                    } while (isReady);

                    /* ... When all buffers are retrieved from the stream grabber, they can be deregistered.
                     *     After deregistering the buffers, it is safe to free the memory. */

                    foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers[deviceIndex])
                    {
                        Pylon.StreamGrabberDeregisterBuffer(hGrabber[deviceIndex], pair.Key);
                        pair.Value.Dispose();
                    }
                    buffers[deviceIndex] = null;

                    /* ... Release grabbing related resources. */
                    Pylon.StreamGrabberFinishGrab(hGrabber[deviceIndex]);

                    /* After calling PylonStreamGrabberFinishGrab(), parameters that impact the payload size (e.g.,
                     * the AOI width and height parameters) are unlocked and can be modified again. */

                    /* ... Close the stream grabber. */
                    Pylon.StreamGrabberClose(hGrabber[deviceIndex]);

                    /* ... 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. */
                    Pylon.DeviceClose(hDev[deviceIndex]);
                    Pylon.DestroyDevice(hDev[deviceIndex]);
                }

                /* Dispose timer and event. */
                timer.Dispose();
                timoutEvent.Close();

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                /* ... Shut down the pylon runtime system. Don't call any pylon function after
                 * calling PylonTerminate(). */
                Pylon.Terminate();
            }
            catch (Exception e)
            {
                /* Retrieve the error message. */
                string msg = GenApi.GetLastErrorMessage() + "\n" + GenApi.GetLastErrorDetail();
                Console.Error.WriteLine("Exception caught:");
                Console.Error.WriteLine(e.Message);
                if (msg != "\n")
                {
                    Console.Error.WriteLine("Last error message:");
                    Console.Error.WriteLine(msg);
                }

                for (uint deviceIndex = 0; deviceIndex < NUM_DEVICES; ++deviceIndex)
                {
                    try
                    {
                        if (hDev[deviceIndex].IsValid)
                        {
                            /* ... Close and release the pylon device. */
                            if (Pylon.DeviceIsOpen(hDev[deviceIndex]))
                            {
                                Pylon.DeviceClose(hDev[deviceIndex]);
                            }
                            Pylon.DestroyDevice(hDev[deviceIndex]);
                        }
                    }
                    catch (Exception)
                    {
                        /*No further handling here.*/
                    }
                }
                Pylon.Terminate();  /* Releases all pylon resources. */

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                Environment.Exit(1);
            }
        }
Esempio n. 6
0
        int i;                                                               /* Counter. */


        public void PylonC_Open()
        {
#if Local_Variables
            PYLON_DEVICE_HANDLE hDev = new PYLON_DEVICE_HANDLE();             /* Handle for the pylon device. */
#endif
            try
            {
#if Local_Variables
                uint numDevices;                                                     /* Number of available devices. */
                PYLON_STREAMGRABBER_HANDLE hGrabber;                                 /* Handle for the pylon stream grabber. */
                PYLON_WAITOBJECT_HANDLE    hWait;                                    /* Handle used for waiting for a grab to be finished. */
                uint payloadSize;                                                    /* Size of an image frame in bytes. */
                Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > buffers; /* Holds handles and buffers used for grabbing. */
                PylonGrabResult_t grabResult;                                        /* Stores the result of a grab operation. */
                int  nGrabs;                                                         /* Counts the number of buffers grabbed. */
                uint nStreams;                                                       /* The number of streams provides by the device.  */
                bool isAvail;                                                        /* Used for checking feature availability. */
                bool isReady;                                                        /* Used as an output parameter. */
                int  i;                                                              /* Counter. */
#endif

#if DEBUG
                /* This is a special debug setting needed only for GigE cameras.
                 * See 'Building Applications with pylon' in the programmer's guide. */
                Environment.SetEnvironmentVariable("PYLON_GIGE_HEARTBEAT", "300000" /*ms*/);
#endif

                /* Before using any pylon methods, the pylon runtime must be initialized. */
                Pylon.Initialize();

                /* Enumerate all camera devices. You must call
                 * PylonEnumerateDevices() before creating a device. */
                numDevices = Pylon.EnumerateDevices();

                if (0 == numDevices)
                {
                    throw new Exception("No devices found.");
                }

                /* Get a handle for the first device found.  */
                hDev = Pylon.CreateDeviceByIndex(0);

                /* Before using the device, it must be opened. Open it for configuring
                 * parameters and for grabbing images. */
                Pylon.DeviceOpen(hDev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);

                /* Print out the name of the camera we are using. */
                {
                    bool isReadable = Pylon.DeviceFeatureIsReadable(hDev, "DeviceModelName");
                    if (isReadable)
                    {
                        string name = Pylon.DeviceFeatureToString(hDev, "DeviceModelName");
                        Console.WriteLine("Using camera {0}.", name);
                    }
                }

                /* Set the pixel format to Mono8, where gray values will be output as 8 bit values for each pixel. */
                /* ... Check first to see if the device supports the Mono8 format. */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_YUV422Packed");

                if (!isAvail)
                {
                    /* Feature is not available. */
                    throw new Exception("Device doesn't support the Mono8/YUV422Packed pixel format.");
                }
                /* ... Set the pixel format to Mono8. */
                Pylon.DeviceFeatureFromString(hDev, "PixelFormat", "YUV422Packed");

                /* Disable acquisition start trigger if available */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_AcquisitionStart");
                if (isAvail)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "AcquisitionStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }

                /* Disable frame burst start trigger if available */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameBurstStart");
                if (isAvail)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameBurstStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }

                /* Disable frame start trigger if available */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameStart");
                if (isAvail)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }

                /* We will use the Continuous frame mode, i.e., the camera delivers
                 * images continuously. */
                Pylon.DeviceFeatureFromString(hDev, "AcquisitionMode", "Continuous");

                /* For GigE cameras, we recommend increasing the packet size for better
                 * performance. When the network adapter supports jumbo frames, set the packet
                 * size to a value > 1500, e.g., to 8192. In this sample, we only set the packet size
                 * to 1500. */
                /* ... Check first to see if the GigE camera packet size parameter is supported and if it is writable. */
                isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");
                if (isAvail)
                {
                    /* ... The device supports the packet size feature. Set a value. */
                    Pylon.DeviceSetIntegerFeature(hDev, "GevSCPSPacketSize", 1500);
                }

                /* Determine the required size of the grab buffer. */
                payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(hDev, "PayloadSize"));

                /* Image grabbing is done using a stream grabber.
                 * A device may be able to provide different streams. A separate stream grabber must
                 * be used for each stream. In this sample, we create a stream grabber for the default
                 * stream, i.e., the first stream ( index == 0 ).
                 */

                /* Get the number of streams supported by the device and the transport layer. */
                nStreams = Pylon.DeviceGetNumStreamGrabberChannels(hDev);

                if (nStreams < 1)
                {
                    throw new Exception("The transport layer doesn't support image streams.");
                }

                /* Create and open a stream grabber for the first channel. */
                hGrabber = Pylon.DeviceGetStreamGrabber(hDev, 0);
                Pylon.StreamGrabberOpen(hGrabber);

                /* Get a handle for the stream grabber's wait object. The wait object
                 * allows waiting for buffers to be filled with grabbed data. */
                hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);

                /* We must tell the stream grabber the number and size of the buffers
                 * we are using. */
                /* .. We will not use more than NUM_BUFFERS for grabbing. */
                Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);

                /* .. We will not use buffers bigger than payloadSize bytes. */
                Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);

                /*  Allocate the resources required for grabbing. After this, critical parameters
                *  that impact the payload size must not be changed until FinishGrab() is called. */
                Pylon.StreamGrabberPrepareGrab(hGrabber);

                /* Before using the buffers for grabbing, they must be registered at
                 * the stream grabber. For each registered buffer, a buffer handle
                 * is returned. After registering, these handles are used instead of the
                 * buffer objects pointers. The buffer objects are held in a dictionary,
                 * that provides access to the buffer using a handle as key.
                 */
                buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();
                for (i = 0; i < NUM_BUFFERS; ++i)
                {
                    PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                    PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
                    buffers.Add(handle, buffer);
                }

                /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
                 * allows passing in an integer as additional context information. This integer
                 * will be returned unchanged when the grab is finished. In our example, we use the index of the
                 * buffer as context information. */
                i = 0;
                foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
                {
                    Pylon.StreamGrabberQueueBuffer(hGrabber, pair.Key, i++);
                }

                /* The stream grabber is now prepared. As soon the camera starts acquiring images,
                 * the image data will be grabbed into the provided buffers.  */

                /* Let the camera acquire images. */
                Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStart");

                /* Grab NUM_GRABS images */
                nGrabs = 0;                                         /* Counts the number of grabbed images. */
                //while (nGrabs < NUM_GRABS)
                while (nGrabs < NUM_GRABS)
                {
                    int  bufferIndex;                                   /* Index of the buffer. */
                    Byte min, max;
                    /* Wait for the next buffer to be filled. Wait up to 1000 ms. */
                    isReady = Pylon.WaitObjectWait(hWait, 1000);

                    if (!isReady)
                    {
                        /* Timeout occurred. */
                        throw new Exception("Grab timeout occurred.");
                    }

                    /* Since the wait operation was successful, the result of at least one grab
                     * operation is available. Retrieve it. */
                    isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);

                    if (!isReady)
                    {
                        /* Oops. No grab result available? We should never have reached this point.
                         * Since the wait operation above returned without a timeout, a grab result
                         * should be available. */
                        throw new Exception("Failed to retrieve a grab result");
                    }

                    nGrabs++;

                    /* Get the buffer index from the context information. */
                    bufferIndex = (int)grabResult.Context;

                    /* Check to see if the image was grabbed successfully. */
                    if (grabResult.Status == EPylonGrabStatus.Grabbed)
                    {
                        /*  Success. Perform image processing. Since we passed more than one buffer
                         * to the stream grabber, the remaining buffers are filled in the background while
                         * we do the image processing. The processed buffer won't be touched by
                         * the stream grabber until we pass it back to the stream grabber. */

                        PylonBuffer <Byte> buffer;                               /* Reference to the buffer attached to the grab result. */

                        /* Get the buffer from the dictionary. Since we also got the buffer index,
                         * we could alternatively use an array, e.g. buffers[bufferIndex]. */
                        if (!buffers.TryGetValue(grabResult.hBuffer, out buffer))
                        {
                            /* Oops. No buffer available? We should never have reached this point. Since all buffers are
                             * in the dictionary. */
                            throw new Exception("Failed to find the buffer associated with the handle returned in grab result.");
                        }

                        /* Perform processing. */
                        getMinMax(buffer.Array, grabResult.SizeX, grabResult.SizeY, out min, out max);
                        Console.WriteLine("Grabbed frame {0} into buffer {1}. Min. gray value = {2}, Max. gray value = {3}",
                                          nGrabs, bufferIndex, min, max);

                        /* Display image */                        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                        WpfApp5.MainWindow.Pylon_Buffer = buffer;
                        WpfApp5.MainWindow.GrabResult   = grabResult;
                        Console.WriteLine("the contents of buffer: [{0, 10}] in OverlappedGrab Class.", buffer.Array[0]);
                        Console.WriteLine("the contents of buffer: [{0, 10}] in WpfApp3.MainWindow.Pylon_Buffer.", WpfApp5.MainWindow.Pylon_Buffer.Array[0]);

                        Pylon.ImageWindowDisplayImage <Byte>(0, buffer, grabResult);
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    }
                    else if (grabResult.Status == EPylonGrabStatus.Failed)
                    {
                        Console.Error.WriteLine("Frame {0} wasn't grabbed successfully.  Error code = {1}",
                                                nGrabs, grabResult.ErrorCode);
                    }

                    /* Once finished with the processing, requeue the buffer to be filled again. */
                    Pylon.StreamGrabberQueueBuffer(hGrabber, grabResult.hBuffer, bufferIndex);
                }

                /* Clean up. */

#if DONT_COMPILE_THESE_CODE
                /*  ... Stop the camera. */
                Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStop");

                /* ... We must issue a cancel call to ensure that all pending buffers are put into the
                 * stream grabber's output queue. */
                Pylon.StreamGrabberCancelGrab(hGrabber);

                /* ... The buffers can now be retrieved from the stream grabber. */
                do
                {
                    isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);
                } while (isReady);

                /* ... When all buffers are retrieved from the stream grabber, they can be deregistered.
                 *         After deregistering the buffers, it is safe to free the memory. */

                foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
                {
                    Pylon.StreamGrabberDeregisterBuffer(hGrabber, pair.Key);
                    pair.Value.Dispose();
                }
                buffers = null;

                /* ... Release grabbing related resources. */
                Pylon.StreamGrabberFinishGrab(hGrabber);

                /* After calling PylonStreamGrabberFinishGrab(), parameters that impact the payload size (e.g.,
                 * the AOI width and height parameters) are unlocked and can be modified again. */

                /* ... Close the stream grabber. */
                Pylon.StreamGrabberClose(hGrabber);

                /* ... 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. */
                Pylon.DeviceClose(hDev);
                Pylon.DestroyDevice(hDev);

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                /* ... Shut down the pylon runtime system. Don't call any pylon method after
                 * calling Pylon.Terminate(). */
                Pylon.Terminate();
#endif
            }
            catch (Exception e)
            {
                /* Retrieve the error message. */
                string msg = GenApi.GetLastErrorMessage() + "\n" + GenApi.GetLastErrorDetail();
                Console.Error.WriteLine("Exception caught:");
                Console.Error.WriteLine(e.Message);
                if (msg != "\n")
                {
                    Console.Error.WriteLine("Last error message:");
                    Console.Error.WriteLine(msg);
                }

                try
                {
                    if (hDev.IsValid)
                    {
                        /* ... Close and release the pylon device. */
                        if (Pylon.DeviceIsOpen(hDev))
                        {
                            Pylon.DeviceClose(hDev);
                        }
                        Pylon.DestroyDevice(hDev);
                    }
                }
                catch (Exception)
                {
                    /*No further handling here.*/
                }

                Pylon.Terminate();                  /* Releases all pylon resources. */

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                Environment.Exit(1);
            }
        }
Esempio n. 7
0
        private void initStreamMode(uint NUM_BUFFERS, out PYLON_STREAMGRABBER_HANDLE hGrabber, out PYLON_WAITOBJECT_HANDLE hWait, out Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > buffers)
        {
            uint numDevices;                           /* Number of available devices. */
            /* Handle for the pylon stream grabber. */
            /* Handle used for waiting for a grab to be finished. */
            uint payloadSize;                          /* Size of an image frame in bytes. */
            /* Holds handles and buffers used for grabbing. */
            /* Stores the result of a grab operation. */
            /* Counts the number of buffers grabbed. */
            uint nStreams;                            /* The number of streams provides by the device.  */
            bool isAvail;                             /* Used for checking feature availability. */
            /* Used as an output parameter. */
            int i;                                    /* Counter. */

#if DEBUG
            /* This is a special debug setting needed only for GigE cameras.
             * See 'Building Applications with pylon' in the programmer's guide. */
            Environment.SetEnvironmentVariable("PYLON_GIGE_HEARTBEAT", "300000" /*ms*/);
#endif


            isAvail = setStreamModeFeature();

            //*******************************設定 Stream 參數 Start *****************************************************************************
            /* Determine the required size of the grab buffer. */
            payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(_pylonDevHandle, "PayloadSize"));



            /* Get the number of streams supported by the device and the transport layer. */
            nStreams = Pylon.DeviceGetNumStreamGrabberChannels(_pylonDevHandle);

            if (nStreams < 1)
            {
                throw new Exception("The transport layer doesn't support image streams.");
            }

            /* Create and open a stream grabber for the first channel. */
            hGrabber = Pylon.DeviceGetStreamGrabber(_pylonDevHandle, 0);
            Pylon.StreamGrabberOpen(hGrabber);

            /* Get a handle for the stream grabber's wait object. The wait object
             * allows waiting for buffers to be filled with grabbed data. */
            hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);

            /* We must tell the stream grabber the number and size of the buffers
             *      we are using. */
            /* .. We will not use more than NUM_BUFFERS for grabbing. */
            Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);

            /* .. We will not use buffers bigger than payloadSize bytes. */
            Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);

            /*  Allocate the resources required for grabbing. After this, critical parameters
            *       that impact the payload size must not be changed until FinishGrab() is called. */
            Pylon.StreamGrabberPrepareGrab(hGrabber);

            /* Before using the buffers for grabbing, they must be registered at
             * the stream grabber. For each registered buffer, a buffer handle
             * is returned. After registering, these handles are used instead of the
             * buffer objects pointers. The buffer objects are held in a dictionary,
             * that provides access to the buffer using a handle as key.
             */
            buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();
            for (i = 0; i < NUM_BUFFERS; ++i)
            {
                PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
                buffers.Add(handle, buffer);
            }

            /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
             * allows passing in an integer as additional context information. This integer
             * will be returned unchanged when the grab is finished. In our example, we use the index of the
             * buffer as context information. */
            i = 0;
            foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
            {
                Pylon.StreamGrabberQueueBuffer(hGrabber, pair.Key, i++);
            }
        }
Esempio n. 8
0
        const uint NUM_BUFFERS = 5;                 /* Number of buffers used for grabbing. */
        private void streamdGrabModelStartMethod()
        {
            bool isReady;

            int bufferIndex;                            /* Index of the buffer. */

            /* Wait for the next buffer to be filled. Wait up to 1000 ms. */
            isReady = Pylon.WaitObjectWait(hWait, 200);

            if (!isReady)
            {
                /* Timeout occurred. */
                throw new Exception("Grab timeout occurred.");
            }

            /* Since the wait operation was successful, the result of at least one grab
             * operation is available. Retrieve it. */
            isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);

            if (!isReady)
            {
                /* Oops. No grab result available? We should never have reached this point.
                 * Since the wait operation above returned without a timeout, a grab result
                 * should be available. */
                throw new Exception("Failed to retrieve a grab result");
            }


            /* Get the buffer index from the context information. */
            bufferIndex = (int)grabResult.Context;

            /* Check to see if the image was grabbed successfully. */
            if (grabResult.Status == EPylonGrabStatus.Grabbed)
            {
                /*  Success. Perform image processing. Since we passed more than one buffer
                 * to the stream grabber, the remaining buffers are filled in the background while
                 * we do the image processing. The processed buffer won't be touched by
                 * the stream grabber until we pass it back to the stream grabber. */

                PylonBuffer <Byte> buffer;                       /* Reference to the buffer attached to the grab result. */

                /* Get the buffer from the dictionary. Since we also got the buffer index,
                 * we could alternatively use an array, e.g. buffers[bufferIndex]. */
                if (!buffers.TryGetValue(grabResult.hBuffer, out buffer))
                {
                    /* Oops. No buffer available? We should never have reached this point. Since all buffers are
                     * in the dictionary. */
                    throw new Exception("Failed to find the buffer associated with the handle returned in grab result.");
                }
                var width  = (int)Pylon.DeviceGetIntegerFeature(_pylonDevHandle, "Width");
                var height = (int)Pylon.DeviceGetIntegerFeature(_pylonDevHandle, "Height");

                /* Perform processing. */
                _latestImage = new HImage("byte", width, height, buffer.Pointer);
            }
            else if (grabResult.Status == EPylonGrabStatus.Failed)
            {
                _latestMessage = String.Format("Frame wasn't grabbed successfully.  Error code = {0}",
                                               grabResult.ErrorCode);
            }

            /* Once finished with the processing, requeue the buffer to be filled again. */
            Pylon.StreamGrabberQueueBuffer(hGrabber, grabResult.hBuffer, bufferIndex);
        }
Esempio n. 9
0
        private void chunkGrabImageMethod()
        {
            string triggerSelectorValue = "FrameStart";             /* Preselect the trigger for image acquisition */

            /* Check the available camera trigger mode(s) to select the appropriate one:
             * acquisition start trigger mode (used by previous cameras;
             * do not confuse with acquisition start command) or
             * frame start trigger mode (equivalent to previous acquisition start trigger mode). */


            bool isAvailAcquisitionStart = Pylon.DeviceFeatureIsAvailable(_pylonDevHandle, "EnumEntry_TriggerSelector_AcquisitionStart");
            bool isAvailFrameStart       = Pylon.DeviceFeatureIsAvailable(_pylonDevHandle, "EnumEntry_TriggerSelector_FrameStart");

            /* Check to see if the camera implements the acquisition start trigger mode only. */
            bool isAcqStartTriggerModeOnly = (isAvailAcquisitionStart && !isAvailFrameStart);

            if (isAcqStartTriggerModeOnly)
            {
                /* Camera uses the acquisition start trigger as the only trigger mode. */
                Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerSelector", "AcquisitionStart");
                Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerMode", "On");
                triggerSelectorValue = "AcquisitionStart";
            }
            else
            {
                /* Camera may have the acquisition start trigger mode and the frame start trigger mode implemented.
                 * In this case, the acquisition trigger mode must be switched off. */
                if (isAvailAcquisitionStart)
                {
                    Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerSelector", "AcquisitionStart");
                    Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerMode", "Off");
                }
                /* To trigger each single frame by software or external hardware trigger: Enable the frame start trigger mode. */
                Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerSelector", "FrameStart");
                Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerMode", "On");
            }

            /* Note: the trigger selector must be set to the appropriate trigger mode
             * before setting the trigger source or issuing software triggers.
             * Frame start trigger mode for newer cameras, acquisition start trigger mode for previous cameras. */
            Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerSelector", triggerSelectorValue);

            /* Enable software triggering. */
            /* ... Select the software trigger as the trigger source. */
            Pylon.DeviceFeatureFromString(_pylonDevHandle, "TriggerSource", "Software");

            /* When using software triggering, the Continuous frame mode should be used. Once
             * acquisition is started, the camera sends one image each time a software trigger is
             * issued. */
            Pylon.DeviceFeatureFromString(_pylonDevHandle, "AcquisitionMode", "Continuous");


            //********************************************************************************************************
            setChunkModeFeatures();

            /* The data block containing the image chunk and the other chunks has a self-descriptive layout.
             * A chunk parser is used to extract the appended chunk data from the grabbed image frame.
             * Create a chunk parser. */
            PYLON_CHUNKPARSER_HANDLE hChunkParser = Pylon.DeviceCreateChunkParser(_pylonDevHandle);

            if (!hChunkParser.IsValid)
            {
                /* The transport layer doesn't provide a chunk parser. */
                throw new Exception("No chunk parser available.");
            }


            /* Image grabbing is done using a stream grabber.
             * A device may be able to provide different streams. A separate stream grabber must
             * be used for each stream. In this sample, we create a stream grabber for the default
             * stream, i.e., the first stream ( index == 0 ).
             */

            /* Get the number of streams supported by the device and the transport layer. */
            var nStreams = Pylon.DeviceGetNumStreamGrabberChannels(_pylonDevHandle);

            if (nStreams < 1)
            {
                throw new Exception("The transport layer doesn't support image streams.");
            }

            /* Create and open a stream grabber for the first channel. */
            uint firstChannel = 0;
            PYLON_STREAMGRABBER_HANDLE hGrabber = Pylon.DeviceGetStreamGrabber(_pylonDevHandle, firstChannel);

            Pylon.StreamGrabberOpen(hGrabber);

            /* Get a handle for the stream grabber's wait object. The wait object
             * allows waiting for buffers to be filled with grabbed data. */
            PYLON_WAITOBJECT_HANDLE hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);

            /* Determine the required size of the grab buffer. Since activating chunks will increase the
             * payload size and thus the required buffer size, do this after enabling the chunks. */
            uint payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(_pylonDevHandle, "PayloadSize"));

            /* We must tell the stream grabber the number and size of the buffers
             *      we are using. */
            /* .. We will not use more than NUM_BUFFERS for grabbing. */
            uint NUM_BUFFERS = 2;

            Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);

            /* .. We will not use buffers bigger than payloadSize bytes. */
            Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);

            /*  Allocate the resources required for grabbing. After this, critical parameters
            *       that impact the payload size must not be changed until FinishGrab() is called. */
            Pylon.StreamGrabberPrepareGrab(hGrabber);

            /* Before using the buffers for grabbing, they must be registered at
             * the stream grabber. For each registered buffer, a buffer handle
             * is returned. After registering, these handles are used instead of the
             * buffer objects pointers. The buffer objects are held in a dictionary,
             * that provides access to the buffer using a handle as key.
             */
            var buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();

            for (int i = 0; i < NUM_BUFFERS; ++i)
            {
                PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
                buffers.Add(handle, buffer);
            }

            /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
             * allows passing in an integer as additional context information. This integer
             * will be returned unchanged when the grab is finished. In our example, we use the index of the
             * buffer as context information. */
            var index = 0;

            foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
            {
                Pylon.StreamGrabberQueueBuffer(hGrabber, pair.Key, index++);
            }

            /* Issue an acquisition start command. Because the trigger mode is enabled, issuing the start command
             * itself will not trigger any image acquisitions. Issuing the start command simply prepares the camera.
             * Once the camera is prepared it will acquire one image for every trigger it receives. */
            Pylon.DeviceExecuteCommandFeature(_pylonDevHandle, "AcquisitionStart");

            /* Trigger the first image. */
            Pylon.DeviceExecuteCommandFeature(_pylonDevHandle, "TriggerSoftware");

            /* Grab NUM_GRABS images. */
            PylonGrabResult_t grabResult;
            int NUM_GRABS = 1;
            int nGrabs    = 0;                                    /* Counts the number of images grabbed. */

            while (nGrabs < NUM_GRABS)
            {
                int bufferIndex;                              /* Index of the buffer. */

                /* Wait for the next buffer to be filled. Wait up to 1000 ms. */
                bool isReady = Pylon.WaitObjectWait(hWait, 1000);

                if (!isReady)
                {
                    /* Timeout occurred. */
                    throw new Exception("Grab timeout occurred.\n");
                }

                /* Since the wait operation was successful, the result of at least one grab
                 * operation is available. Retrieve it. */
                isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);

                if (!isReady)
                {
                    /* Oops. No grab result available? We should never have reached this point.
                     * Since the wait operation above returned without a timeout, a grab result
                     * should be available. */
                    throw new Exception("Failed to retrieve a grab result.\n");
                }

                nGrabs++;

                /* Trigger the next image. Since we passed more than one buffer to the stream grabber,
                 * the triggered image will be grabbed while the image processing is performed.  */
                Pylon.DeviceExecuteCommandFeature(_pylonDevHandle, "TriggerSoftware");

                /* Get the buffer index from the context information. */
                bufferIndex = (int)grabResult.Context;

                /* Check to see if the image was grabbed successfully. */

                if (grabResult.Status == EPylonGrabStatus.Grabbed)
                {
                    /*  The grab is successful.  */

                    PylonBuffer <Byte> buffer;                           /* Reference to the buffer attached to the grab result. */

                    /* Get the buffer from the dictionary. Since we also got the buffer index,
                     * we could alternatively use an array, e.g. buffers[bufferIndex]. */
                    if (!buffers.TryGetValue(grabResult.hBuffer, out buffer))
                    {
                        /* Oops. No buffer available? We should never have reached this point. Since all buffers are
                         * in the dictionary. */
                        throw new Exception("Failed to find the buffer associated with the handle returned in grab result.");
                    }

                    //Console.WriteLine("Grabbed frame {0} into buffer {1}.", nGrabs, bufferIndex);



                    /* Check to see if we really got image data plus chunk data. */
                    if (grabResult.PayloadType != EPylonPayloadType.PayloadType_ChunkData)
                    {
                        Console.WriteLine("Received a buffer not containing chunk data?");
                    }
                    else
                    {
                        /* Process the chunk data. This is done by passing the grabbed image buffer
                         * to the chunk parser. When the chunk parser has processed the buffer, the chunk
                         * data can be accessed in the same manner as "normal" camera parameters.
                         * The only exception is the CRC checksum feature. There are dedicated functions for
                         * checking the CRC checksum. */

                        bool hasCRC;

                        /* Let the parser extract the data. */
                        Pylon.ChunkParserAttachBuffer(hChunkParser, buffer);


                        /* Check the CRC checksum. */
                        hasCRC = Pylon.ChunkParserHasCRC(hChunkParser);
                        bool isOk = (hasCRC) ? Pylon.ChunkParserCheckCRC(hChunkParser) : true;

                        bool isAvail = Pylon.DeviceFeatureIsAvailable(_pylonDevHandle, "ChunkWidth");
                        long chunkWidth = 0, chunkHeight = 0;
                        //Console.WriteLine("Frame {0} {1} a frame width chunk.", nGrabs, isAvail ? "contains" : "doesn't contain");
                        if (isAvail)
                        {
                            /* ... Get the value. */
                            chunkWidth = Pylon.DeviceGetIntegerFeature(_pylonDevHandle, "ChunkWidth");

                            //Console.WriteLine("Width of frame {0}: {1}.", nGrabs, chunkWidth);
                        }

                        /* Retrieve the chunk height value. */
                        /* ... Check the availability. */
                        isAvail = Pylon.DeviceFeatureIsAvailable(_pylonDevHandle, "ChunkHeight");

                        Console.WriteLine("Frame {0} {1} a frame height chunk.", nGrabs, isAvail ? "contains" : "doesn't contain");
                        if (isAvail)
                        {
                            /* ... Get the value. */
                            chunkHeight = Pylon.DeviceGetIntegerFeature(_pylonDevHandle, "ChunkHeight");

                            //Console.WriteLine("Height of frame {0}: {1}.", nGrabs, chunkHeight);
                        }

                        if (isOk)
                        {
                            _latestImage = new HImage("byte", (int)chunkWidth, (int)chunkHeight, buffer.Pointer);
                        }
                    }
                    /* Before requeueing the buffer, you should detach it from the chunk parser. */
                    Pylon.ChunkParserDetachBuffer(hChunkParser);                      /* Now the chunk data in the buffer is no longer accessible. */
                }
                else if (grabResult.Status == EPylonGrabStatus.Failed)
                {
                    Console.Error.WriteLine("Frame {0} wasn't grabbed successfully.  Error code = {1}", nGrabs, grabResult.ErrorCode);
                }

                /* Once finished with the processing, requeue the buffer to be filled again. */
                Pylon.StreamGrabberQueueBuffer(hGrabber, grabResult.hBuffer, bufferIndex);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Configure device and report frame format that will be used during streaming.
        /// This method must return a proper ImageDescriptor so we can pre-allocate buffers.
        /// </summary>
        public ImageDescriptor Prepare()
        {
            Open();

            if (deviceHandle == null || !deviceHandle.IsValid)
            {
                return(ImageDescriptor.Invalid);
            }

            firstOpen = false;

            // Get the configured framerate for recording support.
            resultingFramerate = PylonHelper.GetResultingFramerate(deviceHandle);

            SpecificInfo specific           = summary.Specific as SpecificInfo;
            string       streamFormatSymbol = specific.StreamFormat;

            bool hasWidth                  = Pylon.DeviceFeatureIsReadable(deviceHandle, "Width");
            bool hasHeight                 = Pylon.DeviceFeatureIsReadable(deviceHandle, "Height");
            bool hasPixelFormat            = Pylon.DeviceFeatureIsReadable(deviceHandle, "PixelFormat");
            bool canComputeImageDescriptor = hasWidth && hasHeight && hasPixelFormat;

            if (!canComputeImageDescriptor)
            {
                return(ImageDescriptor.Invalid);
            }

            int    width       = (int)Pylon.DeviceGetIntegerFeature(deviceHandle, "Width");
            int    height      = (int)Pylon.DeviceGetIntegerFeature(deviceHandle, "Height");
            string pixelFormat = Pylon.DeviceFeatureToString(deviceHandle, "PixelFormat");

            EPylonPixelType pixelType = Pylon.PixelTypeFromString(pixelFormat);

            if (pixelType == EPylonPixelType.PixelType_Undefined)
            {
                return(ImageDescriptor.Invalid);
            }

            // Note: the image provider will perform the Bayer conversion itself and only output two formats.
            // - Y800 for anything monochrome.
            // - RGB32 for anything color.
            imageProvider.SetDebayering(specific.Bayer8Conversion);

            bool        isBayer    = Pylon.IsBayer(pixelType);
            bool        isBayer8   = PylonHelper.IsBayer8(pixelType);
            bool        bayerColor = (isBayer && !isBayer8) || (isBayer8 && specific.Bayer8Conversion == Bayer8Conversion.Color);
            bool        color      = !Pylon.IsMono(pixelType) || bayerColor;
            ImageFormat format     = color ? ImageFormat.RGB32 : ImageFormat.Y800;

            finishline.Prepare(width, height, format, resultingFramerate);
            if (finishline.Enabled)
            {
                height             = finishline.Height;
                resultingFramerate = finishline.ResultingFramerate;
            }

            int  bufferSize = ImageFormatHelper.ComputeBufferSize(width, height, format);
            bool topDown    = true;

            return(new ImageDescriptor(format, width, height, topDown, bufferSize));
        }
Esempio n. 11
0
        private void ContinuousGrab()
        {
            try
            {
                lock (dev)
                {
                    // prepare grabbing, see pylon C.NET docs
                    Pylon.DeviceOpen(dev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);
                    Pylon.DeviceFeatureFromString(dev, "AcquisitionMode", "Continuous");
                    uint payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(dev, "PayloadSize"));
                    uint nStreams    = Pylon.DeviceGetNumStreamGrabberChannels(dev);
                    hGrabber = Pylon.DeviceGetStreamGrabber(dev, 0);
                    Pylon.StreamGrabberOpen(hGrabber);
                    hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);
                    Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);
                    Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);
                    Pylon.StreamGrabberPrepareGrab(hGrabber);
                    var buffers = new PylonBuffer <Byte> [NUM_BUFFERS];
                    var handles = new PYLON_STREAMBUFFER_HANDLE[NUM_BUFFERS];
                    for (int i = 0; i < NUM_BUFFERS; i++)
                    {
                        PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                        PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
                        Pylon.StreamGrabberQueueBuffer(hGrabber, handle, i);
                        handles[i] = handle;
                        buffers[i] = buffer;
                    }

                    Pylon.DeviceExecuteCommandFeature(dev, "AcquisitionStart");

                    PylonGrabResult_t grabResult;
                    bool isReady;

                    while (grabbing)
                    {
                        int bufferIndex;
                        isReady = Pylon.WaitObjectWait(hWait, 1000);

                        if (!isReady)
                        {
                            throw new Exception("Grab timeout");
                        }
                        //

                        isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);

                        if (!isReady)
                        {
                            throw new Exception("Failed to retrieve a grab result");
                        }

                        bufferIndex = (int)grabResult.Context;

                        if (grabResult.Status == EPylonGrabStatus.Grabbed)
                        {
                            PylonBuffer <Byte> buffer = buffers[bufferIndex];
                            OnGrabAndDispose(GrabResultToImage(grabResult, buffer));
                            //Thread.Sleep(10);
                        }
                        else if (grabResult.Status == EPylonGrabStatus.Failed)
                        {
                            Console.Error.WriteLine("Error grabbing. Error Code = {0}", grabResult.ErrorCode);
                        }

                        Pylon.StreamGrabberQueueBuffer(hGrabber, grabResult.hBuffer, bufferIndex);
                    }
                    Pylon.DeviceExecuteCommandFeature(dev, "AcquisitionStop");
                    Pylon.StreamGrabberCancelGrab(hGrabber);
                    do
                    {
                        isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);
                    } while (isReady);
                    for (int i = 0; i < NUM_BUFFERS; i++)
                    {
                        Pylon.StreamGrabberDeregisterBuffer(hGrabber, handles[i]);
                        buffers[i].Dispose();
                    }
                    Pylon.StreamGrabberFinishGrab(hGrabber);
                    Pylon.StreamGrabberClose(hGrabber);
                    Pylon.DeviceClose(dev);
                }
            }
            catch
            {
                Console.WriteLine(GenApi.GetLastErrorDetail());
            }
        }
Esempio n. 12
0
    public void cameraInit(string cameraType)
    {
        //Initiates camera to run in 12 bit mode with continuous acquisition.
        int  i           = 0;
        uint NUM_BUFFERS = 10;

        if (cameraType == "basler")
        {
            Pylon.Initialize();
            numDevices = Pylon.EnumerateDevices();
            if (ConfigurationManager.AppSettings.Get("ipAddress").Length > 0)
            {
                while (ip != ConfigurationManager.AppSettings.Get("ipAddress"))
                {
                    hDev = Pylon.CreateDeviceByIndex(j);
                    prop = Pylon.DeviceGetDeviceInfoHandle(hDev);
                    ip   = Pylon.DeviceInfoGetPropertyValueByIndex(prop, 8);
                    j++;
                    if (j > numDevices)
                    {
                        break;
                    }
                }
            }
            else
            {
                numDevices = Pylon.EnumerateDevices();
                hDev       = Pylon.CreateDeviceByIndex(0);
            }
            try
            {
                Pylon.DeviceOpen(hDev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);
            }
            catch (System.Threading.ThreadAbortException) { }
            catch (Exception ex)
            {
                EmailError.emailAlert(ex);
                throw (ex);
            }

            isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono12");
            Pylon.DeviceFeatureFromString(hDev, "PixelFormat", "Mono12");
            Pylon.DeviceFeatureFromString(hDev, "AcquisitionMode", "Continuous");
            Pylon.DeviceSetIntegerFeature(hDev, "Height", 1);
            Pylon.DeviceSetFloatFeature(hDev, "ExposureTimeAbs", exp); //Exposure time is in microseconds and rounded to the closest 100 ns.
            isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");
            if (isAvail)
            {
                Pylon.DeviceSetIntegerFeature(hDev, "GevSCPSPacketSize", 1500);
            }
            payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(hDev, "PayloadSize"));
            nStreams    = Pylon.DeviceGetNumStreamGrabberChannels(hDev);
            hGrabber    = Pylon.DeviceGetStreamGrabber(hDev, 0);
            Pylon.StreamGrabberOpen(hGrabber);
            hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);
            Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);
            Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);
            Pylon.StreamGrabberPrepareGrab(hGrabber);
            buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();
            for (i = 0; i < NUM_BUFFERS; ++i)
            {
                PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
                buffers.Add(handle, buffer);
            }
            i = 0;
            foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
            {
                Pylon.StreamGrabberQueueBuffer(hGrabber, pair.Key, i++);
            }
            Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStart");
        }
    }
Esempio n. 13
0
        const uint NUM_BUFFERS = 2;         /* Number of buffers used for grabbing. */

        static void Main(string[] args)
        {
            PYLON_DEVICE_HANDLE hDev = new PYLON_DEVICE_HANDLE(); /* Handle for the pylon device. */

            try
            {
                uint numDevices;                                                     /* Number of available devices. */
                PYLON_STREAMGRABBER_HANDLE hGrabber;                                 /* Handle for the pylon stream grabber. */
                PYLON_CHUNKPARSER_HANDLE   hChunkParser;                             /* Handle for the parser extracting the chunk data. */
                PYLON_WAITOBJECT_HANDLE    hWait;                                    /* Handle used for waiting for a grab to be finished. */
                uint payloadSize;                                                    /* Size of an image frame in bytes. */
                Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > buffers; /* Holds handles and buffers used for grabbing. */
                PylonGrabResult_t grabResult;                                        /* Stores the result of a grab operation. */
                int    nGrabs;                                                       /* Counts the number of buffers grabbed. */
                uint   nStreams;                                                     /* The number of streams the device provides. */
                bool   isAvail;                                                      /* Used for checking feature availability */
                bool   isReady;                                                      /* Used as an output parameter */
                int    i;                                                            /* Counter. */
                string triggerSelectorValue = "FrameStart";                          /* Preselect the trigger for image acquisition */
                bool   isAvailFrameStart;                                            /* Used for checking feature availability */
                bool   isAvailAcquisitionStart;                                      /* Used for checking feature availability */

#if DEBUG
                /* This is a special debug setting needed only for GigE cameras.
                 * See 'Building Applications with pylon' in the programmers guide */
                Environment.SetEnvironmentVariable("PYLON_GIGE_HEARTBEAT", "300000" /*ms*/);
#endif

                /* Before using any pylon methods, the pylon runtime must be initialized. */
                Pylon.Initialize();

                /* Enumerate all camera devices. You must call
                 * PylonEnumerateDevices() before creating a device. */
                numDevices = Pylon.EnumerateDevices();

                if (0 == numDevices)
                {
                    throw new Exception("No devices found!");
                }

                /* Get a handle for the first device found.  */
                hDev = Pylon.CreateDeviceByIndex(0);

                /* Before using the device, it must be opened. Open it for configuring
                 * parameters and for grabbing images. */
                Pylon.DeviceOpen(hDev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);

                /* Set the pixel format to Mono8, where gray values will be output as 8 bit values for each pixel. */
                /* ... Check first to see if the device supports the Mono8 format. */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8");

                if (!isAvail)
                {
                    /* Feature is not available. */
                    throw new Exception("Device doesn't support the Mono8 pixel format.");
                }
                /* ... Set the pixel format to Mono8. */
                Pylon.DeviceFeatureFromString(hDev, "PixelFormat", "Mono8");

                /* Check the available camera trigger mode(s) to select the appropriate one: acquisition start trigger mode (used by previous cameras;
                *  do not confuse with acquisition start command) or frame start trigger mode (equivalent to previous acquisition start trigger mode). */
                isAvailAcquisitionStart = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_AcquisitionStart");
                isAvailFrameStart       = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameStart");

                /* Check to see if the camera implements the acquisition start trigger mode only. */
                if (isAvailAcquisitionStart && !isAvailFrameStart)
                {
                    /* Camera uses the acquisition start trigger as the only trigger mode. */
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "AcquisitionStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "On");
                    triggerSelectorValue = "AcquisitionStart";
                }
                else
                {
                    /* Camera may have the acquisition start trigger mode and the frame start trigger mode implemented.
                     * In this case, the acquisition trigger mode must be switched off. */
                    if (isAvailAcquisitionStart)
                    {
                        Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "AcquisitionStart");
                        Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                    }

                    /* Disable frame burst start trigger if available */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameBurstStart");
                    if (isAvail)
                    {
                        Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameBurstStart");
                        Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                    }

                    /* To trigger each single frame by software or external hardware trigger: Enable the frame start trigger mode. */
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "On");
                }

                /* Note: the trigger selector must be set to the appropriate trigger mode
                 * before setting the trigger source or issuing software triggers.
                 * Frame start trigger mode for newer cameras, acquisition start trigger mode for previous cameras. */
                Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", triggerSelectorValue);

                /* Enable software triggering. */
                /* ... Select the software trigger as the trigger source. */
                Pylon.DeviceFeatureFromString(hDev, "TriggerSource", "Software");

                /* When using software triggering, the Continuous frame mode should be used. Once
                 * acquisition is started, the camera sends one image each time a software trigger is
                 * issued. */
                Pylon.DeviceFeatureFromString(hDev, "AcquisitionMode", "Continuous");

                /* For GigE cameras, we recommend increasing the packet size for better
                 * performance. If the network adapter supports jumbo frames, set the packet
                 * size to a value > 1500, e.g., to 8192. In this sample, we only set the packet size
                 * to 1500. */
                /* ... Check first to see if the GigE camera packet size parameter is supported and if it is writable. */
                isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");

                if (isAvail)
                {
                    /* ... The device supports the packet size feature. Set a value. */
                    Pylon.DeviceSetIntegerFeature(hDev, "GevSCPSPacketSize", 1500);
                }

                /* Before enabling individual chunks, the chunk mode in general must be activated. */
                isAvail = Pylon.DeviceFeatureIsWritable(hDev, "ChunkModeActive");

                if (!isAvail)
                {
                    throw new Exception("The device doesn't support the chunk mode.");
                }

                /* Activate the chunk mode. */
                Pylon.DeviceSetBooleanFeature(hDev, "ChunkModeActive", true);

                /* Enable some individual chunks... */

                /* ... The frame counter chunk feature. */
                /* Is the chunk feature available? */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_ChunkSelector_Framecounter");

                if (isAvail)
                {
                    /* Select the frame counter chunk feature. */
                    Pylon.DeviceFeatureFromString(hDev, "ChunkSelector", "Framecounter");

                    /* Can the chunk feature be activated? */
                    isAvail = Pylon.DeviceFeatureIsWritable(hDev, "ChunkEnable");

                    if (isAvail)
                    {
                        /* Activate the chunk feature. */
                        Pylon.DeviceSetBooleanFeature(hDev, "ChunkEnable", true);
                    }
                }
                /* ... The CRC checksum chunk feature. */

                /*  Note: Enabling the CRC checksum chunk feature is not a prerequisite for using
                 * chunks. Chunks can also be handled when the CRC checksum chunk feature is disabled. */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_ChunkSelector_PayloadCRC16");

                if (isAvail)
                {
                    /* Select the CRC checksum chunk feature. */
                    Pylon.DeviceFeatureFromString(hDev, "ChunkSelector", "PayloadCRC16");

                    /* Can the chunk feature be activated? */
                    isAvail = Pylon.DeviceFeatureIsWritable(hDev, "ChunkEnable");

                    if (isAvail)
                    {
                        /* Activate the chunk feature. */
                        Pylon.DeviceSetBooleanFeature(hDev, "ChunkEnable", true);
                    }
                }

                /* The data block containing the image chunk and the other chunks has a self-descriptive layout.
                 * A chunk parser is used to extract the appended chunk data from the grabbed image frame.
                 * Create a chunk parser. */
                hChunkParser = Pylon.DeviceCreateChunkParser(hDev);

                if (!hChunkParser.IsValid)
                {
                    /* The transport layer doesn't provide a chunk parser. */
                    throw new Exception("No chunk parser available.");
                }


                /* Image grabbing is done using a stream grabber.
                 * A device may be able to provide different streams. A separate stream grabber must
                 * be used for each stream. In this sample, we create a stream grabber for the default
                 * stream, i.e., the first stream ( index == 0 ).
                 */

                /* Get the number of streams supported by the device and the transport layer. */
                nStreams = Pylon.DeviceGetNumStreamGrabberChannels(hDev);

                if (nStreams < 1)
                {
                    throw new Exception("The transport layer doesn't support image streams.");
                }

                /* Create and open a stream grabber for the first channel. */
                hGrabber = Pylon.DeviceGetStreamGrabber(hDev, 0);
                Pylon.StreamGrabberOpen(hGrabber);

                /* Get a handle for the stream grabber's wait object. The wait object
                 * allows waiting for buffers to be filled with grabbed data. */
                hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);

                /* Determine the required size of the grab buffer. Since activating chunks will increase the
                 * payload size and thus the required buffer size, do this after enabling the chunks. */
                payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(hDev, "PayloadSize"));

                /* We must tell the stream grabber the number and size of the buffers
                 *  we are using. */
                /* .. We will not use more than NUM_BUFFERS for grabbing. */
                Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);

                /* .. We will not use buffers bigger than payloadSize bytes. */
                Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);

                /*  Allocate the resources required for grabbing. After this, critical parameters
                *   that impact the payload size must not be changed until FinishGrab() is called. */
                Pylon.StreamGrabberPrepareGrab(hGrabber);

                /* Before using the buffers for grabbing, they must be registered at
                 * the stream grabber. For each registered buffer, a buffer handle
                 * is returned. After registering, these handles are used instead of the
                 * buffer objects pointers. The buffer objects are held in a dictionary,
                 * that provides access to the buffer using a handle as key.
                 */
                buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();
                for (i = 0; i < NUM_BUFFERS; ++i)
                {
                    PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                    PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
                    buffers.Add(handle, buffer);
                }

                /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
                 * allows passing in an integer as additional context information. This integer
                 * will be returned unchanged when the grab is finished. In our example, we use the index of the
                 * buffer as context information. */
                i = 0;
                foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
                {
                    Pylon.StreamGrabberQueueBuffer(hGrabber, pair.Key, i++);
                }

                /* Issue an acquisition start command. Because the trigger mode is enabled, issuing the start command
                 * itself will not trigger any image acquisitions. Issuing the start command simply prepares the camera.
                 * Once the camera is prepared it will acquire one image for every trigger it receives. */
                Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStart");

                /* Trigger the first image. */
                Pylon.DeviceExecuteCommandFeature(hDev, "TriggerSoftware");

                /* Grab NUM_GRABS images. */
                nGrabs = 0;                           /* Counts the number of images grabbed. */
                while (nGrabs < NUM_GRABS)
                {
                    int  bufferIndex;     /* Index of the buffer. */
                    Byte min = 255, max = 0;
                    long chunkWidth  = 0; /* data retrieved from the chunk parser */
                    long chunkHeight = 0; /* data retrieved from the chunk parser */

                    /* Wait for the next buffer to be filled. Wait up to 1000 ms. */
                    isReady = Pylon.WaitObjectWait(hWait, 1000);

                    if (!isReady)
                    {
                        /* Timeout occurred. */
                        throw new Exception("Grab timeout occurred.\n");
                    }

                    /* Since the wait operation was successful, the result of at least one grab
                     * operation is available. Retrieve it. */
                    isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);

                    if (!isReady)
                    {
                        /* Oops. No grab result available? We should never have reached this point.
                         * Since the wait operation above returned without a timeout, a grab result
                         * should be available. */
                        throw new Exception("Failed to retrieve a grab result.\n");
                    }

                    nGrabs++;

                    /* Trigger the next image. Since we passed more than one buffer to the stream grabber,
                     * the triggered image will be grabbed while the image processing is performed.  */
                    Pylon.DeviceExecuteCommandFeature(hDev, "TriggerSoftware");

                    /* Get the buffer index from the context information. */
                    bufferIndex = (int)grabResult.Context;

                    /* Check to see if the image was grabbed successfully. */
                    if (grabResult.Status == EPylonGrabStatus.Grabbed)
                    {
                        /*  The grab is successful.  */

                        PylonBuffer <Byte> buffer;        /* Reference to the buffer attached to the grab result. */

                        /* Get the buffer from the dictionary. Since we also got the buffer index,
                         * we could alternatively use an array, e.g. buffers[bufferIndex]. */
                        if (!buffers.TryGetValue(grabResult.hBuffer, out buffer))
                        {
                            /* Oops. No buffer available? We should never have reached this point. Since all buffers are
                             * in the dictionary. */
                            throw new Exception("Failed to find the buffer associated with the handle returned in grab result.");
                        }

                        Console.WriteLine("Grabbed frame {0} into buffer {1}.", nGrabs, bufferIndex);

                        /* Check to see if we really got image data plus chunk data. */
                        if (grabResult.PayloadType != EPylonPayloadType.PayloadType_ChunkData)
                        {
                            Console.WriteLine("Received a buffer not containing chunk data?");
                        }
                        else
                        {
                            /* Process the chunk data. This is done by passing the grabbed image buffer
                             * to the chunk parser. When the chunk parser has processed the buffer, the chunk
                             * data can be accessed in the same manner as "normal" camera parameters.
                             * The only exception is the CRC checksum feature. There are dedicated functions for
                             * checking the CRC checksum. */

                            bool hasCRC;

                            /* Let the parser extract the data. */
                            Pylon.ChunkParserAttachBuffer(hChunkParser, buffer);


                            /* Check the CRC checksum. */
                            hasCRC = Pylon.ChunkParserHasCRC(hChunkParser);

                            if (hasCRC)
                            {
                                bool isOk = Pylon.ChunkParserCheckCRC(hChunkParser);

                                Console.WriteLine("Frame {0} contains a CRC checksum. The checksum {1} ok.", nGrabs, isOk ? "is" : "is not");
                            }

                            /* Retrieve the frame counter value. */
                            /* ... Check the availability. */
                            isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "ChunkFramecounter");

                            Console.WriteLine("Frame {0} {1} a frame counter chunk.", nGrabs, isAvail ? "contains" : "doesn't contain");
                            if (isAvail)
                            {
                                /* ... Get the value. */
                                long counter;
                                counter = Pylon.DeviceGetIntegerFeature(hDev, "ChunkFramecounter");

                                Console.WriteLine("Frame counter of frame {0}: {1}.", nGrabs, counter);
                            }

                            /* Retrieve the chunk width value. */
                            /* ... Check the availability. */
                            isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "ChunkWidth");

                            Console.WriteLine("Frame {0} {1} a frame width chunk.", nGrabs, isAvail ? "contains" : "doesn't contain");
                            if (isAvail)
                            {
                                /* ... Get the value. */
                                chunkWidth = Pylon.DeviceGetIntegerFeature(hDev, "ChunkWidth");

                                Console.WriteLine("Width of frame {0}: {1}.", nGrabs, chunkWidth);
                            }

                            /* Retrieve the chunk height value. */
                            /* ... Check the availability. */
                            isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "ChunkHeight");

                            Console.WriteLine("Frame {0} {1} a frame height chunk.", nGrabs, isAvail ? "contains" : "doesn't contain");
                            if (isAvail)
                            {
                                /* ... Get the value. */
                                chunkHeight = Pylon.DeviceGetIntegerFeature(hDev, "ChunkHeight");

                                Console.WriteLine("Height of frame {0}: {1}.", nGrabs, chunkHeight);
                            }
                        }

                        /* Perform the image processing. */
                        getMinMax(buffer.Array, chunkWidth, chunkHeight, out min, out max);
                        Console.WriteLine("Min. gray value  = {0}, Max. gray value = {1}", min, max);

                        /* Before requeueing the buffer, you should detach it from the chunk parser. */
                        Pylon.ChunkParserDetachBuffer(hChunkParser);  /* Now the chunk data in the buffer is no longer accessible. */
                    }
                    else if (grabResult.Status == EPylonGrabStatus.Failed)
                    {
                        Console.Error.WriteLine("Frame {0} wasn't grabbed successfully.  Error code = {1}", nGrabs, grabResult.ErrorCode);
                    }

                    /* Once finished with the processing, requeue the buffer to be filled again. */
                    Pylon.StreamGrabberQueueBuffer(hGrabber, grabResult.hBuffer, bufferIndex);
                }

                /* Clean up. */

                /*  ... Stop the camera. */
                Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStop");

                /* ... We must issue a cancel call to ensure that all pending buffers are put into the
                 * stream grabber's output queue. */
                Pylon.StreamGrabberCancelGrab(hGrabber);

                /* ... The buffers can now be retrieved from the stream grabber. */
                do
                {
                    isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);
                } while (isReady);

                /* ... When all buffers are retrieved from the stream grabber, they can be deregistered.
                 *     After deregistering the buffers, it is safe to free the memory */

                foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
                {
                    Pylon.StreamGrabberDeregisterBuffer(hGrabber, pair.Key);
                    pair.Value.Dispose();
                }
                buffers = null;

                /* ... Release grabbing related resources. */
                Pylon.StreamGrabberFinishGrab(hGrabber);


                /* After calling PylonStreamGrabberFinishGrab(), parameters that impact the payload size (e.g.,
                 * the AOI width and height parameters) are unlocked and can be modified again. */

                /* ... Close the stream grabber. */
                Pylon.StreamGrabberClose(hGrabber);


                /* ... Release the chunk parser. */
                Pylon.DeviceDestroyChunkParser(hDev, hChunkParser);


                /*  Disable the software trigger and chunk mode. */
                if (hDev.IsValid)
                {
                    Pylon.DeviceSetBooleanFeature(hDev, "ChunkModeActive", false);
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }

                /* ... 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. */
                Pylon.DeviceClose(hDev);
                Pylon.DestroyDevice(hDev);

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

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                /* Retrieve more details about the error.
                 * /* Retrieve the error message. */
                string msg = GenApi.GetLastErrorMessage() + "\n" + GenApi.GetLastErrorDetail();
                Console.Error.WriteLine("Exception caught:");
                Console.Error.WriteLine(e.Message);
                if (msg != "\n")
                {
                    Console.Error.WriteLine("Last error message:");
                    Console.Error.WriteLine(msg);
                }

                try
                {
                    if (hDev.IsValid)
                    {
                        /*  Disable the software trigger. */
                        Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                        /* ... Close and release the pylon device. */
                        if (Pylon.DeviceIsOpen(hDev))
                        {
                            Pylon.DeviceClose(hDev);
                        }
                        Pylon.DestroyDevice(hDev);
                    }
                }
                catch (Exception)
                {
                    /*No further handling here.*/
                }

                Pylon.Terminate();  /* Releases all pylon resources. */

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                Environment.Exit(1);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            /* Use a random number as the device key. */
            uint DeviceKey = (uint)(new Random()).Next(int.MaxValue);
            /* In this sample all cameras belong to the same group. */
            const uint GroupKey = 0x24;


            PYLON_DEVICE_HANDLE[] hDev = new PYLON_DEVICE_HANDLE[MAX_NUM_DEVICES];        /* Handles for the pylon devices. */
            for (int deviceIndex = 0; deviceIndex < MAX_NUM_DEVICES; ++deviceIndex)
            {
                hDev[deviceIndex] = new PYLON_DEVICE_HANDLE();
            }

            try
            {
                uint numDevicesEnumerated;    /* Number of the devices connected to this PC. */
                uint numDevicesToUse;         /* Number of the devices to use in this sample. */
                bool isAvail;                 /* Used for checking feature availability. */
                bool isReady;                 /* Used as an output parameter. */
                int  i;                       /* Counter. */
                uint deviceIndex;             /* Index of device used in the following variables. */
                PYLON_WAITOBJECTS_HANDLE wos; /* Wait objects. */

                /* These are camera specific variables: */
                PYLON_STREAMGRABBER_HANDLE[] hGrabber = new PYLON_STREAMGRABBER_HANDLE[MAX_NUM_DEVICES]; /* Handle for the pylon stream grabber. */
                PYLON_WAITOBJECT_HANDLE[]    hWait    = new PYLON_WAITOBJECT_HANDLE[MAX_NUM_DEVICES];    /* Handle used for waiting for a grab to be finished. */
                uint[] payloadSize = new uint[MAX_NUM_DEVICES];                                          /* Size of an image frame in bytes. */
                uint[] nStreams    = new uint[MAX_NUM_DEVICES];                                          /* The number of streams provided by the device. */
                PYLON_STREAMBUFFER_HANDLE[] hBuffer = new PYLON_STREAMBUFFER_HANDLE[MAX_NUM_DEVICES];
                PylonBuffer <Byte>[]        buffer  = new PylonBuffer <Byte> [MAX_NUM_DEVICES];

#if DEBUG
                /* This is a special debug setting needed only for GigE cameras.
                 * See 'Building Applications with pylon' in the Programmer's Guide. */
                Environment.SetEnvironmentVariable("PYLON_GIGE_HEARTBEAT", "300000" /*ms*/);
#endif

                /* Before using any pylon methods, the pylon runtime must be initialized. */
                Pylon.Initialize();

                /* Enumerate all camera devices. You must call
                 * PylonEnumerateDevices() before creating a device. */
                numDevicesEnumerated = Pylon.EnumerateDevices();

                if (numDevicesEnumerated == 0)
                {
                    Pylon.Terminate();

                    Console.Error.WriteLine("No devices found!");
                    Console.Error.WriteLine("\nPress enter to exit.");
                    Console.ReadLine();
                    return;
                }

                /* Create wait objects. This must be done outside of the loop. */
                wos = Pylon.WaitObjectsCreate();

                /* Open cameras and set parameter */
                deviceIndex = 0;
                for (uint enumeratedDeviceIndex = 0; enumeratedDeviceIndex < numDevicesEnumerated; ++enumeratedDeviceIndex)
                {
                    /* only open GigE devices */
                    PYLON_DEVICE_INFO_HANDLE hDI = Pylon.GetDeviceInfoHandle(enumeratedDeviceIndex);
                    if (Pylon.DeviceInfoGetPropertyValueByName(hDI, Pylon.cPylonDeviceInfoDeviceClassKey) != "BaslerGigE")
                    {
                        continue;
                    }

                    /* Get handles for the devices. */
                    hDev[deviceIndex] = Pylon.CreateDeviceByIndex((uint)enumeratedDeviceIndex);

                    /* Before using the device, it must be opened. Open it for configuring
                     * parameters and for grabbing images. */
                    Pylon.DeviceOpen(hDev[deviceIndex], Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);

                    /* Print out the name of the camera we are using. */
                    Console.WriteLine("Using camera '{0}'", Pylon.DeviceInfoGetPropertyValueByName(hDI, Pylon.cPylonDeviceInfoModelNameKey));

                    isAvail = Pylon.DeviceFeatureIsReadable(hDev[deviceIndex], "ActionControl");
                    if (!isAvail)
                    {
                        throw new Exception("Device doesn't support the Action Command");
                    }

                    /* Configure the first action */
                    Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "ActionSelector", 1);
                    Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "ActionDeviceKey", DeviceKey);
                    Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "ActionGroupKey", GroupKey);
                    Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "ActionGroupMask", AllGroupMask);

                    /* Set the pixel format to Mono8, where gray values will be output as 8 bit values for each pixel. */
                    /* ... Check first to see if the device supports the Mono8 format. */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev[deviceIndex], "EnumEntry_PixelFormat_Mono8");
                    if (!isAvail)
                    {
                        /* Feature is not available. */
                        throw new Exception("Device doesn't support the Mono8 pixel format.");
                    }

                    /* ... Set the pixel format to Mono8. */
                    Pylon.DeviceFeatureFromString(hDev[deviceIndex], "PixelFormat", "Mono8");


                    /* Disable acquisition start trigger if available */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev[deviceIndex], "EnumEntry_TriggerSelector_AcquisitionStart");
                    if (isAvail)
                    {
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerSelector", "AcquisitionStart");
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerMode", "Off");
                    }
                    /* Disable line1 trigger if available */
                    isAvail = Pylon.DeviceFeatureIsAvailable(hDev[deviceIndex], "EnumEntry_TriggerSelector_Line1");
                    if (isAvail)
                    {
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerSelector", "Line1");
                        Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerMode", "Off");
                    }

                    /* Enable frame start trigger with first action */
                    Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerSelector", "FrameStart");
                    Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerMode", "On");
                    Pylon.DeviceFeatureFromString(hDev[deviceIndex], "TriggerSource", "Action1");

                    /* For GigE cameras, we recommend increasing the packet size for better
                     *  performance. When the network adapter supports jumbo frames, set the packet
                     *  size to a value > 1500, e.g., to 8192. In this sample, we only set the packet size
                     *  to 1500.
                     *
                     *  We also set the Inter-Packet and the Frame Transmission delay
                     *  so the switch can line up packets better.
                     */
                    Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "GevSCPSPacketSize", GIGE_PACKET_SIZE);
                    Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "GevSCPD", (GIGE_PACKET_SIZE + GIGE_PROTOCOL_OVERHEAD) * (MAX_NUM_DEVICES - 1));
                    Pylon.DeviceSetIntegerFeature(hDev[deviceIndex], "GevSCFTD", (GIGE_PACKET_SIZE + GIGE_PROTOCOL_OVERHEAD) * deviceIndex);

                    /* one device opened */
                    ++deviceIndex;
                }

                /* remember how many devices we have actually created */
                numDevicesToUse = deviceIndex;

                /* Remember the number of devices actually created */
                numDevicesToUse = deviceIndex;

                if (numDevicesToUse == 0)
                {
                    Console.Error.WriteLine("No suitable cameras found!");
                    Pylon.Terminate();  /* Releases all pylon resources. */
                    Console.Error.WriteLine("\nPress enter to exit.");
                    Console.ReadLine();
                    Environment.Exit(0);
                }

                if (numDevicesToUse < 2)
                {
                    Console.Error.WriteLine("WARNING: This sample works best with two or more GigE cameras supporting action commands.");
                }

                /* Allocate and register buffers for grab. */
                for (deviceIndex = 0; deviceIndex < numDevicesToUse; ++deviceIndex)
                {
                    /* Determine the required size for the grab buffer. */
                    payloadSize[deviceIndex] = checked ((uint)Pylon.DeviceGetIntegerFeature(hDev[deviceIndex], "PayloadSize"));

                    /* Image grabbing is done using a stream grabber.
                     * A device may be able to provide different streams. A separate stream grabber must
                     * be used for each stream. In this sample, we create a stream grabber for the default
                     * stream, i.e., the first stream ( index == 0 ).
                     */

                    /* Get the number of streams supported by the device and the transport layer. */
                    nStreams[deviceIndex] = Pylon.DeviceGetNumStreamGrabberChannels(hDev[deviceIndex]);

                    if (nStreams[deviceIndex] < 1)
                    {
                        throw new Exception("The transport layer doesn't support image streams.");
                    }

                    /* Create and open a stream grabber for the first channel. */
                    hGrabber[deviceIndex] = Pylon.DeviceGetStreamGrabber(hDev[deviceIndex], 0);

                    Pylon.StreamGrabberOpen(hGrabber[deviceIndex]);


                    /* Get a handle for the stream grabber's wait object. The wait object
                     * allows waiting for buffers to be filled with grabbed data. */
                    hWait[deviceIndex] = Pylon.StreamGrabberGetWaitObject(hGrabber[deviceIndex]);

                    /* Add the stream grabber's wait object to our wait objects.
                     * This is needed to be able to wait until all cameras have
                     * grabbed an image in our grab loop below. */
                    Pylon.WaitObjectsAdd(wos, hWait[deviceIndex]);

                    /* We must tell the stream grabber the number and size of the buffers
                     *  we are using. */
                    /* .. We will not use more than NUM_BUFFERS for grabbing. */
                    Pylon.StreamGrabberSetMaxNumBuffer(hGrabber[deviceIndex], NUM_BUFFERS);

                    /* .. We will not use buffers bigger than payloadSize bytes. */
                    Pylon.StreamGrabberSetMaxBufferSize(hGrabber[deviceIndex], payloadSize[deviceIndex]);

                    /*  Allocate the resources required for grabbing. After this, critical parameters
                    *   that impact the payload size must not be changed until FinishGrab() is called. */
                    Pylon.StreamGrabberPrepareGrab(hGrabber[deviceIndex]);

                    /* Before using the buffers for grabbing, they must be registered at
                     * the stream grabber. For each registered buffer, a buffer handle
                     * is returned. After registering, these handles are used instead of the
                     * buffer objects pointers. The buffer objects are held in a dictionary,
                     * that provides access to the buffer using a handle as key.
                     */
                    buffer[deviceIndex]  = new PylonBuffer <byte>(payloadSize[deviceIndex], true);
                    hBuffer[deviceIndex] = Pylon.StreamGrabberRegisterBuffer(hGrabber[deviceIndex], ref buffer[deviceIndex]);

                    /* Feed the buffers into the stream grabber's input queue. */
                    Pylon.StreamGrabberQueueBuffer(hGrabber[deviceIndex], hBuffer[deviceIndex], 0);
                }

                /* The stream grabber is now prepared. Start the image acquisition.
                 * The camera won't send any image data, since it's configured to wait
                 * for the action to trigger the acquisition */
                for (deviceIndex = 0; deviceIndex < numDevicesToUse; ++deviceIndex)
                {
                    Pylon.DeviceExecuteCommandFeature(hDev[deviceIndex], "AcquisitionStart");
                }


                /*  ======================================================================
                 *  Issue an ActionCommand and retrieve the images.
                 *  ====================================================================== */
                Console.WriteLine("*** Issuing action command ***");

                /* Trigger the camera using an action command (w/o waiting for results).
                 * If your setup support PTP, you could use a scheduled action command.
                 * Pylon.GigEIssueScheduledActionCommand(subnet, DefaultDeviceKey, DefaultGroupKey, 1, triggertime, 0)
                 */
                string subnet = Pylon.DeviceInfoGetPropertyValueByName(Pylon.DeviceGetDeviceInfoHandle(hDev[0]), "SubnetAddress");

                Pylon.GigEIssueActionCommand(DeviceKey, GroupKey, 1, subnet);

                /* Grab one image from each camera. */
                for (i = 0; i < numDevicesToUse; ++i)
                {
                    uint woIndex; /* this corresponds to the index in hDev and hGrabber */

                    /* Wait for the next buffer to be filled. Wait up to 5000 ms. */
                    isReady = Pylon.WaitObjectsWaitForAny(wos, 5000, out woIndex);

                    if (!isReady)
                    {   /* Timeout occurred */
                        /* Grab Timeout occurred. */
                        throw new Exception("Grab timeout occurred.");
                    }

                    PylonGrabResult_t grabResult;

                    /* Since the wait operation was successful, the result of at least one grab
                     * operation is available. Retrieve it. */
                    isReady = Pylon.StreamGrabberRetrieveResult(hGrabber[woIndex], out grabResult);

                    if (!isReady)
                    {
                        /* Oops. No grab result available? We should never have reached this point.
                         * Since the wait operation above returned without a timeout, a grab result
                         * should be available. */
                        throw new Exception("Failed to retrieve a grab result.");
                    }

                    /* Check to see if the image was grabbed successfully. */
                    if (grabResult.Status == EPylonGrabStatus.Grabbed)
                    {
                        /* Success. Perform image processing. Since we passed more than one buffer
                         * to the stream grabber, the remaining buffers are filled in the background while
                         * we do the image processing. The processed buffer won't be touched by
                         * the stream grabber until we pass it back to the stream grabber. */

                        /* We only use one buffer per camera */
                        System.Diagnostics.Debug.Assert(grabResult.hBuffer == hBuffer[woIndex]);

                        byte pixel = buffer[woIndex].Array[0];

                        /* Perform processing. */
                        Console.WriteLine("Grabbed a frame from camera {0}.", woIndex);

                        /* Display image */
                        if (woIndex < 32)
                        {
                            Pylon.ImageWindowDisplayImage <Byte>(woIndex, buffer[woIndex], grabResult);
                        }
                    }
                    else if (grabResult.Status == EPylonGrabStatus.Failed)
                    {
                        /* If a buffer has been incompletely grabbed the network bandwidth is possibly insufficient for transferring
                         * multiple images simultaneously. See note above MAX_NUM_DEVICES. */
                        Console.Error.WriteLine("Frame from camera {0} wasn't grabbed successfully.  Error code = {1}",
                                                woIndex, grabResult.ErrorCode);
                    }
                }

                /* Stop the image acquisition on the cameras. */
                for (deviceIndex = 0; deviceIndex < numDevicesToUse; ++deviceIndex)
                {
                    /*  Stop the camera. */
                    Pylon.DeviceExecuteCommandFeature(hDev[deviceIndex], "AcquisitionStop");
                }

                // Remove all wait objects from WaitObjects.
                Pylon.WaitObjectsRemoveAll(wos);
                Pylon.WaitObjectsDestroy(wos);

                for (deviceIndex = 0; deviceIndex < numDevicesToUse; ++deviceIndex)
                {
                    /* We must issue a cancel call to ensure that all pending buffers are put into the
                     * stream grabber's output queue. */
                    Pylon.StreamGrabberCancelGrab(hGrabber[deviceIndex]);

                    /* The buffers can now be retrieved from the stream grabber. */
                    do
                    {
                        PylonGrabResult_t grabResult;
                        isReady = Pylon.StreamGrabberRetrieveResult(hGrabber[deviceIndex], out grabResult);
                    } while (isReady);

                    /* When all buffers are retrieved from the stream grabber, they can be de-registered.
                     * After de-registering the buffers, it is safe to free the memory. */

                    Pylon.StreamGrabberDeregisterBuffer(hGrabber[deviceIndex], hBuffer[deviceIndex]);
                    buffer[deviceIndex].Dispose();
                    buffer[deviceIndex] = null;

                    /* Release grabbing related resources. */
                    Pylon.StreamGrabberFinishGrab(hGrabber[deviceIndex]);

                    /* After calling PylonStreamGrabberFinishGrab(), parameters that impact the payload size (e.g.,
                     * the AOI width and height parameters) are unlocked and can be modified again. */

                    /* Close the stream grabber. */
                    Pylon.StreamGrabberClose(hGrabber[deviceIndex]);

                    /* 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. */
                    Pylon.DeviceClose(hDev[deviceIndex]);
                    Pylon.DestroyDevice(hDev[deviceIndex]);
                }


                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                /* Shut down the pylon runtime system. Don't call any pylon function after
                 * calling PylonTerminate(). */
                Pylon.Terminate();
            }
            catch (Exception e)
            {
                /* Retrieve the error message. */
                string msg = GenApi.GetLastErrorMessage() + "\n" + GenApi.GetLastErrorDetail();
                Console.Error.WriteLine("Exception caught:");
                Console.Error.WriteLine(e.Message);
                if (msg != "\n")
                {
                    Console.Error.WriteLine("Last error message:");
                    Console.Error.WriteLine(msg);
                }

                for (uint deviceIndex = 0; deviceIndex < MAX_NUM_DEVICES; ++deviceIndex)
                {
                    try
                    {
                        if (hDev[deviceIndex].IsValid)
                        {
                            /* Close and release the pylon device. */
                            if (Pylon.DeviceIsOpen(hDev[deviceIndex]))
                            {
                                Pylon.DeviceClose(hDev[deviceIndex]);
                            }
                            Pylon.DestroyDevice(hDev[deviceIndex]);
                        }
                    }
                    catch (Exception)
                    {
                        /* No further handling here.*/
                    }
                }
                Pylon.Terminate();  /* Releases all pylon resources. */

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                Environment.Exit(1);
            }
        }
Esempio n. 15
0
        private void initStreamMode()
        {
            _width  = (int)Pylon.DeviceGetIntegerFeature(hDev, "Width");
            _height = (int)Pylon.DeviceGetIntegerFeature(hDev, "Height");
            /* Print out the name of the camera we are using. */
            bool isReadable = Pylon.DeviceFeatureIsReadable(hDev, "DeviceModelName");

            if (isReadable)
            {
                string name = Pylon.DeviceFeatureToString(hDev, "DeviceModelName");
                Console.WriteLine("Using camera {0}.", name);
            }

            /* Set the pixel format to Mono8, where gray values will be output as 8 bit values for each pixel. */
            /* ... Check first to see if the device supports the Mono8 format. */
            isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8");

            if (!isAvail)
            {
                /* Feature is not available. */
                throw new Exception("Device doesn't support the Mono8 pixel format.");
            }
            /* ... Set the pixel format to Mono8. */
            bool isWritable = Pylon.DeviceFeatureIsWritable(hDev, "PixelFormat");

            if (isWritable)
            {
                Pylon.DeviceFeatureFromString(hDev, "PixelFormat", "Mono8");
            }

            /* Disable acquisition start trigger if available */
            isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_AcquisitionStart");
            if (isAvail)
            {
                isWritable = Pylon.DeviceFeatureIsWritable(hDev, "TriggerSelector");
                if (isWritable)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "AcquisitionStart");
                }

                isWritable = Pylon.DeviceFeatureIsWritable(hDev, "TriggerMode");
                if (isWritable)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }
            }

            /* Disable frame start trigger if available */
            isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameStart");
            if (isAvail)
            {
                isWritable = Pylon.DeviceFeatureIsWritable(hDev, "TriggerSelector");
                if (isWritable)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameStart");
                }

                isWritable = Pylon.DeviceFeatureIsWritable(hDev, "TriggerMode");
                if (isWritable)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }
            }

            /* We will use the Continuous frame mode, i.e., the camera delivers
             * images continuously. */
            isWritable = Pylon.DeviceFeatureIsWritable(hDev, "AcquisitionMode");
            if (isWritable)
            {
                Pylon.DeviceFeatureFromString(hDev, "AcquisitionMode", "Continuous");
            }

            /* For GigE cameras, we recommend increasing the packet size for better
             * performance. When the network adapter supports jumbo frames, set the packet
             * size to a value > 1500, e.g., to 8192. In this sample, we only set the packet size
             * to 1500. */
            /* ... Check first to see if the GigE camera packet size parameter is supported and if it is writable. */
            isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");
            if (isAvail)
            {
                /* ... The device supports the packet size feature. Set a value. */
                isWritable = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");
                if (isWritable)
                {
                    Pylon.DeviceSetIntegerFeature(hDev, "GevSCPSPacketSize", GevSCPSPacketSize);
                }
            }
            _isModelValid = isAvail;
            /* Determine the required size of the grab buffer. */
            payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(hDev, "PayloadSize"));

            /* Image grabbing is done using a stream grabber.
             * A device may be able to provide different streams. A separate stream grabber must
             * be used for each stream. In this sample, we create a stream grabber for the default
             * stream, i.e., the first stream ( index == 0 ).
             */

            /* Get the number of streams supported by the device and the transport layer. */
            nStreams = Pylon.DeviceGetNumStreamGrabberChannels(hDev);

            if (nStreams < 1)
            {
                throw new Exception("The transport layer doesn't support image streams.");
            }

            /* Create and open a stream grabber for the first channel. */
            hGrabber = Pylon.DeviceGetStreamGrabber(hDev, 0);
            Pylon.StreamGrabberOpen(hGrabber);

            /* Get a handle for the stream grabber's wait object. The wait object
             * allows waiting for buffers to be filled with grabbed data. */
            hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);

            /* We must tell the stream grabber the number and size of the buffers
             *      we are using. */
            /* .. We will not use more than NUM_BUFFERS for grabbing. */
            Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);

            /* .. We will not use buffers bigger than payloadSize bytes. */
            Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);

            /*  Allocate the resources required for grabbing. After this, critical parameters
            *       that impact the payload size must not be changed until FinishGrab() is called. */
            Pylon.StreamGrabberPrepareGrab(hGrabber);

            /* Before using the buffers for grabbing, they must be registered at
             * the stream grabber. For each registered buffer, a buffer handle
             * is returned. After registering, these handles are used instead of the
             * buffer objects pointers. The buffer objects are held in a dictionary,
             * that provides access to the buffer using a handle as key.
             */
            buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();
            int i;

            for (i = 0; i < NUM_BUFFERS; ++i)
            {
                PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
                buffers.Add(handle, buffer);
            }

            /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
             * allows passing in an integer as additional context information. This integer
             * will be returned unchanged when the grab is finished. In our example, we use the index of the
             * buffer as context information. */
            i = 0;
            foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
            {
                Pylon.StreamGrabberQueueBuffer(hGrabber, pair.Key, i++);
            }
        }
Esempio n. 16
0
        const uint NUM_EVENT_BUFFERS = 20;   /* Number of buffers used for grabbing. */

        static void Main(string[] args)
        {
            PYLON_DEVICE_HANDLE hDev = new PYLON_DEVICE_HANDLE(); /* Handle for the pylon device. */

            try
            {
                uint numDevices;                                                     /* Number of available devices. */
                PYLON_STREAMGRABBER_HANDLE hStreamGrabber;                           /* Handle for the pylon stream grabber. */
                PYLON_EVENTGRABBER_HANDLE  hEventGrabber;                            /* Handle for the event grabber used for receiving events. */
                PYLON_EVENTADAPTER_HANDLE  hEventAdapter;                            /* Handle for the event adapter used for dispatching events. */
                PYLON_WAITOBJECT_HANDLE    hWaitStream;                              /* Handle used for waiting for a grab to be finished. */
                PYLON_WAITOBJECT_HANDLE    hWaitEvent;                               /* Handle used for waiting for an event message. */
                PYLON_WAITOBJECTS_HANDLE   hWaitObjects;                             /* Container allowing waiting for multiple wait objects. */
                NODEMAP_HANDLE             hNodeMap;                                 /* Handle for the node map containing the
                                                                                      *  camera parameters. */
                NODE_CALLBACK_HANDLE hCallback;                                      /* Used for deregistering a callback function. */
                NODE_HANDLE          hNode;                                          /* Handle for a camera parameter. */
                uint payloadSize;                                                    /* Size of an image frame in bytes. */
                Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > buffers; /* Holds handles and buffers used for grabbing. */
                PylonGrabResult_t   grabResult;                                      /* Stores the result of a grab operation. */
                NodeCallbackHandler callbackHandler = new NodeCallbackHandler();     /* Handles incoming callbacks. */
                int  nGrabs;                                                         /* Counts the number of buffers grabbed. */
                uint nStreams;                                                       /* The number of streams the device provides. */
                bool isAvail;                                                        /* Used for checking feature availability. */
                bool isReady;                                                        /* Used as an output parameter. */
                int  i;                                                              /* Counter. */
                PylonEventResult_t eventMsg = new PylonEventResult_t();              /* Event data container. */
                long sfncVersionMajor;                                               /* The major number of the Standard Feature Naming Convention (SFNC)
                                                                                      * version used by the camera device. */

#if DEBUG
                /* This is a special debug setting needed only for GigE cameras.
                 * See 'Building Applications with pylon' in the programmer's guide */
                Environment.SetEnvironmentVariable("PYLON_GIGE_HEARTBEAT", "300000" /*ms*/);
#endif

                /* Before using any pylon methods, the pylon runtime must be initialized. */
                Pylon.Initialize();

                /* Enumerate all camera devices. You must call
                 * PylonEnumerateDevices() before creating a device. */
                numDevices = Pylon.EnumerateDevices();

                if (0 == numDevices)
                {
                    throw new Exception("No devices found.");
                }

                /* Get a handle for the first device found.  */
                hDev = Pylon.CreateDeviceByIndex(0);

                /* Before using the device, it must be opened. Open it for configuring
                 * parameters, for grabbing images, and for grabbing events. */
                Pylon.DeviceOpen(hDev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream | Pylon.cPylonAccessModeEvent);

                /* Print out the name of the camera we are using. */
                {
                    bool isReadable = Pylon.DeviceFeatureIsReadable(hDev, "DeviceModelName");
                    if (isReadable)
                    {
                        string name = Pylon.DeviceFeatureToString(hDev, "DeviceModelName");
                        Console.WriteLine("Using camera {0}", name);
                    }
                }

                /* Set the pixel format to Mono8, where gray values will be output as 8 bit values for each pixel. */
                /* ... Check first to see if the device supports the Mono8 format. */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8");

                if (!isAvail)
                {
                    /* Feature is not available. */
                    throw new Exception("Device doesn't support the Mono8 pixel format.");
                }
                /* ... Set the pixel format to Mono8. */
                Pylon.DeviceFeatureFromString(hDev, "PixelFormat", "Mono8");

                /* Disable acquisition start trigger if available. */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_AcquisitionStart");
                if (isAvail)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "AcquisitionStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }

                /* Disable frame burst start trigger if available */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameBurstStart");
                if (isAvail)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameBurstStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }

                /* Disable frame start trigger if available. */
                isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameStart");
                if (isAvail)
                {
                    Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameStart");
                    Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                }

                /* We will use the Continuous frame mode, i.e., the camera delivers
                 * images continuously. */
                Pylon.DeviceFeatureFromString(hDev, "AcquisitionMode", "Continuous");

                /* For GigE cameras, we recommend increasing the packet size for better
                 * performance. If the network adapter supports jumbo frames, set the packet
                 * size to a value > 1500, e.g., to 8192. In this sample, we only set the packet size
                 * to 1500. */
                /* ... Check first to see if the GigE camera packet size parameter is supported and if it is writable. */
                isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");

                if (isAvail)
                {
                    /* ... The device supports the packet size feature. Set a value. */
                    Pylon.DeviceSetIntegerFeature(hDev, "GevSCPSPacketSize", 1500);
                }

                /* Determine the required size of the grab buffer. */
                payloadSize = checked ((uint)Pylon.DeviceGetIntegerFeature(hDev, "PayloadSize"));

                /* Determine the major number of the SFNC version used by the camera device. */
                if (Pylon.DeviceFeatureIsAvailable(hDev, "DeviceSFNCVersionMajor"))
                {
                    sfncVersionMajor = Pylon.DeviceGetIntegerFeature(hDev, "DeviceSFNCVersionMajor");
                }
                else
                {
                    /* No SFNC version information is provided by the camera device. */
                    sfncVersionMajor = 0;
                }

                /* Enable camera events. */
                /* Select the end-of-exposure event.*/
                Pylon.DeviceFeatureFromString(hDev, "EventSelector", "ExposureEnd");
                /* Enable the event. Select the enumeration entry name depending on the SFNC version used by the camera device. */
                if (sfncVersionMajor >= 2)
                {
                    Pylon.DeviceFeatureFromString(hDev, "EventNotification", "On");
                }
                else
                {
                    Pylon.DeviceFeatureFromString(hDev, "EventNotification", "GenICamEvent");
                }

                /* Image grabbing is done using a stream grabber.
                 * A device may be able to provide different streams. A separate stream grabber must
                 * be used for each stream. In this sample, we create a stream grabber for the default
                 * stream, i.e., the first stream ( index == 0 ).
                 */

                /* Get the number of streams supported by the device and the transport layer. */
                nStreams = Pylon.DeviceGetNumStreamGrabberChannels(hDev);
                if (nStreams < 1)
                {
                    throw new Exception("The transport layer doesn't support image streams");
                }

                /* Create and open a stream grabber for the first channel. */
                hStreamGrabber = Pylon.DeviceGetStreamGrabber(hDev, 0);
                Pylon.StreamGrabberOpen(hStreamGrabber);

                /* Get a handle for the stream grabber's wait object. The wait object
                 * allows waiting for buffers to be grabbed. */
                hWaitStream = Pylon.StreamGrabberGetWaitObject(hStreamGrabber);

                /* We must tell the stream grabber the number and size of the buffers
                 * we are using. */
                /* .. We will not use more than NUM_BUFFERS for grabbing. */
                Pylon.StreamGrabberSetMaxNumBuffer(hStreamGrabber, NUM_IMAGE_BUFFERS);

                /* .. We will not use buffers bigger than payloadSize bytes. */
                Pylon.StreamGrabberSetMaxBufferSize(hStreamGrabber, payloadSize);

                /*  Allocate the resources required for grabbing. After this, critical parameters
                *  that impact the payload size must not be changed until FinishGrab() is called. */
                Pylon.StreamGrabberPrepareGrab(hStreamGrabber);

                /* Before using the buffers for grabbing, they must be registered at
                 * the stream grabber. For each registered buffer, a buffer handle
                 * is returned. After registering, these handles are used instead of the
                 * buffer object pointers. The buffer objects are held in a dictionary,
                 * that provides access to the buffer using a handle as key.
                 */
                buffers = new Dictionary <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> >();
                for (i = 0; i < NUM_IMAGE_BUFFERS; ++i)
                {
                    PylonBuffer <Byte>        buffer = new PylonBuffer <byte>(payloadSize, true);
                    PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hStreamGrabber, ref buffer);
                    buffers.Add(handle, buffer);
                }

                /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
                 * allows passing in an integer as additional context information. This integer
                 * will be returned unchanged when the grab is finished. In our example, we use the index of the
                 * buffer as context information. */
                i = 0;
                foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
                {
                    Pylon.StreamGrabberQueueBuffer(hStreamGrabber, pair.Key, i++);
                }

                /* The stream grabber is now prepared. As soon the camera starts to acquire images,
                 * the image data will be grabbed into the provided buffers.  */


                /* Create and prepare an event grabber. */
                /* ... Get a handle for the event grabber. */
                hEventGrabber = Pylon.DeviceGetEventGrabber(hDev);

                if (!hEventGrabber.IsValid)
                {
                    /* The transport layer doesn't support event grabbers. */
                    throw new Exception("No event grabber supported.");
                }

                /* ... Tell the grabber how many buffers to use. */
                Pylon.EventGrabberSetNumBuffers(hEventGrabber, NUM_EVENT_BUFFERS);

                /* ... Open the event grabber. */
                Pylon.EventGrabberOpen(hEventGrabber);  /* The event grabber is now ready
                                                         * for receiving events. */

                /* Retrieve the wait object that is associated with the event grabber. The event
                 * will be signaled when an event message has been received. */
                hWaitEvent = Pylon.EventGrabberGetWaitObject(hEventGrabber);

                /* For extracting the event data from an event message, an event adapter is used. */
                hEventAdapter = Pylon.DeviceCreateEventAdapter(hDev);

                if (!hEventAdapter.IsValid)
                {
                    /* The transport layer doesn't support event grabbers. */
                    throw new Exception("No event adapter supported.");
                }

                /* Register the callback function for the ExposureEndEventFrameID parameter. */
                /*.Get the node map containing all parameters. */
                hNodeMap = Pylon.DeviceGetNodeMap(hDev);

                /* Get the ExposureEndEventFrameID parameter.
                 * Select the parameter name depending on the SFNC version used by the camera device.
                 */
                if (sfncVersionMajor >= 2)
                {
                    hNode = GenApi.NodeMapGetNode(hNodeMap, "EventExposureEndFrameID");
                }
                else
                {
                    hNode = GenApi.NodeMapGetNode(hNodeMap, "ExposureEndEventFrameID");
                }

                if (!hNode.IsValid)
                {
                    /* There is no ExposureEndEventFrameID parameter. */
                    throw new Exception("There is no ExposureEndEventFrameID or EventExposureEndFrameID parameter!");
                }
                /* ... Register the callback function. */
                callbackHandler.CallbackEvent += new NodeCallbackHandler.NodeCallback(endOfExposureCallback);
                hCallback = GenApi.NodeRegisterCallback(hNode, callbackHandler);

                /* Put the wait objects into a container. */
                /* ... Create the container. */
                hWaitObjects = Pylon.WaitObjectsCreate();

                /* ... Add the wait objects' handles. */
                Pylon.WaitObjectsAdd(hWaitObjects, hWaitEvent);
                Pylon.WaitObjectsAdd(hWaitObjects, hWaitStream);

                /* Let the camera acquire images. */
                Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStart");

                /* Grab NUM_GRABS images. */
                nGrabs = 0;                         /* Counts the number of images grabbed. */
                while (nGrabs < NUM_GRABS)
                {
                    int  bufferIndex;             /* Index of the buffer. */
                    uint waitObjectIndex;         /* Index of the wait object that is signalled.*/
                    Byte min, max;

                    /* Wait for either an image buffer grabbed or an event received. Wait up to 1000 ms. */
                    isReady = Pylon.WaitObjectsWaitForAny(hWaitObjects, 1000, out waitObjectIndex);

                    if (!isReady)
                    {
                        /* Timeout occurred. */
                        throw new Exception("Timeout. Neither grabbed an image nor received an event.");
                    }

                    if (0 == waitObjectIndex)
                    {
                        /* hWaitEvent has been signalled. At least one event message is available. Retrieve it. */
                        isReady = Pylon.EventGrabberRetrieveEvent(hEventGrabber, ref eventMsg);

                        if (!isReady)
                        {
                            /* Oops. No event message available? We should never have reached this point.
                             * Since the wait operation above returned without a timeout, an event message
                             * should be available. */
                            throw new Exception("Failed to retrieve an event.");
                        }
                        /* Check to see if the event was successfully received. */
                        if (0 == eventMsg.ErrorCode)
                        {
                            /* Successfully received an event message. */

                            /* Pass the event message to the event adapter. The event adapter will
                             * update the parameters related to events and will fire the callbacks
                             * registered to event related parameters. */
                            Pylon.EventAdapterDeliverMessage(hEventAdapter, eventMsg);
                        }
                        else
                        {
                            Console.Error.WriteLine("Error when receiving an event: {1}", eventMsg.ErrorCode);
                        }
                    }
                    else if (1 == waitObjectIndex)
                    {
                        /* hWaitStream  has been signalled. The result of at least one grab
                         * operation is available. Retrieve it. */
                        isReady = Pylon.StreamGrabberRetrieveResult(hStreamGrabber, out grabResult);

                        if (!isReady)
                        {
                            /* Oops. No grab result available? We should never have reached this point.
                             * Since the wait operation above returned without a timeout, a grab result
                             * should be available. */
                            throw new Exception("Failed to retrieve a grab result.");
                        }

                        nGrabs++;

                        /* Get the buffer index from the context information. */
                        bufferIndex = (int)grabResult.Context;

                        /* Check to see if the image was grabbed successfully. */
                        if (grabResult.Status == EPylonGrabStatus.Grabbed)
                        {
                            /*  Success. Perform image processing. Since we passed more than one buffer
                             * to the stream grabber, the remaining buffers are filled while
                             * we do the image processing. The processed buffer won't be touched by
                             * the stream grabber until we pass it back to the stream grabber. */

                            PylonBuffer <Byte> buffer;        /* Reference to the buffer attached to the grab result. */

                            /* Get the buffer from the dictionary. Since we also got the buffer index,
                             * we could alternatively use an array, e.g. buffers[bufferIndex]. */
                            if (!buffers.TryGetValue(grabResult.hBuffer, out buffer))
                            {
                                /* Oops. No buffer available? We should never have reached this point. Since all buffers are
                                 * in the dictionary. */
                                throw new Exception("Failed to find the buffer associated with the handle returned in grab result.");
                            }

                            getMinMax(buffer.Array, out min, out max);
                            Console.WriteLine("Grabbed frame {0} into buffer {1}. Min. gray value = {2}, Max. gray value = {3}",
                                              nGrabs, bufferIndex, min, max);
                        }
                        else if (grabResult.Status == EPylonGrabStatus.Failed)
                        {
                            Console.Error.WriteLine("Frame {0} wasn't grabbed successfully.  Error code = {1}",
                                                    nGrabs, grabResult.ErrorCode);
                        }

                        /* Once finished with the processing, requeue the buffer to be filled again. */
                        Pylon.StreamGrabberQueueBuffer(hStreamGrabber, grabResult.hBuffer, bufferIndex);
                    }
                }

                /* Clean up. */

                /*  ... Stop the camera. */
                Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStop");

                /* ... Switch off the events. */
                Pylon.DeviceFeatureFromString(hDev, "EventSelector", "ExposureEnd");
                Pylon.DeviceFeatureFromString(hDev, "EventNotification", "Off");


                /* ... We must issue a cancel call to ensure that all pending buffers are put into the
                 * stream grabber's output queue. */
                Pylon.StreamGrabberCancelGrab(hStreamGrabber);

                /* ... The buffers can now be retrieved from the stream grabber. */
                do
                {
                    isReady = Pylon.StreamGrabberRetrieveResult(hStreamGrabber, out grabResult);
                } while (isReady);

                /* ... When all buffers are retrieved from the stream grabber, they can be deregistered.
                 *     After deregistering the buffers, it is safe to free the memory. */
                foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers)
                {
                    Pylon.StreamGrabberDeregisterBuffer(hStreamGrabber, pair.Key);
                    pair.Value.Dispose();
                }
                buffers = null;


                /* ... Release grabbing related resources. */
                Pylon.StreamGrabberFinishGrab(hStreamGrabber);

                /* After calling PylonStreamGrabberFinishGrab(), parameters that impact the payload size (e.g.,
                 * the AOI width and height parameters) are unlocked and can be modified again. */

                /* ... Close the stream grabber. */
                Pylon.StreamGrabberClose(hStreamGrabber);

                /* ... Deregister the callback. */
                GenApi.NodeDeregisterCallback(hNode, hCallback);

                /* ... Close the event grabber.*/
                Pylon.EventGrabberClose(hEventGrabber);

                /* ... Release the event adapter. */
                Pylon.DeviceDestroyEventAdapter(hDev, hEventAdapter);

                /* ... Release the wait object container. */
                Pylon.WaitObjectsDestroy(hWaitObjects);

                /* ... 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. */
                Pylon.DeviceClose(hDev);
                Pylon.DestroyDevice(hDev);

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

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                /* Retrieve the error message. */
                string msg = GenApi.GetLastErrorMessage() + "\n" + GenApi.GetLastErrorDetail();
                Console.Error.WriteLine("Exception caught:");
                Console.Error.WriteLine(e.Message);
                if (msg != "\n")
                {
                    Console.Error.WriteLine("Last error message:");
                    Console.Error.WriteLine(msg);
                }

                try
                {
                    if (hDev.IsValid)
                    {
                        /*  Disable the software trigger. */
                        Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
                        /* ... Close and release the pylon device. */
                        if (Pylon.DeviceIsOpen(hDev))
                        {
                            Pylon.DeviceClose(hDev);
                        }
                        Pylon.DestroyDevice(hDev);
                    }
                }
                catch (Exception)
                {
                    /*No further handling here.*/
                }

                Pylon.Terminate();  /* Releases all pylon resources. */

                Console.Error.WriteLine("\nPress enter to exit.");
                Console.ReadLine();

                Environment.Exit(1);
            }
        }