• Basler相机Sdk采图的演示例程(C#)


    这个话题的起因是追求极速的拍图速度。

    机器ppm不达标的情况下,往往对视觉的处理速度有变态的要求,为了争取处理时间最短,几十毫秒也要争取。

    halcon的接口是通用接口,其速度是比不上相机厂商自己相机配套的SDK的采图速度的。

    下面程序运行后,500w的CCD拍图的时间(不算显示时间)达到惊人的32毫秒,如果用halcon接口,最快的我见过是180毫秒。

    1. using Basler.Pylon;
    2. using HalconDotNet;
    3. using System;
    4. using System.Collections.Generic;
    5. using System.ComponentModel;
    6. using System.Data;
    7. using System.Diagnostics;
    8. using System.Drawing;
    9. using System.Linq;
    10. using System.Runtime.InteropServices;
    11. using System.Text;
    12. using System.Threading;
    13. using System.Threading.Tasks;
    14. using System.Windows.Forms;
    15. namespace WindowsFormsApplication1
    16. {
    17. public partial class Form1 : Form
    18. {
    19. private PixelDataConverter converter = new PixelDataConverter();
    20. ///
    21. /// 相机ID
    22. ///
    23. public string UserID { get { return userID; } }
    24. private string userID = string.Empty;
    25. private Stopwatch sw = new Stopwatch();
    26. private bool isOkGrab = false;
    27. private IntPtr latestFrameAddress = IntPtr.Zero;
    28. public HObject Image { get { return image; } }
    29. private HObject image = null;
    30. static Version Sfnc2_0_0 = new Version(2, 0, 0);
    31. private Camera camera = null;
    32. HTuple handle;
    33. public Form1()
    34. {
    35. InitializeComponent();
    36. }
    37. private void button1_Click(object sender, EventArgs e)
    38. {
    39. var f1=BaslerCameraInit();
    40. if(f1)
    41. {
    42. MessageBox.Show( Open().ToString());
    43. }
    44. }
    45. ///
    46. /// 实例化第一个找到的相机
    47. ///
    48. public bool BaslerCameraInit()
    49. {
    50. try
    51. {
    52. camera = new Camera();
    53. camera.StreamGrabber.ImageGrabbed -= StreamGrabber_ImageGrabbed;
    54. camera.StreamGrabber.ImageGrabbed+=StreamGrabber_ImageGrabbed;
    55. return true;
    56. }
    57. catch (Exception ex)
    58. {
    59. return false;
    60. //NotifyG.Error(ex.ToString());
    61. }
    62. }
    63. ///
    64. /// 根据相机UserID实例化相机
    65. ///
    66. ///
    67. public bool BaslerCameraInit(string userID)
    68. {
    69. try
    70. {
    71. // 枚举相机列表
    72. List allCameraInfos = CameraFinder.Enumerate();
    73. foreach (ICameraInfo cameraInfo in allCameraInfos)
    74. {
    75. if (userID == cameraInfo[CameraInfoKey.UserDefinedName])
    76. {
    77. this.userID = userID;
    78. camera = new Camera(cameraInfo);
    79. camera.StreamGrabber.ImageGrabbed -= StreamGrabber_ImageGrabbed;
    80. camera.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed;
    81. }
    82. }
    83. if (camera == null)
    84. {
    85. //NotifyG.Error("未识别到UserID为“" + UserID + "”的相机!");
    86. return false;
    87. }
    88. return true;
    89. }
    90. catch (Exception ex)
    91. {
    92. return false;
    93. //NotifyG.Error(ex.ToString());
    94. }
    95. }
    96. void StreamGrabber_ImageGrabbed(object sender, ImageGrabbedEventArgs e)
    97. {
    98. try
    99. {
    100. // Acquire the image from the camera. Only show the latest image. The camera may acquire images faster than the images can be displayed.
    101. // Get the grab result.
    102. IGrabResult grabResult = e.GrabResult;
    103. // Check if the image can be displayed.
    104. if (grabResult.IsValid)
    105. {
    106. //grabTime = sw.ElapsedMilliseconds;
    107. //if (eventComputeGrabTime != null) eventComputeGrabTime(grabTime);
    108. //Reduce the number of displayed images to a reasonable amount if the camera is acquiring images very fast.
    109. // **** 降低显示帧率,减少CPU占用率 **** //
    110. //if (!stopWatch.IsRunning || stopWatch.ElapsedMilliseconds > 33)
    111. {
    112. //stopWatch.Restart();
    113. // 判断是否是黑白图片格式
    114. if (grabResult.PixelTypeValue == PixelType.Mono8)
    115. {
    116. //allocate the m_stream_size amount of bytes in non-managed environment
    117. if (latestFrameAddress == IntPtr.Zero)
    118. {
    119. latestFrameAddress = Marshal.AllocHGlobal((Int32)grabResult.PayloadSize);
    120. }
    121. converter.OutputPixelFormat = PixelType.Mono8;
    122. converter.Convert(latestFrameAddress, grabResult.PayloadSize, grabResult);
    123. HOperatorSet.GenEmptyObj(out image);
    124. image.Dispose();
    125. // 转换为Halcon图像显示
    126. HOperatorSet.GenImage1(out image, "byte", grabResult.Width, grabResult.Height, latestFrameAddress);
    127. HOperatorSet.SetPart(handle, 0, 0, grabResult.Height - 1, grabResult.Width - 1);
    128. }
    129. else if (grabResult.PixelTypeValue == PixelType.BayerBG8 || grabResult.PixelTypeValue == PixelType.BayerGB8
    130. || grabResult.PixelTypeValue == PixelType.BayerRG8 || grabResult.PixelTypeValue == PixelType.YUV422packed)
    131. {
    132. int imageWidth = grabResult.Width - 1;
    133. int imageHeight = grabResult.Height - 1;
    134. HOperatorSet.SetPart(handle, 0, 0, imageHeight, imageWidth);
    135. int payloadSize = imageWidth * imageHeight;
    136. //allocate the m_stream_size amount of bytes in non-managed environment
    137. if (latestFrameAddress == IntPtr.Zero)
    138. {
    139. latestFrameAddress = Marshal.AllocHGlobal((Int32)(3 * payloadSize));
    140. }
    141. converter.OutputPixelFormat = PixelType.RGB8packed; // 根据下面halcon转换的色彩格式bgr
    142. converter.Parameters[PLPixelDataConverter.InconvertibleEdgeHandling].SetValue("Clip");
    143. converter.Convert(latestFrameAddress, 3 * payloadSize, grabResult);
    144. HOperatorSet.GenImageInterleaved(out image, latestFrameAddress, "bgr",
    145. (HTuple)imageWidth, (HTuple)imageHeight, -1, "byte", (HTuple)imageWidth, (HTuple)imageHeight, 0, 0, -1, 0);
    146. }
    147. else
    148. {
    149. //NotifyG.Error(DeviceName + "拍照失败,相机图像格式设置");
    150. return;
    151. }
    152. isOkGrab = true;
    153. //MessageBox.Show(isOkGrab.ToString());
    154. // 抛出图像处理事件
    155. //if (EventGrab != null) EventGrab(this, new CameraGrabEventArgs(image));
    156. }
    157. }
    158. }
    159. catch (Exception ex)
    160. {
    161. //MessageBox.Show(ex.ToString());
    162. return;
    163. }
    164. finally
    165. {
    166. // Dispose the grab result if needed for returning it to the grab loop.
    167. e.DisposeGrabResultIfClone();
    168. }
    169. }
    170. ///
    171. /// 打开相机
    172. ///
    173. public bool Open()
    174. {
    175. try
    176. {
    177. if (camera.IsOpen) camera.Close();
    178. Thread.Sleep(200);
    179. camera.Open();
    180. var imageWidth = camera.Parameters[PLCamera.Width].GetValue(); // 获取图像宽
    181. var imageHeight = camera.Parameters[PLCamera.Height].GetValue(); // 获取图像高
    182. GetMinMaxExposureTime();
    183. GetMinMaxGain();
    184. camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);
    185. //NotifyG.Debug(DeviceName + "打开相机成功:" + userID);
    186. }
    187. catch (Exception ex)
    188. {
    189. MessageBox.Show(ex.ToString());
    190. return false;
    191. }
    192. return true;
    193. }
    194. ///
    195. /// 关闭相机,释放相关资源
    196. ///
    197. public new bool Close()
    198. {
    199. try
    200. {
    201. camera.Close();
    202. camera.Dispose();
    203. if (Image != null)
    204. {
    205. Image.Dispose();
    206. }
    207. if (latestFrameAddress != null)
    208. {
    209. Marshal.FreeHGlobal(latestFrameAddress);
    210. latestFrameAddress = IntPtr.Zero;
    211. }
    212. //NotifyG.Debug(DeviceName + "关闭相机成功:" + userID);
    213. }
    214. catch (Exception ex)
    215. {
    216. MessageBox.Show(ex.ToString());
    217. return false;
    218. }
    219. return true;
    220. }
    221. ///
    222. /// 单张采集
    223. ///
    224. public bool GrabImage()
    225. {
    226. try
    227. {
    228. isOkGrab = false;
    229. sw.Restart();
    230. if (camera.StreamGrabber.IsGrabbing)
    231. {
    232. //NotifyG.Error("相机当前正处于采集状态!");
    233. return false;
    234. }
    235. else
    236. {
    237. camera.StreamGrabber.Start(1, GrabStrategy.LatestImages, GrabLoop.ProvidedByStreamGrabber);
    238. //while (!isOkGrab)
    239. //{
    240. // if (sw.ElapsedMilliseconds > 2000) { isOkGrab = false; return false; }
    241. // Thread.Sleep(1);
    242. //}
    243. //NotifyG.Debug(DeviceName + "拍照成功:" + sw.ElapsedMilliseconds);
    244. return true;
    245. }
    246. }
    247. catch (Exception ex)
    248. {
    249. MessageBox.Show(ex.ToString());
    250. return false;
    251. }
    252. return true;
    253. }
    254. ///
    255. /// 开始连续采集
    256. ///
    257. public bool StartGrabbing()
    258. {
    259. try
    260. {
    261. if (camera.StreamGrabber.IsGrabbing)
    262. {
    263. //NotifyG.Error("相机当前正处于采集状态!");
    264. return false;
    265. }
    266. else
    267. {
    268. camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
    269. camera.StreamGrabber.Start(GrabStrategy.LatestImages, GrabLoop.ProvidedByStreamGrabber);
    270. return true;
    271. }
    272. }
    273. catch (Exception ex)
    274. {
    275. //NotifyG.Error(DeviceName + ex.ToString());
    276. return false;
    277. }
    278. }
    279. ///
    280. /// 停止连续采集
    281. ///
    282. public bool StopGrabbing()
    283. {
    284. try
    285. {
    286. if (camera.StreamGrabber.IsGrabbing)
    287. {
    288. camera.StreamGrabber.Stop();
    289. }
    290. }
    291. catch (Exception ex)
    292. {
    293. //NotifyG.Error(DeviceName + ex.ToString());
    294. }
    295. return true;
    296. }
    297. ///
    298. /// 获取最小最大曝光时间
    299. ///
    300. public void GetMinMaxExposureTime()
    301. {
    302. try
    303. {
    304. if (camera.GetSfncVersion() < Sfnc2_0_0)
    305. {
    306. var minExposureTime = camera.Parameters[PLCamera.ExposureTimeRaw].GetMinimum();
    307. var maxExposureTime = camera.Parameters[PLCamera.ExposureTimeRaw].GetMaximum();
    308. }
    309. else
    310. {
    311. var minExposureTime = (long)camera.Parameters[PLUsbCamera.ExposureTime].GetMinimum();
    312. var maxExposureTime = (long)camera.Parameters[PLUsbCamera.ExposureTime].GetMaximum();
    313. }
    314. }
    315. catch (Exception ex)
    316. {
    317. }
    318. }
    319. ///
    320. /// 获取最小最大增益
    321. ///
    322. public void GetMinMaxGain()
    323. {
    324. try
    325. {
    326. if (camera.GetSfncVersion() < Sfnc2_0_0)
    327. {
    328. var minGain = camera.Parameters[PLCamera.GainRaw].GetMinimum();
    329. var maxGain = camera.Parameters[PLCamera.GainRaw].GetMaximum();
    330. }
    331. else
    332. {
    333. var minGain = (long)camera.Parameters[PLUsbCamera.Gain].GetMinimum();
    334. var maxGain = (long)camera.Parameters[PLUsbCamera.Gain].GetMaximum();
    335. }
    336. }
    337. catch (Exception ex)
    338. {
    339. //NotifyG.Error(DeviceName + ex.ToString());
    340. }
    341. }
    342. private void button2_Click(object sender, EventArgs e)
    343. {
    344. Stopwatch sw1 = new Stopwatch();
    345. sw1.Start();
    346. var f1 = GrabImage();
    347. sw1.Stop();
    348. MessageBox.Show(string.Format("grab time:{0}",sw1.ElapsedMilliseconds));
    349. //if(f1)
    350. //{
    351. // if (null != Image)
    352. // HOperatorSet.DispObj(Image, hWindowControl1.Handle);
    353. //}
    354. }
    355. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    356. {
    357. if (null != camera && camera.IsOpen)
    358. Close();
    359. }
    360. private void button6_Click(object sender, EventArgs e)
    361. {
    362. try
    363. {
    364. if (null != Image && Image.IsInitialized())
    365. {
    366. //HOperatorSet.WriteImage(Image, "bmp", 0, "d:\\123.bmp");
    367. HOperatorSet.DispObj(Image, handle);
    368. }
    369. }
    370. catch (Exception ex)
    371. {
    372. MessageBox.Show(ex.Message);
    373. }
    374. }
    375. private void Form1_Load(object sender, EventArgs e)
    376. {
    377. handle = hWindowControl1.HalconWindow;
    378. }
    379. private void button3_Click(object sender, EventArgs e)
    380. {
    381. timer1.Start();
    382. StartGrabbing();
    383. }
    384. private void button4_Click(object sender, EventArgs e)
    385. {
    386. timer1.Stop();
    387. StopGrabbing();
    388. }
    389. private void timer1_Tick(object sender, EventArgs e)
    390. {
    391. button6_Click(null, null);
    392. }
    393. }
    394. }
  • 相关阅读:
    vue ant 两个页面 调用同一个接口 想在 前端的一个 接口传 一个固定的值 ,另外一个不变 ,查询条件默认值加上自己要的就好啦
    原生js的animate()方法详解
    Yolov5 ONNX导出报错: export failure: Unsupported ONNX opset version: 17
    Java运算符的使用
    LINUX 基础
    “媒体+”时代正当时,ATEN以前瞻解决方案助推媒体融合纵深发展
    c# Stack vs Queue
    [资源推荐] 关于计算机毕设的方法论(重庆大学吕昱峰)
    让iPhone用电脑的网络上网
    CNC 3D浮雕 Aspire 11.55 Crack
  • 原文地址:https://blog.csdn.net/soinlove36/article/details/127717894