BaslerCamera.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. using Basler.Pylon;
  2. using System.ComponentModel;
  3. using Microsoft.Win32;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Drawing;
  8. using System.Drawing.Imaging;
  9. using System.Runtime.InteropServices;
  10. using TeamAAS.Camera.Images;
  11. using TeamAAS.Camera.Models;
  12. using TeamAAS.Camera.Attributes;
  13. using TeamAAS.Camera.Enums;
  14. namespace TeamAAS.Camera.Cameras
  15. {
  16. /// <summary>
  17. /// 巴斯勒 Pylon 相机
  18. /// </summary>
  19. [Camera("Basler Pylon", "巴斯勒 Pylon")]
  20. public class BaslerCamera : CameraBase
  21. {
  22. #region 字段
  23. private Basler.Pylon.Camera m_MyCamera;
  24. UInt32 m_nRowStep = 0;
  25. private PixelDataConverter converter = new PixelDataConverter();
  26. [Browsable(false)]
  27. public ICameraInfo CameraInfo { get; private set; }
  28. #endregion
  29. [Browsable(false)]
  30. public override string CameraBrand => "巴斯勒 Pylon";
  31. public BaslerCamera(Guid id, int index, string name, string serialNumber, string cameraIp, bool isFindByIp)
  32. : base(id, index, name, serialNumber, cameraIp, isFindByIp)
  33. {
  34. List<Basler.Pylon.ICameraInfo> allCameraInfos = Basler.Pylon.CameraFinder.Enumerate();
  35. foreach (ICameraInfo cameraInfo in allCameraInfos)
  36. {
  37. if (cameraInfo[CameraInfoKey.DeviceType].ToLower().Contains("gige"))
  38. {
  39. if (IsFindByIp)
  40. {
  41. if (cameraInfo[CameraInfoKey.DeviceIpAddress] == CameraIp)
  42. {
  43. CameraInfo = cameraInfo;
  44. m_MyCamera = new Basler.Pylon.Camera(cameraInfo);
  45. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo];
  46. ModelName = cameraInfo[CameraInfoKey.ModelName];
  47. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber];
  48. CameraType = CameraType.GIGE;
  49. m_MyCamera.Parameters[PLCameraInstance.GrabCameraEvents].SetValue(true);
  50. m_MyCamera.CameraOpened += Configuration.AcquireContinuous;
  51. m_MyCamera.CameraOpened += M_MyCamera_CameraOpened;
  52. m_MyCamera.CameraClosed += M_MyCamera_CameraClosed;
  53. break;
  54. }
  55. }
  56. else
  57. {
  58. if (cameraInfo[CameraInfoKey.SerialNumber] == SerialNumber)
  59. {
  60. CameraInfo = cameraInfo;
  61. m_MyCamera = new Basler.Pylon.Camera(cameraInfo);
  62. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo];
  63. ModelName = cameraInfo[CameraInfoKey.ModelName];
  64. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber];
  65. CameraType = CameraType.GIGE;
  66. CameraIp = cameraInfo[CameraInfoKey.DeviceIpAddress];
  67. m_MyCamera.Parameters[PLCameraInstance.GrabCameraEvents].SetValue(true);
  68. m_MyCamera.CameraOpened += Configuration.AcquireContinuous;
  69. m_MyCamera.CameraOpened += M_MyCamera_CameraOpened;
  70. m_MyCamera.CameraClosed += M_MyCamera_CameraClosed;
  71. break;
  72. }
  73. }
  74. }
  75. else
  76. {
  77. if (cameraInfo[CameraInfoKey.SerialNumber] == SerialNumber)
  78. {
  79. CameraInfo = cameraInfo;
  80. m_MyCamera = new Basler.Pylon.Camera(cameraInfo);
  81. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo];
  82. ModelName = cameraInfo[CameraInfoKey.ModelName];
  83. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber];
  84. CameraType = CameraType.USB;
  85. m_MyCamera.Parameters[PLCameraInstance.GrabCameraEvents].SetValue(true);
  86. m_MyCamera.CameraOpened += Configuration.AcquireContinuous;
  87. m_MyCamera.CameraOpened += M_MyCamera_CameraOpened;
  88. m_MyCamera.CameraClosed += M_MyCamera_CameraClosed;
  89. break;
  90. }
  91. }
  92. }
  93. IsConnected = false;
  94. }
  95. #region 设备发现
  96. public static CameraInfo[] GetDevices()
  97. {
  98. List<CameraInfo> cameras = new List<CameraInfo>();
  99. try
  100. {
  101. if (!CheckSoftwareInstalled().isInstalled)
  102. {
  103. return cameras.ToArray();
  104. }
  105. List<Basler.Pylon.ICameraInfo> allCameraInfos = Basler.Pylon.CameraFinder.Enumerate();
  106. int i = 0;
  107. foreach (ICameraInfo cameraInfo in allCameraInfos)
  108. {
  109. if (cameraInfo[CameraInfoKey.DeviceType].ToLower().Contains("gige"))
  110. {
  111. cameras.Add(new CameraInfo()
  112. {
  113. CameraNo = i + 1,
  114. CameraName = cameraInfo[CameraInfoKey.FullName],
  115. CameraBrand = "巴斯勒 Pylon",
  116. CameraType = CameraType.GIGE,
  117. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo],
  118. Model = cameraInfo[CameraInfoKey.ModelName],
  119. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber],
  120. CameraIp = cameraInfo[CameraInfoKey.DeviceIpAddress],
  121. IsFindByIp = true,
  122. });
  123. }
  124. else if (cameraInfo[CameraInfoKey.DeviceType].ToLower().Contains("usb"))
  125. {
  126. cameras.Add(new CameraInfo()
  127. {
  128. CameraNo = i + 1,
  129. CameraName = cameraInfo[CameraInfoKey.FullName],
  130. CameraBrand = "巴斯勒 Pylon",
  131. CameraType = CameraType.USB,
  132. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo],
  133. Model = cameraInfo[CameraInfoKey.ModelName],
  134. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber],
  135. CameraIp = "",
  136. });
  137. }
  138. else if (cameraInfo[CameraInfoKey.DeviceType].ToLower().Contains("link"))
  139. {
  140. cameras.Add(new CameraInfo()
  141. {
  142. CameraNo = i + 1,
  143. CameraName = cameraInfo[CameraInfoKey.FullName],
  144. CameraBrand = "巴斯勒 Pylon",
  145. CameraType = CameraType.Link,
  146. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo],
  147. Model = cameraInfo[CameraInfoKey.ModelName],
  148. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber],
  149. CameraIp = "",
  150. });
  151. }
  152. else
  153. {
  154. cameras.Add(new CameraInfo()
  155. {
  156. CameraNo = i + 1,
  157. CameraName = cameraInfo[CameraInfoKey.FullName],
  158. CameraBrand = "巴斯勒 Pylon",
  159. CameraType = CameraType.Unknown,
  160. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo],
  161. Model = cameraInfo[CameraInfoKey.ModelName],
  162. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber],
  163. CameraIp = "",
  164. });
  165. }
  166. i++;
  167. }
  168. }
  169. catch (Exception)
  170. {
  171. }
  172. return cameras.ToArray();
  173. }
  174. public static (bool isInstalled, string version) CheckSoftwareInstalled()
  175. {
  176. string softwareName = "pylon 7 Camera Software";
  177. string softwareVersion = "7.5.0.15658";
  178. string[] registryPaths = new[]
  179. {
  180. @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  181. @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
  182. };
  183. foreach (var path in registryPaths)
  184. {
  185. using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path))
  186. {
  187. if (key == null) continue;
  188. foreach (string subKeyName in key.GetSubKeyNames())
  189. {
  190. using (RegistryKey subKey = key.OpenSubKey(subKeyName))
  191. {
  192. string displayName = subKey?.GetValue("DisplayName")?.ToString();
  193. if (displayName != null && displayName.Contains(softwareName))
  194. {
  195. string version = subKey.GetValue("DisplayVersion")?.ToString();
  196. Version v1 = new Version(version);
  197. Version v2 = new Version(softwareVersion);
  198. if (v1 >= v2)
  199. {
  200. return (true, version);
  201. }
  202. else
  203. {
  204. return (false, version);
  205. }
  206. }
  207. }
  208. }
  209. }
  210. }
  211. return (false, "");
  212. }
  213. #endregion
  214. #region SDK 实现
  215. public override bool OpenDevice()
  216. {
  217. using (WriteLockScope())
  218. {
  219. if (m_MyCamera == null)
  220. {
  221. List<Basler.Pylon.ICameraInfo> allCameraInfos = Basler.Pylon.CameraFinder.Enumerate();
  222. foreach (ICameraInfo cameraInfo in allCameraInfos)
  223. {
  224. if (cameraInfo[CameraInfoKey.DeviceType].ToLower().Contains("gige"))
  225. {
  226. if (IsFindByIp)
  227. {
  228. if (cameraInfo[CameraInfoKey.DeviceIpAddress] == CameraIp)
  229. {
  230. CameraInfo = cameraInfo;
  231. m_MyCamera = new Basler.Pylon.Camera(cameraInfo);
  232. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo];
  233. ModelName = cameraInfo[CameraInfoKey.ModelName];
  234. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber];
  235. CameraType = CameraType.GIGE;
  236. m_MyCamera.Parameters[PLCameraInstance.GrabCameraEvents].SetValue(true);
  237. m_MyCamera.CameraOpened += Configuration.AcquireContinuous;
  238. m_MyCamera.CameraOpened += M_MyCamera_CameraOpened;
  239. m_MyCamera.CameraClosed += M_MyCamera_CameraClosed;
  240. break;
  241. }
  242. }
  243. else
  244. {
  245. if (cameraInfo[CameraInfoKey.SerialNumber] == SerialNumber)
  246. {
  247. CameraInfo = cameraInfo;
  248. m_MyCamera = new Basler.Pylon.Camera(cameraInfo);
  249. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo];
  250. ModelName = cameraInfo[CameraInfoKey.ModelName];
  251. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber];
  252. CameraType = CameraType.GIGE;
  253. CameraIp = cameraInfo[CameraInfoKey.DeviceIpAddress];
  254. m_MyCamera.Parameters[PLCameraInstance.GrabCameraEvents].SetValue(true);
  255. m_MyCamera.CameraOpened += Configuration.AcquireContinuous;
  256. m_MyCamera.CameraOpened += M_MyCamera_CameraOpened;
  257. m_MyCamera.CameraClosed += M_MyCamera_CameraClosed;
  258. break;
  259. }
  260. }
  261. }
  262. else
  263. {
  264. if (cameraInfo[CameraInfoKey.SerialNumber] == SerialNumber)
  265. {
  266. CameraInfo = cameraInfo;
  267. m_MyCamera = new Basler.Pylon.Camera(cameraInfo);
  268. ManufacturerName = cameraInfo[CameraInfoKey.ManufacturerInfo];
  269. ModelName = cameraInfo[CameraInfoKey.ModelName];
  270. SerialNumber = cameraInfo[CameraInfoKey.SerialNumber];
  271. CameraType = CameraType.USB;
  272. m_MyCamera.Parameters[PLCameraInstance.GrabCameraEvents].SetValue(true);
  273. m_MyCamera.CameraOpened += Configuration.AcquireContinuous;
  274. m_MyCamera.CameraOpened += M_MyCamera_CameraOpened;
  275. m_MyCamera.CameraClosed += M_MyCamera_CameraClosed;
  276. break;
  277. }
  278. }
  279. }
  280. if (m_MyCamera == null)
  281. {
  282. throw new Exception("没有识别到相机");
  283. }
  284. }
  285. if (!m_MyCamera.IsOpen)
  286. {
  287. m_MyCamera.Open();
  288. // 按当前触发模式下发(默认软触发,与历史硬编码行为一致)
  289. ApplyTriggerToHardware(TriggerMode);
  290. }
  291. IsConnected = m_MyCamera.IsConnected;
  292. return IsConnected;
  293. }
  294. }
  295. public override void CloseDevice()
  296. {
  297. using (WriteLockScope())
  298. {
  299. if (m_MyCamera != null)
  300. {
  301. if (m_MyCamera.IsOpen)
  302. {
  303. m_MyCamera.Close();
  304. m_MyCamera.CameraOpened -= Configuration.AcquireContinuous;
  305. m_MyCamera.CameraOpened -= M_MyCamera_CameraOpened;
  306. m_MyCamera.CameraClosed -= M_MyCamera_CameraClosed;
  307. IsConnected = m_MyCamera.IsConnected;
  308. m_MyCamera.Dispose();
  309. }
  310. }
  311. }
  312. }
  313. public override GenImage Grab()
  314. {
  315. using (WriteLockScope())
  316. {
  317. var sw = Stopwatch.StartNew();
  318. if (!m_MyCamera.IsOpen)
  319. {
  320. m_MyCamera.Open();
  321. ApplyTriggerToHardware(TriggerMode);
  322. }
  323. if (!m_MyCamera.StreamGrabber.IsGrabbing)
  324. {
  325. m_MyCamera.StreamGrabber.Start();
  326. }
  327. bool Succeed = false;
  328. IGrabResult grabResult = null;
  329. for (int i = 0; i < 5; i++)
  330. {
  331. try
  332. {
  333. // 仅软触发需主动发触发命令;连续采集自由出图,硬触发等外部信号
  334. if (IsSoftwareTrigger)
  335. m_MyCamera.ExecuteSoftwareTrigger();
  336. grabResult = m_MyCamera.StreamGrabber.RetrieveResult(1000, TimeoutHandling.ThrowException);
  337. if (grabResult != null && grabResult.GrabSucceeded)
  338. {
  339. ErrorMessage = "";
  340. Succeed = true;
  341. break;
  342. }
  343. else
  344. {
  345. ErrorMessage = grabResult.ErrorDescription;
  346. }
  347. }
  348. catch (Exception ex)
  349. {
  350. ErrorMessage = ex.Message;
  351. m_MyCamera.Close();
  352. m_MyCamera.CameraOpened -= M_MyCamera_CameraOpened;
  353. m_MyCamera.CameraClosed -= M_MyCamera_CameraClosed;
  354. m_MyCamera.Open();
  355. ApplyTriggerToHardware(TriggerMode);
  356. IsConnected = m_MyCamera.IsConnected;
  357. }
  358. }
  359. if (!Succeed)
  360. {
  361. if (IsConnected)
  362. {
  363. IsConnected = false;
  364. OnConnectChanged(false);
  365. }
  366. return null;
  367. }
  368. Image = GrabResult2GenImage(grabResult);
  369. ImageWidth = (uint)Image.Width;
  370. ImageHeight = (uint)Image.Height;
  371. ApplyGammaToImage(Image);
  372. GC.Collect();
  373. grabResult.Dispose();
  374. TotalTime = sw.Elapsed;
  375. return Image;
  376. }}
  377. #region 触发模式
  378. /// <summary>Basler 支持连续/软触发/硬触发(Line0)全部模式</summary>
  379. public override IReadOnlyList<CameraTriggerMode> SupportedTriggerModes => FullTriggerModes;
  380. /// <summary>历史行为:OpenDevice 硬编码 TriggerMode=On + TriggerSource=Software,故默认软触发</summary>
  381. protected override CameraTriggerMode DefaultTriggerMode => CameraTriggerMode.软触发;
  382. protected override bool ApplyTriggerMode(CameraTriggerMode mode)
  383. {
  384. using (WriteLockScope())
  385. return ApplyTriggerToHardware(mode);
  386. }
  387. /// <summary>
  388. /// 把触发模式下发到 Pylon。AcquisitionMode 恒为 Continuous,仅触发项随模式变化。
  389. /// 调用方需已持有写锁(OpenDevice/Grab 内部已在锁内;锁可重入)。
  390. /// </summary>
  391. private bool ApplyTriggerToHardware(CameraTriggerMode mode)
  392. {
  393. if (m_MyCamera == null || !m_MyCamera.IsOpen) return false;
  394. m_MyCamera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
  395. switch (mode)
  396. {
  397. case CameraTriggerMode.连续采集:
  398. m_MyCamera.Parameters[PLCamera.TriggerMode].SetValue(PLCamera.TriggerMode.Off);
  399. break;
  400. case CameraTriggerMode.软触发:
  401. m_MyCamera.Parameters[PLCamera.TriggerSource].SetValue(PLCamera.TriggerSource.Software);
  402. m_MyCamera.Parameters[PLCamera.TriggerMode].SetValue(PLCamera.TriggerMode.On);
  403. break;
  404. case CameraTriggerMode.硬触发上升沿:
  405. case CameraTriggerMode.硬触发下降沿:
  406. // 本版 Pylon 的 TriggerSource 枚举无 Line0,Basler 机型光耦输入惯例为 Line1;
  407. // 边沿名为 RisingEdge/FallingEdge(非 GenICam 通用的 Rising/Falling)。
  408. m_MyCamera.Parameters[PLCamera.TriggerSource].SetValue(PLCamera.TriggerSource.Line1);
  409. m_MyCamera.Parameters[PLCamera.TriggerActivation].SetValue(
  410. mode == CameraTriggerMode.硬触发上升沿
  411. ? PLCamera.TriggerActivation.RisingEdge
  412. : PLCamera.TriggerActivation.FallingEdge);
  413. m_MyCamera.Parameters[PLCamera.TriggerMode].SetValue(PLCamera.TriggerMode.On);
  414. break;
  415. default: // 跟随相机:不下发,沿用相机自身配置
  416. break;
  417. }
  418. return true;
  419. }
  420. #endregion
  421. public override bool SetExposureTime(float exposureTime)
  422. {
  423. using (WriteLockScope())
  424. {
  425. if (m_MyCamera.Parameters.Contains(PLCamera.ExposureTimeAbs))
  426. {
  427. m_MyCamera.Parameters[PLCamera.ExposureTimeAbs].SetValue(exposureTime);
  428. }
  429. else
  430. m_MyCamera.Parameters[PLCamera.ExposureTime].SetValue(exposureTime);
  431. return true;
  432. }}
  433. public override float GetExposureTime()
  434. {
  435. using (ReadLockScope())
  436. {
  437. if (m_MyCamera.Parameters.Contains(PLCamera.ExposureTimeAbs))
  438. {
  439. return (float)m_MyCamera.Parameters[PLCamera.ExposureTimeAbs].GetValue();
  440. }
  441. else
  442. return (float)m_MyCamera.Parameters[PLCamera.ExposureTime].GetValue();
  443. }}
  444. public override bool SetGain(float gain)
  445. {
  446. using (WriteLockScope())
  447. {
  448. if (m_MyCamera.Parameters.Contains(PLCamera.Gain))
  449. {
  450. m_MyCamera.Parameters[PLCamera.Gain].SetValue(gain);
  451. }
  452. else if (m_MyCamera.Parameters.Contains(PLCamera.GainRaw))
  453. {
  454. m_MyCamera.Parameters[PLCamera.GainRaw].SetValue((int)gain);
  455. }
  456. else if (m_MyCamera.Parameters.Contains(PLCamera.GainAbs))
  457. {
  458. m_MyCamera.Parameters[PLCamera.GainAbs].SetValue(gain);
  459. }
  460. return true;
  461. }}
  462. public override float GetGain()
  463. {
  464. using (ReadLockScope())
  465. {
  466. if (m_MyCamera == null) return 0;
  467. if (m_MyCamera.Parameters.Contains(PLCamera.Gain))
  468. return (float)m_MyCamera.Parameters[PLCamera.Gain].GetValue();
  469. if (m_MyCamera.Parameters.Contains(PLCamera.GainAbs))
  470. return (float)m_MyCamera.Parameters[PLCamera.GainAbs].GetValue();
  471. return (float)m_MyCamera.Parameters[PLCamera.GainRaw].GetValue();
  472. }
  473. }
  474. public override bool SetGamma(float gamma)
  475. {
  476. using (WriteLockScope())
  477. {
  478. try
  479. {
  480. if (m_MyCamera != null && m_MyCamera.Parameters.Contains(PLCamera.Gamma))
  481. {
  482. m_MyCamera.Parameters[PLCamera.Gamma].SetValue(gamma);
  483. return true;
  484. }
  485. }
  486. catch { }
  487. Gamma = gamma;
  488. return true;
  489. }
  490. }
  491. public override float GetGamma()
  492. {
  493. using (ReadLockScope())
  494. {
  495. try
  496. {
  497. if (m_MyCamera != null && m_MyCamera.Parameters.Contains(PLCamera.Gamma))
  498. return (float)m_MyCamera.Parameters[PLCamera.Gamma].GetValue();
  499. }
  500. catch { }
  501. return Gamma;
  502. }
  503. }
  504. #endregion
  505. #region 辅助方法
  506. private void M_MyCamera_CameraClosed(object sender, EventArgs e)
  507. {
  508. OnConnectChanged(false);
  509. }
  510. private void M_MyCamera_CameraOpened(object sender, EventArgs e)
  511. {
  512. OnConnectChanged(true);
  513. }
  514. private bool IsColorPixelFormat(Basler.Pylon.PixelType enType)
  515. {
  516. switch (enType)
  517. {
  518. case Basler.Pylon.PixelType.RGB8packed:
  519. case Basler.Pylon.PixelType.BGR8packed:
  520. case Basler.Pylon.PixelType.RGBA8packed:
  521. case Basler.Pylon.PixelType.BGRA8packed:
  522. case Basler.Pylon.PixelType.YUV422packed:
  523. case Basler.Pylon.PixelType.YUV422_YUYV_Packed:
  524. case Basler.Pylon.PixelType.BayerGR8:
  525. case Basler.Pylon.PixelType.BayerRG8:
  526. case Basler.Pylon.PixelType.BayerGB8:
  527. case Basler.Pylon.PixelType.BayerBG8:
  528. case Basler.Pylon.PixelType.BayerGB10:
  529. case Basler.Pylon.PixelType.BayerGB10pp:
  530. case Basler.Pylon.PixelType.BayerBG10:
  531. case Basler.Pylon.PixelType.BayerBG10pp:
  532. case Basler.Pylon.PixelType.BayerRG10:
  533. case Basler.Pylon.PixelType.BayerRG10pp:
  534. case Basler.Pylon.PixelType.BayerGR10:
  535. case Basler.Pylon.PixelType.BayerGR10pp:
  536. case Basler.Pylon.PixelType.BayerGB12:
  537. case Basler.Pylon.PixelType.BayerGB12p:
  538. case Basler.Pylon.PixelType.BayerBG12:
  539. case Basler.Pylon.PixelType.BayerBG12Packed:
  540. case Basler.Pylon.PixelType.BayerRG12:
  541. case Basler.Pylon.PixelType.BayerRG12Packed:
  542. case Basler.Pylon.PixelType.BayerGR12:
  543. case Basler.Pylon.PixelType.BayerGR12Packed:
  544. return true;
  545. default:
  546. return false;
  547. }
  548. }
  549. private bool IsMonoPixelFormat(Basler.Pylon.PixelType enType)
  550. {
  551. switch (enType)
  552. {
  553. case Basler.Pylon.PixelType.Mono8:
  554. case Basler.Pylon.PixelType.Mono10:
  555. case Basler.Pylon.PixelType.Mono10packed:
  556. case Basler.Pylon.PixelType.Mono12:
  557. case Basler.Pylon.PixelType.Mono12packed:
  558. return true;
  559. default:
  560. return false;
  561. }
  562. }
  563. private GenImage GrabResult2GenImage(IGrabResult grabResult)
  564. {
  565. if (grabResult == null) return null;
  566. int width = grabResult.Width;
  567. int height = grabResult.Height;
  568. byte[] pixelData = grabResult.PixelData as byte[];
  569. if (pixelData == null || pixelData.Length == 0) return null;
  570. // 单通道灰度
  571. if (IsMonoPixelFormat(grabResult.PixelTypeValue))
  572. {
  573. if (grabResult.PixelTypeValue == Basler.Pylon.PixelType.Mono8)
  574. {
  575. return new GenImage(width, height, Images.PixelType.Grey8, pixelData, width);
  576. }
  577. // 非 Mono8 → 转 Mono8
  578. int bufSize = width * height;
  579. var buf = new byte[bufSize];
  580. GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned);
  581. try
  582. {
  583. var conv = new Basler.Pylon.PixelDataConverter();
  584. conv.OutputPixelFormat = Basler.Pylon.PixelType.Mono8;
  585. conv.Convert(handle.AddrOfPinnedObject(), bufSize, grabResult);
  586. }
  587. finally { handle.Free(); }
  588. return new GenImage(width, height, Images.PixelType.Grey8, buf, width);
  589. }
  590. // 彩色 → BGRA32
  591. if (IsColorPixelFormat(grabResult.PixelTypeValue))
  592. {
  593. int stride = width * 4;
  594. var buf = new byte[stride * height];
  595. GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned);
  596. try
  597. {
  598. converter.OutputPixelFormat = Basler.Pylon.PixelType.BGRA8packed;
  599. converter.Convert(handle.AddrOfPinnedObject(), stride * height, grabResult);
  600. }
  601. finally { handle.Free(); }
  602. return new GenImage(width, height, Images.PixelType.BGRA32, buf, stride);
  603. }
  604. return null;
  605. }
  606. #endregion
  607. }
  608. }