public void stopFrameGrab(string cameraType) { if (cameraType == "basler") { //Stops acquisition and closes camera. Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStop"); Pylon.StreamGrabberCancelGrab(hGrabber); do { isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult); } while (isReady); foreach (KeyValuePair <PYLON_STREAMBUFFER_HANDLE, PylonBuffer <Byte> > pair in buffers) { Pylon.StreamGrabberDeregisterBuffer(hGrabber, pair.Key); pair.Value.Dispose(); } buffers = null; Pylon.StreamGrabberFinishGrab(hGrabber); Pylon.StreamGrabberClose(hGrabber); Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); Console.ReadLine(); Pylon.Terminate(); } }
public void OneFrame() { try { lock (dev) { Pylon.DeviceOpen(dev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream); PylonGrabResult_t grabResult; PylonBuffer <Byte> imgBuf = null; if (!Pylon.DeviceGrabSingleFrame(dev, 0, ref imgBuf, out grabResult, 500)) { Console.WriteLine("timeout"); } if (grabResult.Status == EPylonGrabStatus.Grabbed) { OnGrabAndDispose(GrabResultToImage(grabResult, imgBuf)); } else if (grabResult.Status == EPylonGrabStatus.Failed) { Console.Error.WriteLine("Frame wasn't grabbed successfully. Error code = {1}", grabResult.ErrorCode); } Pylon.DeviceClose(dev); } } catch { Console.WriteLine(GenApi.GetLastErrorDetail()); } }
/* Close the device */ public void Close() { /* Notify that ImageProvider is about to close the device to give other objects the chance to do clean up operations. */ OnDeviceClosingEvent(); /* Try to close everything even if exceptions occur. Keep the last exception to throw when it is done. */ Exception lastException = null; /* Reset the removed flag. */ m_removed = false; if( m_hGrabber.IsValid ) { /* Try to close the stream grabber. */ try { Pylon.StreamGrabberClose( m_hGrabber ); } catch( Exception e ) { lastException = e; UpdateLastError(); } } if( m_hDevice.IsValid ) { /* Try to deregister the removal callback. */ try { if( m_hRemovalCallback.IsValid ) { Pylon.DeviceDeregisterRemovalCallback( m_hDevice, m_hRemovalCallback ); } } catch( Exception e ) { lastException = e; UpdateLastError(); } /* Try to close the device. */ try { /* ... Close and release the pylon device. */ if( Pylon.DeviceIsOpen( m_hDevice ) ) { Pylon.DeviceClose( m_hDevice ); } } catch( Exception e ) { lastException = e; UpdateLastError(); } /* Try to destroy the device. */ try { Pylon.DestroyDevice( m_hDevice ); } catch( Exception e ) { lastException = e; UpdateLastError(); } } m_hGrabber.SetInvalid(); m_hRemovalCallback.SetInvalid(); m_hDevice.SetInvalid(); /* Notify that ImageProvider is now closed.*/ OnDeviceClosedEvent(); /* If an exception occurred throw it. */ if( lastException != null ) { throw lastException; } }
public void DisConnect() { if (clearMethod != null) { clearMethod(); } Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); }
/// <summary> /// 關閉裝置 /// </summary> public void DeviceClose() { /* 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. */ if (Pylon.DeviceIsOpen(_pylonDevHandle)) { Pylon.DeviceClose(_pylonDevHandle); } }
public void PylonC_Close() { /* ... 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(); }
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); } }
static void mmMain(string[] args) { PYLON_DEVICE_HANDLE hDev = new PYLON_DEVICE_HANDLE(); /* Handle for the pylon device. */ try { uint numDevices; /* Number of devices available. */ #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 * Pylon.EnumerateDevices() 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; isReadable = Pylon.DeviceFeatureIsReadable(hDev, "DeviceModelName"); if (isReadable) { string name = Pylon.DeviceFeatureToString(hDev, "DeviceModelName"); Console.WriteLine("Using camera {0}", name); } } /* Demonstrate how to check the accessibility of a feature. */ demonstrateAccessibilityCheck(hDev); Console.WriteLine(""); /* Demonstrate how to handle integer camera parameters. */ demonstrateIntFeature(hDev); Console.WriteLine(""); /* Demonstrate how to handle floating point camera parameters. */ demonstrateFloatFeature(hDev); Console.WriteLine(""); /* Demonstrate how to handle boolean camera parameters. */ demonstrateBooleanFeature(hDev); Console.WriteLine(""); /* Each feature can be read as a string and also set as a string. */ demonstrateFromStringToString(hDev); Console.WriteLine(""); /* Demonstrate how to handle enumeration camera parameters. */ demonstrateEnumFeature(hDev); Console.WriteLine(""); /* Demonstrate how to iterate enumeration entries. */ demonstrateEnumIteration(hDev); Console.WriteLine(""); /* Demonstrate how to execute actions. */ demonstrateCommandFeature(hDev); Console.WriteLine(""); /* Display category nodes. */ demonstrateCategory(hDev); /* Clean up. Close and release the pylon device. */ Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); /* Shut down the pylon runtime system. Don't call any pylon method after * calling Pylon.Terminate(). */ Pylon.Terminate(); Console.Error.WriteLine("\nPress enter to exit."); Console.ReadLine(); } catch (Exception e) { /* Retrieve the error message. */ string msg = GenApi.GetLastErrorMessage() + "" + GenApi.GetLastErrorDetail(); Console.Error.WriteLine("Exception caught:"); Console.Error.WriteLine(e.Message); if (msg.Length > 0) { 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); } }
/// <summary> /// Calibrate intrinsic parameters. /// </summary> public void Calibrate(int w = 1200, int h = 800, bool color = false, bool setFrameRate = false, int frameRate = 2) { if (!isCalibrated) { PYLON_DEVICE_HANDLE device = null; try { // Must Enumerate all camera devices before creating a device. uint numDevices = Pylon.EnumerateDevices(); if (numDevices > 0) { // Get a handle for the first device found. device = Pylon.CreateDeviceByIndex(0); // Open device to configuring parameters Pylon.DeviceOpen(device, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream); // Check to see if the Mono8 pixel format can be set if (!Pylon.DeviceFeatureIsAvailable(device, "EnumEntry_PixelFormat_Mono8")) { throw new Exception("Invalid camera pixel format."); } string width = "1980"; string height = "1080"; int xOffset = (int.Parse(width) - w) / 2; int yOffset = (int.Parse(height) - h) / 2; this.SetConfig(device, "Width", w); this.SetConfig(device, "Height", h); this.SetConfig(device, "XOffset", xOffset); this.SetConfig(device, "YOffset", yOffset); this.SetConfig(device, "AcquisitionFrameRateEnable", "1"); // string fps = this.GetConfig(device, "ResultingFrameRateAbs"); if (setFrameRate) { this.SetConfig(device, "AcquisitionFrameRateAbs", frameRate.ToString()); } if (!color) { this.SetConfig(device, "PixelFormat", "Mono8"); } } } catch (Exception ex) { throw ex; } finally { try { // Clean up. Close and release the pylon device. if (Pylon.DeviceIsOpen(device)) { Pylon.DeviceClose(device); } Pylon.DestroyDevice(device); } catch (Exception ex) { throw ex; } } isCalibrated = true; } }
//停止采集图像 public override void StopCameraSoftTrigger() { Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); }
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()); } }
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); } }
/// <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); } }
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); } }
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. */ const int numGrabs = 10; /* Number of images to grab. */ PylonBuffer <Byte> imgBuf = null; /* Buffer used for grabbing. */ bool isAvail; int i; #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); /* 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"); } /* 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); } /* Grab some images in a loop. */ for (i = 0; i < numGrabs; ++i) { Byte min, max; PylonGrabResult_t grabResult; /* Grab one single frame from stream channel 0. The * camera is set to "single frame" acquisition mode. * Wait up to 500 ms for the image to be grabbed. * If imgBuf is null a buffer is automatically created with the right size.*/ if (!Pylon.DeviceGrabSingleFrame(hDev, 0, ref imgBuf, out grabResult, 500)) { /* Timeout occurred. */ Console.WriteLine("Frame {0}: timeout.", i + 1); } /* Check to see if the image was grabbed successfully. */ if (grabResult.Status == EPylonGrabStatus.Grabbed) { /* Success. Perform image processing. */ getMinMax(imgBuf.Array, grabResult.SizeX, grabResult.SizeY, out min, out max); Console.WriteLine("Grabbed frame {0}. Min. gray value = {1}, Max. gray value = {2}", i + 1, min, max); /* Display image */ Pylon.ImageWindowDisplayImage <Byte>(0, imgBuf, grabResult); } else if (grabResult.Status == EPylonGrabStatus.Failed) { Console.Error.WriteLine("Frame {0} wasn't grabbed successfully. Error code = {1}", i + 1, grabResult.ErrorCode); } } /* Release the buffer. */ imgBuf.Dispose(); /* Clean up. Close and release the pylon device. */ Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); /* Free memory for grabbing. */ imgBuf = null; 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(); } 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); } }
private void DestroyDeviceHandle() { Pylon.DeviceClose(DeviceHandle); Pylon.DestroyDevice(DeviceHandle); }
static void Main(string[] args) { for (uint i = 0; i < args.Length; i++) { switch (args[i]) { case par_cameraSerialNumber: arg_cameraSerialNumber = args[i + 1]; i++; break; case par_pathToFile: arg_pathToFile = args[i + 1]; i++; break; case par_imageFormat: arg_imageFormat = args[i + 1]; i++; break; case par_packageSize: arg_packageSize = args[i + 1]; i++; break; case par_interPackageDelay: arg_interPackageDelay = args[i + 1]; i++; break; case par_attemptsToGrab: arg_attemptsToGrab = args[i + 1]; i++; break; case par_exposureTime: arg_exposureTime = args[i + 1]; i++; break; default: break; } } //arg_exposureTime = "35000"; bool error = false; if (arg_pathToFile.Length == 0) { Console.WriteLine("Path to file is empty"); error = true; } if (!(arg_imageFormat.Equals("BMP") || !arg_imageFormat.Equals("PNG") || !arg_imageFormat.Equals("JPG") || !arg_imageFormat.Equals("RAW") || !arg_imageFormat.Equals("TIFF"))) { Console.WriteLine("File format should be [BMP|PNG|JPG|RAW|TIFF]"); error = true; } if (arg_cameraSerialNumber.Length == 0) { Console.WriteLine("Camera serial number is empty"); error = true; } int exposureTime = 0; try { exposureTime = Int32.Parse(arg_exposureTime); } catch (Exception e) { Console.WriteLine("Wrong exposure time value"); error = true; } int interPackageDelay = 0; try { interPackageDelay = Int32.Parse(arg_interPackageDelay); } catch (Exception e) { Console.WriteLine("Wrong interPackageDelay value"); error = true; } int attemptsToGrap = 0; try { attemptsToGrap = Int16.Parse(arg_attemptsToGrab); }catch (Exception e) { Console.WriteLine("Wrong attempts to grab value"); error = true; } //sodapef if (error) { Console.WriteLine("Parameters usage:"); Console.WriteLine("-s Camera serial number"); Console.WriteLine("-o Path to file"); Console.WriteLine("-d Inter package delay in ticks (default 1000)"); Console.WriteLine("-a Attempts tp grab image (default 1)"); Console.WriteLine("-p Package size (default 1500)"); Console.WriteLine("-e Exposure time (default 35000)"); Console.WriteLine("-f Image format [BMP|PNG|JPG|RAW|TIFF]"); return; } PYLON_DEVICE_HANDLE hDev = new PYLON_DEVICE_HANDLE(); /* Handle for the pylon device. */ try { uint numDevices; /* Number of available devices. */ const int numGrabs = 1; /* Number of images to grab. */ PylonBuffer <Byte> imgBuf = null; /* Buffer used for grabbing. */ bool isAvail; Pylon.Initialize(); numDevices = Pylon.EnumerateDevices(); if (0 == numDevices) { Console.WriteLine("Error: No devices found"); return; } bool deviceFound = false; uint deviceNum = 0; for (uint di = 0; di < numDevices; di++) { PYLON_DEVICE_INFO_HANDLE hDi = Pylon.GetDeviceInfoHandle((uint)di); string serial = Pylon.DeviceInfoGetPropertyValueByName(hDi, Pylon.cPylonDeviceInfoSerialNumberKey); deviceNum = di; if (serial.Equals(arg_cameraSerialNumber)) { deviceFound = true; break; } } if (!deviceFound) { Console.WriteLine("Error: No devices found by serial number"); return; } hDev = Pylon.CreateDeviceByIndex(deviceNum); Pylon.DeviceOpen(hDev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream | Pylon.cPylonAccessModeExclusive); isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8"); if (!isAvail) { Console.WriteLine("Error: Device doesn't support the Mono8 pixel format"); return; } Pylon.DeviceFeatureFromString(hDev, "PixelFormat", "Mono8"); isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_AcquisitionStart"); if (isAvail) { Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "AcquisitionStart"); Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off"); } isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameBurstStart"); if (isAvail) { Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameBurstStart"); Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off"); } isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameStart"); if (isAvail) { Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameStart"); Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off"); } isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize"); if (isAvail) { int packageSize = 1500; try{ packageSize = Int32.Parse(arg_packageSize); } catch (Exception e) { } Pylon.DeviceSetIntegerFeature(hDev, "GevSCPSPacketSize", packageSize); } isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPD"); if (isAvail) { Pylon.DeviceSetIntegerFeature(hDev, "GevSCPD", interPackageDelay); } Pylon.DeviceFeatureFromString(hDev, "ExposureAuto", "Off"); /* * isAvail = Pylon.DeviceFeatureIsWritable(hDev, "ExposureTimeRaw"); * if (isAvail) * { * try * { * Pylon.DeviceSetFloatFeature(hDev, "ExposureTimeRaw", exposureTime); * } * catch (Exception e) * { * Console.WriteLine("Some error 1"); * } * }*/ isAvail = Pylon.DeviceFeatureIsWritable(hDev, "ExposureTimeAbs"); if (isAvail) { Pylon.DeviceSetFloatFeature(hDev, "ExposureTimeAbs", (long)exposureTime); /* * try{ * Pylon.DeviceSetFloatFeature(hDev, "ExposureTimeAbs", (long)exposureTime); * }catch (Exception e) { * //Console.WriteLine("Some error 2"); * } */ } Byte min, max; PylonGrabResult_t grabResult; for (int attempt = 0; attempt < attemptsToGrap; attempt++) { if (!Pylon.DeviceGrabSingleFrame(hDev, 0, ref imgBuf, out grabResult, 5000)) { /* Timeout occurred. */ //Console.WriteLine("Frame {0}: timeout.", i + 1); Console.WriteLine("Error: timeout"); } /* Check to see if the image was grabbed successfully. */ if (grabResult.Status == EPylonGrabStatus.Grabbed) { /* Success. Perform image processing. */ getMinMax(imgBuf.Array, grabResult.SizeX, grabResult.SizeY, out min, out max); //Console.WriteLine("Grabbed frame {0}. Min. gray value = {1}, Max. gray value = {2}", i + 1, min, max); Console.WriteLine("Frame grabbed success"); /* Display image */ //Pylon.ImagePersistenceSave<Byte>(EPylonImageFileFormat.ImageFileFormat_Png, "C:\\Users\\v.yakubov\\grabber\\test.png", imgBuf, grabResult.PixelType, (uint)grabResult.SizeX, (uint)grabResult.SizeY, 0, EPylonImageOrientation.ImageOrientation_TopDown); if (arg_imageFormat.Equals("PNG")) { Pylon.ImagePersistenceSave <Byte>(EPylonImageFileFormat.ImageFileFormat_Png, arg_pathToFile, imgBuf, grabResult.PixelType, (uint)grabResult.SizeX, (uint)grabResult.SizeY, 0, EPylonImageOrientation.ImageOrientation_TopDown); } else if (arg_imageFormat.Equals("JPG")) { Pylon.ImagePersistenceSave <Byte>(EPylonImageFileFormat.ImageFileFormat_Jpeg, arg_pathToFile, imgBuf, grabResult.PixelType, (uint)grabResult.SizeX, (uint)grabResult.SizeY, 0, EPylonImageOrientation.ImageOrientation_TopDown); } else if (arg_imageFormat.Equals("RAW")) { Pylon.ImagePersistenceSave <Byte>(EPylonImageFileFormat.ImageFileFormat_Raw, arg_pathToFile, imgBuf, grabResult.PixelType, (uint)grabResult.SizeX, (uint)grabResult.SizeY, 0, EPylonImageOrientation.ImageOrientation_TopDown); } else if (arg_imageFormat.Equals("TIFF")) { Pylon.ImagePersistenceSave <Byte>(EPylonImageFileFormat.ImageFileFormat_Tiff, arg_pathToFile, imgBuf, grabResult.PixelType, (uint)grabResult.SizeX, (uint)grabResult.SizeY, 0, EPylonImageOrientation.ImageOrientation_TopDown); } else if (arg_imageFormat.Equals("BMP")) { Pylon.ImagePersistenceSave <Byte>(EPylonImageFileFormat.ImageFileFormat_Bmp, arg_pathToFile, imgBuf, grabResult.PixelType, (uint)grabResult.SizeX, (uint)grabResult.SizeY, 0, EPylonImageOrientation.ImageOrientation_TopDown); } else { Pylon.ImagePersistenceSave <Byte>(EPylonImageFileFormat.ImageFileFormat_Bmp, arg_pathToFile, imgBuf, grabResult.PixelType, (uint)grabResult.SizeX, (uint)grabResult.SizeY, 0, EPylonImageOrientation.ImageOrientation_TopDown); } break; } else if (grabResult.Status == EPylonGrabStatus.Failed) { //Console.Error.WriteLine("Frame {0} wasn't grabbed successfully. Error code = {1}", i + 1, grabResult.ErrorCode); Console.WriteLine("Error: failed"); } } imgBuf.Dispose(); Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); imgBuf = null; Pylon.Terminate(); } catch (Exception e) { try { if (hDev.IsValid) { if (Pylon.DeviceIsOpen(hDev)) { Pylon.DeviceClose(hDev); } Pylon.DestroyDevice(hDev); } } catch (Exception) {} Pylon.Terminate(); /* Releases all pylon resources. */ Environment.Exit(1); } }
static int callbackCounter = 0; /* Will be incremented by the callback function. */ 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_DEVICECALLBACK_HANDLE hCb; /* Required for deregistering the callback. */ int loopCount; /* Counter. */ #if DEBUG bool isGigECamera; /* 1 if the device is a GigE device. */ #endif DeviceCallbackHandler callbackHandler = new DeviceCallbackHandler(); /* Handles callbacks from a device. */ /* 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); /* 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); } } /* Register the callback function. */ callbackHandler.CallbackEvent += new DeviceCallbackHandler.DeviceCallback(removalCallbackFunction); hCb = Pylon.DeviceRegisterRemovalCallback(hDev, callbackHandler); #if DEBUG /* For GigE cameras, the application periodically sends heartbeat signals to the camera to keep the * connection to the camera alive. If the camera doesn't receive heartbeat signals within the time * period specified by the heartbeat timeout counter, the camera resets the connection. * When the application is stopped by the debugger, the application cannot create the heartbeat signals. * For that reason, the pylon runtime extends the heartbeat timeout in debug mode to 5 minutes to allow * debugging. For GigE cameras, we will set the heartbeat timeout to a shorter period before testing the * callbacks. * The heartbeat mechanism is also used for detection of device removal. When the pylon runtime doesn't * receive an acknowledge for the heartbeat signal, it is assumed that the device has been removed. A * removal callback will be fired in that case. * By decreasing the heartbeat timeout in debug mode for GigE cameras, the surprise removal will be noticed sooner than set by the pylon runtime. */ { /* Find out if we are using a GigE camera. */ PYLON_DEVICE_INFO_HANDLE hDi = Pylon.DeviceGetDeviceInfoHandle(hDev); string deviceClass = Pylon.DeviceInfoGetPropertyValueByName(hDi, Pylon.cPylonDeviceInfoDeviceClassKey); isGigECamera = deviceClass == "BaslerGigE"; /* Adjust the heartbeat timeout. */ if (isGigECamera) { setHeartbeatTimeout(hDev, 1000); /* 1000 ms */ } } #endif /* Ask the user to disconnect a device. */ loopCount = 20 * 4; Console.WriteLine("Please disconnect the device (timeout {0} s) ", loopCount / 4); /* Wait until the removal has been noticed and the callback function has been fired. */ do { /* Print a . every few seconds to tell the user we're waiting for the callback. */ if (--loopCount % 4 == 0) { Console.Write("."); } System.Threading.Thread.Sleep(250); }while (callbackCounter < 1 && loopCount >= 0); /* Check loopCount so we won't wait forever. */ if (callbackCounter < 1) { Console.WriteLine("\nTimeout expired. Device hasn't been removed."); } /* Clean up. */ /* ... Deregister the removal callback. */ Pylon.DeviceDeregisterRemovalCallback(hDev, hCb); /* ....Close and release the pylon device. */ Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); /* Shut down the pylon runtime system. Don't call any pylon method after * calling Pylon.Terminate(). */ 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) { /* ... 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); } }
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); } }
/// <summary> /// Check if device is ready /// </summary> /// <returns>true if device is ready</returns> /// <param name="isUpdateListDevice">true if update list of devices</param> private static bool IsReadyDevice(bool isUpdateListDevice) { bool isReady = false; try { // Update list of cameras if (isUpdateListDevice || list == null) { list = DeviceEnumerator.EnumerateDevices(); } if (list.Count == 0) { return(false); } PYLON_DEVICE_HANDLE device = null; BaslerParams baslerParams = new BaslerParams(); for (int i = 0; i < list.Count; i++) { // Check ip address try { device = Pylon.CreateDeviceByIndex((uint)i); string ipAddress = Pylon.DeviceInfoGetPropertyValueByName(Pylon.DeviceGetDeviceInfoHandle(device), Pylon.cPylonDeviceInfoIpAddressKey); if (string.Compare(baslerParams.IpAddress, ipAddress) == 0) { cameraIndex = i; return(true); } } catch (Exception ex) { isReady = false; } finally { try { // Clean up. Close and release the pylon device. if (Pylon.DeviceIsOpen(device)) { Pylon.DeviceClose(device); } Pylon.DestroyDevice(device); } catch (Exception ex) { isReady = false; } } } } catch (Exception ex) { isReady = false; } return(isReady); }