Guest User

Untitled

a guest
Jan 16th, 2018
447
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.69 KB | None | 0 0
  1. /*
  2. This sample illustrates how to grab images and process images asynchronously, i.e.,
  3. while the application is processing a buffer, the acquistion of the next buffer is done
  4. in parallel.
  5. The sample uses a pool of buffers that are passed to a stream grabber to be filled with
  6. image data. Once a buffer is filled and ready for processing, the buffer is retrieved from
  7. the stream grabber, processed, and passed back to the stream grabber to be filled again.
  8. Buffers retrieved from the stream grabber are not overwritten in the background as long as
  9. they are not passed back to the stream grabber.
  10. */
  11.  
  12. using System;
  13. using System.Collections.Generic;
  14. using PylonC.NET;
  15.  
  16. namespace OverlappedGrab
  17. {
  18. class OverlappedGrab
  19. {
  20. const uint NUM_GRABS = 20; /* Number of images to grab. */
  21. const uint NUM_BUFFERS = 5; /* Number of buffers used for grabbing. */
  22.  
  23. static void Main(string[] args)
  24. {
  25. PYLON_DEVICE_HANDLE hDev = new PYLON_DEVICE_HANDLE(); /* Handle for the pylon device. */
  26. try
  27. {
  28. uint numDevices; /* Number of available devices. */
  29. PYLON_STREAMGRABBER_HANDLE hGrabber; /* Handle for the pylon stream grabber. */
  30. PYLON_WAITOBJECT_HANDLE hWait; /* Handle used for waiting for a grab to be finished. */
  31. uint payloadSize; /* Size of an image frame in bytes. */
  32. Dictionary<PYLON_STREAMBUFFER_HANDLE, PylonBuffer<Byte>> buffers; /* Holds handles and buffers used for grabbing. */
  33. PylonGrabResult_t grabResult; /* Stores the result of a grab operation. */
  34. int nGrabs; /* Counts the number of buffers grabbed. */
  35. uint nStreams; /* The number of streams provides by the device. */
  36. bool isAvail; /* Used for checking feature availability. */
  37. bool isReady; /* Used as an output parameter. */
  38. int i; /* Counter. */
  39.  
  40. #if DEBUG
  41. /* This is a special debug setting needed only for GigE cameras.
  42. See 'Building Applications with pylon' in the programmer's guide. */
  43. Environment.SetEnvironmentVariable("PYLON_GIGE_HEARTBEAT", "300000" /*ms*/);
  44. #endif
  45.  
  46. /* Before using any pylon methods, the pylon runtime must be initialized. */
  47. Pylon.Initialize();
  48.  
  49. /* Enumerate all camera devices. You must call
  50. PylonEnumerateDevices() before creating a device. */
  51. numDevices = Pylon.EnumerateDevices();
  52.  
  53. if (0 == numDevices)
  54. {
  55. throw new Exception("No devices found.");
  56. }
  57.  
  58. /* Get a handle for the first device found. */
  59. hDev = Pylon.CreateDeviceByIndex(0);
  60.  
  61. /* Before using the device, it must be opened. Open it for configuring
  62. parameters and for grabbing images. */
  63. Pylon.DeviceOpen(hDev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);
  64.  
  65. /* Print out the name of the camera we are using. */
  66. {
  67. bool isReadable = Pylon.DeviceFeatureIsReadable(hDev, "DeviceModelName");
  68. if (isReadable)
  69. {
  70. string name = Pylon.DeviceFeatureToString(hDev, "DeviceModelName");
  71. Console.WriteLine("Using camera {0}.", name);
  72. }
  73. }
  74.  
  75. /* Set the pixel format to Mono8, where gray values will be output as 8 bit values for each pixel. */
  76. /* ... Check first to see if the device supports the Mono8 format. */
  77. isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8");
  78.  
  79. if (!isAvail)
  80. {
  81. /* Feature is not available. */
  82. throw new Exception("Device doesn't support the Mono8 pixel format.");
  83. }
  84. /* ... Set the pixel format to Mono8. */
  85. Pylon.DeviceFeatureFromString(hDev, "PixelFormat", "Mono8");
  86.  
  87. /* Disable acquisition start trigger if available */
  88. isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_AcquisitionStart");
  89. if (isAvail)
  90. {
  91. Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "AcquisitionStart");
  92. Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
  93. }
  94.  
  95. /* Disable frame burst start trigger if available */
  96. isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameBurstStart");
  97. if (isAvail)
  98. {
  99. Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameBurstStart");
  100. Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
  101. }
  102.  
  103. /* Disable frame start trigger if available */
  104. isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_TriggerSelector_FrameStart");
  105. if (isAvail)
  106. {
  107. Pylon.DeviceFeatureFromString(hDev, "TriggerSelector", "FrameStart");
  108. Pylon.DeviceFeatureFromString(hDev, "TriggerMode", "Off");
  109. }
  110.  
  111. /* We will use the Continuous frame mode, i.e., the camera delivers
  112. images continuously. */
  113. Pylon.DeviceFeatureFromString(hDev, "AcquisitionMode", "Continuous");
  114.  
  115. /* For GigE cameras, we recommend increasing the packet size for better
  116. performance. When the network adapter supports jumbo frames, set the packet
  117. size to a value > 1500, e.g., to 8192. In this sample, we only set the packet size
  118. to 1500. */
  119. /* ... Check first to see if the GigE camera packet size parameter is supported and if it is writable. */
  120. isAvail = Pylon.DeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");
  121. if (isAvail)
  122. {
  123. /* ... The device supports the packet size feature. Set a value. */
  124. Pylon.DeviceSetIntegerFeature(hDev, "GevSCPSPacketSize", 1500);
  125. }
  126.  
  127. /* Determine the required size of the grab buffer. */
  128. payloadSize = checked((uint)Pylon.DeviceGetIntegerFeature(hDev, "PayloadSize"));
  129.  
  130. /* Image grabbing is done using a stream grabber.
  131. A device may be able to provide different streams. A separate stream grabber must
  132. be used for each stream. In this sample, we create a stream grabber for the default
  133. stream, i.e., the first stream ( index == 0 ).
  134. */
  135.  
  136. /* Get the number of streams supported by the device and the transport layer. */
  137. nStreams = Pylon.DeviceGetNumStreamGrabberChannels(hDev);
  138.  
  139. if (nStreams < 1)
  140. {
  141. throw new Exception("The transport layer doesn't support image streams.");
  142. }
  143.  
  144. /* Create and open a stream grabber for the first channel. */
  145. hGrabber = Pylon.DeviceGetStreamGrabber(hDev, 0);
  146. Pylon.StreamGrabberOpen(hGrabber);
  147.  
  148. /* Get a handle for the stream grabber's wait object. The wait object
  149. allows waiting for buffers to be filled with grabbed data. */
  150. hWait = Pylon.StreamGrabberGetWaitObject(hGrabber);
  151.  
  152. /* We must tell the stream grabber the number and size of the buffers
  153. we are using. */
  154. /* .. We will not use more than NUM_BUFFERS for grabbing. */
  155. Pylon.StreamGrabberSetMaxNumBuffer(hGrabber, NUM_BUFFERS);
  156.  
  157. /* .. We will not use buffers bigger than payloadSize bytes. */
  158. Pylon.StreamGrabberSetMaxBufferSize(hGrabber, payloadSize);
  159.  
  160. /* Allocate the resources required for grabbing. After this, critical parameters
  161. that impact the payload size must not be changed until FinishGrab() is called. */
  162. Pylon.StreamGrabberPrepareGrab(hGrabber);
  163.  
  164. /* Before using the buffers for grabbing, they must be registered at
  165. the stream grabber. For each registered buffer, a buffer handle
  166. is returned. After registering, these handles are used instead of the
  167. buffer objects pointers. The buffer objects are held in a dictionary,
  168. that provides access to the buffer using a handle as key.
  169. */
  170. buffers = new Dictionary<PYLON_STREAMBUFFER_HANDLE, PylonBuffer<Byte>>();
  171. for (i = 0; i < NUM_BUFFERS; ++i)
  172. {
  173. PylonBuffer<Byte> buffer = new PylonBuffer<byte>(payloadSize, true);
  174. PYLON_STREAMBUFFER_HANDLE handle = Pylon.StreamGrabberRegisterBuffer(hGrabber, ref buffer);
  175. buffers.Add(handle, buffer);
  176. }
  177.  
  178. /* Feed the buffers into the stream grabber's input queue. For each buffer, the API
  179. allows passing in an integer as additional context information. This integer
  180. will be returned unchanged when the grab is finished. In our example, we use the index of the
  181. buffer as context information. */
  182. i = 0;
  183. foreach (KeyValuePair<PYLON_STREAMBUFFER_HANDLE, PylonBuffer<Byte>> pair in buffers)
  184. {
  185. Pylon.StreamGrabberQueueBuffer(hGrabber, pair.Key, i++);
  186. }
  187.  
  188. /* The stream grabber is now prepared. As soon the camera starts acquiring images,
  189. the image data will be grabbed into the provided buffers. */
  190.  
  191. /* Let the camera acquire images. */
  192. Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStart");
  193.  
  194. /* Grab NUM_GRABS images */
  195. nGrabs = 0; /* Counts the number of grabbed images. */
  196. while (nGrabs < NUM_GRABS)
  197. {
  198. int bufferIndex; /* Index of the buffer. */
  199. Byte min, max;
  200. /* Wait for the next buffer to be filled. Wait up to 1000 ms. */
  201. isReady = Pylon.WaitObjectWait(hWait, 1000);
  202.  
  203. if (!isReady)
  204. {
  205. /* Timeout occurred. */
  206. throw new Exception("Grab timeout occurred.");
  207. }
  208.  
  209. /* Since the wait operation was successful, the result of at least one grab
  210. operation is available. Retrieve it. */
  211. isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);
  212.  
  213. if (!isReady)
  214. {
  215. /* Oops. No grab result available? We should never have reached this point.
  216. Since the wait operation above returned without a timeout, a grab result
  217. should be available. */
  218. throw new Exception("Failed to retrieve a grab result");
  219. }
  220.  
  221. nGrabs++;
  222.  
  223. /* Get the buffer index from the context information. */
  224. bufferIndex = (int)grabResult.Context;
  225.  
  226. /* Check to see if the image was grabbed successfully. */
  227. if (grabResult.Status == EPylonGrabStatus.Grabbed)
  228. {
  229. /* Success. Perform image processing. Since we passed more than one buffer
  230. to the stream grabber, the remaining buffers are filled in the background while
  231. we do the image processing. The processed buffer won't be touched by
  232. the stream grabber until we pass it back to the stream grabber. */
  233.  
  234. PylonBuffer<Byte> buffer; /* Reference to the buffer attached to the grab result. */
  235.  
  236. /* Get the buffer from the dictionary. Since we also got the buffer index,
  237. we could alternatively use an array, e.g. buffers[bufferIndex]. */
  238. if (!buffers.TryGetValue(grabResult.hBuffer, out buffer))
  239. {
  240. /* Oops. No buffer available? We should never have reached this point. Since all buffers are
  241. in the dictionary. */
  242. throw new Exception("Failed to find the buffer associated with the handle returned in grab result.");
  243. }
  244.  
  245. /* Perform processing. */
  246. getMinMax(buffer.Array, grabResult.SizeX, grabResult.SizeY, out min, out max);
  247. Console.WriteLine("Grabbed frame {0} into buffer {1}. Min. gray value = {2}, Max. gray value = {3}",
  248. nGrabs, bufferIndex, min, max);
  249.  
  250. /* Display image */
  251. Pylon.ImageWindowDisplayImage<Byte>(0, buffer, grabResult);
  252. }
  253. else if (grabResult.Status == EPylonGrabStatus.Failed)
  254. {
  255. Console.Error.WriteLine("Frame {0} wasn't grabbed successfully. Error code = {1}",
  256. nGrabs, grabResult.ErrorCode);
  257. }
  258.  
  259. /* Once finished with the processing, requeue the buffer to be filled again. */
  260. Pylon.StreamGrabberQueueBuffer(hGrabber, grabResult.hBuffer, bufferIndex);
  261. }
  262.  
  263. /* Clean up. */
  264.  
  265. /* ... Stop the camera. */
  266. Pylon.DeviceExecuteCommandFeature(hDev, "AcquisitionStop");
  267.  
  268. /* ... We must issue a cancel call to ensure that all pending buffers are put into the
  269. stream grabber's output queue. */
  270. Pylon.StreamGrabberCancelGrab(hGrabber);
  271.  
  272. /* ... The buffers can now be retrieved from the stream grabber. */
  273. do
  274. {
  275. isReady = Pylon.StreamGrabberRetrieveResult(hGrabber, out grabResult);
  276.  
  277. } while (isReady);
  278.  
  279. /* ... When all buffers are retrieved from the stream grabber, they can be deregistered.
  280. After deregistering the buffers, it is safe to free the memory. */
  281.  
  282. foreach (KeyValuePair<PYLON_STREAMBUFFER_HANDLE, PylonBuffer<Byte>> pair in buffers)
  283. {
  284. Pylon.StreamGrabberDeregisterBuffer(hGrabber, pair.Key);
  285. pair.Value.Dispose();
  286. }
  287. buffers = null;
  288.  
  289. /* ... Release grabbing related resources. */
  290. Pylon.StreamGrabberFinishGrab(hGrabber);
  291.  
  292. /* After calling PylonStreamGrabberFinishGrab(), parameters that impact the payload size (e.g.,
  293. the AOI width and height parameters) are unlocked and can be modified again. */
  294.  
  295. /* ... Close the stream grabber. */
  296. Pylon.StreamGrabberClose(hGrabber);
  297.  
  298. /* ... Close and release the pylon device. The stream grabber becomes invalid
  299. after closing the pylon device. Don't call stream grabber related methods after
  300. closing or releasing the device. */
  301. Pylon.DeviceClose(hDev);
  302. Pylon.DestroyDevice(hDev);
  303.  
  304. Console.Error.WriteLine("\nPress enter to exit.");
  305. Console.ReadLine();
  306.  
  307. /* ... Shut down the pylon runtime system. Don't call any pylon method after
  308. calling Pylon.Terminate(). */
  309. Pylon.Terminate();
  310. }
  311. catch (Exception e)
  312. {
  313. /* Retrieve the error message. */
  314. string msg = GenApi.GetLastErrorMessage() + "\n" + GenApi.GetLastErrorDetail();
  315. Console.Error.WriteLine("Exception caught:");
  316. Console.Error.WriteLine(e.Message);
  317. if (msg != "\n")
  318. {
  319. Console.Error.WriteLine("Last error message:");
  320. Console.Error.WriteLine(msg);
  321. }
  322.  
  323. try
  324. {
  325. if (hDev.IsValid)
  326. {
  327. /* ... Close and release the pylon device. */
  328. if (Pylon.DeviceIsOpen(hDev))
  329. {
  330. Pylon.DeviceClose(hDev);
  331. }
  332. Pylon.DestroyDevice(hDev);
  333. }
  334. }
  335. catch (Exception)
  336. {
  337. /*No further handling here.*/
  338. }
  339.  
  340. Pylon.Terminate(); /* Releases all pylon resources. */
  341.  
  342. Console.Error.WriteLine("\nPress enter to exit.");
  343. Console.ReadLine();
  344.  
  345. Environment.Exit(1);
  346. }
  347. }
  348.  
  349. /* Simple "image processing" function returning the minimum and maximum gray
  350. value of an 8 bit gray value image. */
  351. static void getMinMax(Byte[] imageBuffer, long width, long height, out Byte min, out Byte max)
  352. {
  353. min = 255; max = 0;
  354. long imageDataSize = width * height;
  355.  
  356. for (long i = 0; i < imageDataSize; ++i)
  357. {
  358. Byte val = imageBuffer[i];
  359. if (val > max)
  360. max = val;
  361. if (val < min)
  362. min = val;
  363. }
  364. }
  365. }
  366. }
Add Comment
Please, Sign In to add comment