AHuaCamera.cs 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. using Cognex.VisionPro;
  2. using CSScripting;
  3. using Microsoft.Win32;
  4. using MVSDK_Net;
  5. using NPOI.Util;
  6. using NPOI.XSSF.Model;
  7. using OpenCvSharp.Dnn;
  8. using Org.BouncyCastle.Asn1.Tsp;
  9. using OxyPlot;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.ComponentModel;
  13. using System.Data.SqlTypes;
  14. using System.Diagnostics;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Runtime.CompilerServices;
  18. using System.Runtime.InteropServices;
  19. using System.Text;
  20. using System.Text.RegularExpressions;
  21. using System.Threading;
  22. using System.Threading.Tasks;
  23. using System.Windows.Media.Media3D;
  24. using TeamAAS_VP.Enums;
  25. using TeamAAS_VP.Interfaces;
  26. using TeamAAS_VP.Models;
  27. using TeamAAS_VP;
  28. using static MVSDK_Net.IMVDefine;
  29. namespace TeamAAS_VP.Core.Cameras
  30. {
  31. public class AHuaCamera : CameraBase, ICamera, INotifyPropertyChanged
  32. {
  33. #region 字段
  34. private Thread m_hReceiveThread;
  35. #endregion
  36. #region 属性
  37. /// <summary>
  38. /// 是否是3D相机
  39. /// </summary>
  40. public bool Is3D { get; } = false;
  41. public CameraBrand CameraBrand { get => CameraBrand.IRayple; }
  42. public string Name { get; private set; }
  43. public Guid ID { get; private set; }
  44. public int Index { get; set; }
  45. public string ManufacturerName { get; private set; }
  46. public bool IsFindByIp { get; private set; }
  47. public string ModelName { get; private set; }
  48. public string SerialNumber { get; private set; }
  49. public string CameraIp { get; private set; }
  50. public CameraType CameraType { get; private set; }
  51. MVSDK_Net.MyCamera mvCameraAcq;
  52. public UInt32 ImageWidth { get; private set; }
  53. public UInt32 ImageHeight { get; private set; }
  54. private bool _IsGrabbing;
  55. /// <summary>
  56. /// 正在采集
  57. /// </summary>
  58. public bool IsGrabbing
  59. {
  60. get { return _IsGrabbing; }
  61. private set { SetProperty(ref _IsGrabbing, value); }
  62. }
  63. private ICogImage _Image;
  64. public ICogImage Image
  65. {
  66. get { return _Image; }
  67. private set { SetProperty(ref _Image, value); }
  68. }
  69. public bool IsConnected { get; private set; }
  70. /// <summary>
  71. /// 采集用时
  72. /// </summary>
  73. public TimeSpan TotalTime { get; private set; }
  74. /// <summary>
  75. /// 错误信息
  76. /// </summary>
  77. public string ErrorMessage { get; private set; }
  78. private bool IsHaveCamera = false;
  79. #endregion
  80. #region 事件
  81. public event Action<ICogImage, TimeSpan, string, Guid> ImageCallbackEvent;
  82. public event Action<Guid, bool> CameraConnectChangedEvent;
  83. #endregion
  84. public AHuaCamera(Guid id, int index, string name, string serialNumber, string cameraip, bool isFindByIp)
  85. {
  86. ID = id;
  87. Name = serialNumber;
  88. Index = index;
  89. CameraIp = cameraip;
  90. SerialNumber = serialNumber;
  91. IsFindByIp = isFindByIp;
  92. mvCameraAcq = new MVSDK_Net.MyCamera();
  93. var list = GetDevices();
  94. foreach (var device in list)
  95. {
  96. if (device.CameraType == CameraType.GIGE)
  97. {
  98. if (IsFindByIp)
  99. {
  100. if (device.CameraIp == CameraIp)
  101. {
  102. IsHaveCamera = true;
  103. ManufacturerName = device.ManufacturerName;
  104. ModelName = device.Model;
  105. SerialNumber = device.SerialNumber;
  106. CameraType = device.CameraType;
  107. int res = mvCameraAcq.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByCameraKey, 0, serialNumber);
  108. if (res == IMVDefine.IMV_OK)
  109. {
  110. }
  111. break;
  112. }
  113. }
  114. else
  115. {
  116. if (device.SerialNumber == serialNumber)
  117. {
  118. IsHaveCamera = true;
  119. ManufacturerName = device.ManufacturerName;
  120. ModelName = device.Model;
  121. SerialNumber = device.SerialNumber;
  122. CameraType = device.CameraType;
  123. CameraIp = device.CameraIp;
  124. int res = mvCameraAcq.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByCameraKey, 0, serialNumber);
  125. if (res == IMVDefine.IMV_OK)
  126. {
  127. }
  128. break;
  129. }
  130. }
  131. }
  132. else
  133. {
  134. if (device.SerialNumber == serialNumber)
  135. {
  136. IsHaveCamera = true;
  137. ManufacturerName = device.ManufacturerName;
  138. ModelName = device.Model;
  139. SerialNumber = device.SerialNumber;
  140. CameraType = device.CameraType;
  141. int res = mvCameraAcq.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByCameraKey, 0, serialNumber);
  142. if (res == IMVDefine.IMV_OK)
  143. {
  144. }
  145. break;
  146. }
  147. }
  148. }
  149. IsConnected = false;
  150. }
  151. #region 方法
  152. /// <summary>
  153. /// 获取设备
  154. /// </summary>
  155. /// <returns></returns>
  156. public static CameraInfo[] GetDevices()
  157. {
  158. List<CameraInfo> cameras = new List<CameraInfo>();
  159. if (!CheckSoftwareInstalled().isInstalled)
  160. {
  161. LogHelper.WriteLogInfo("未安装MV Viewer");
  162. return cameras.ToArray();
  163. }
  164. // 设备搜索
  165. // device search
  166. IMVDefine.IMV_DeviceList deviceList = new IMVDefine.IMV_DeviceList();
  167. IMVDefine.IMV_EInterfaceType interfaceTp = IMVDefine.IMV_EInterfaceType.interfaceTypeAll;
  168. int res = MyCamera.IMV_EnumDevices(ref deviceList, (uint)interfaceTp);
  169. // 添加设备信息
  170. // Add device info
  171. if (res == IMVDefine.IMV_OK && deviceList.nDevNum > 0)
  172. {
  173. for (int i = 0; i < deviceList.nDevNum; i++)
  174. {
  175. IMVDefine.IMV_DeviceInfo deviceInfo =
  176. (IMVDefine.IMV_DeviceInfo)
  177. Marshal.PtrToStructure(
  178. deviceList.pDevInfo + Marshal.SizeOf(typeof(IMVDefine.IMV_DeviceInfo)) * i,
  179. typeof(IMVDefine.IMV_DeviceInfo));
  180. if (deviceInfo.nCameraType == IMV_ECameraType.typeGigeCamera)
  181. {
  182. IMVDefine.IMV_GigEDeviceInfo gigEDeviceInfo =
  183. (IMVDefine.IMV_GigEDeviceInfo)
  184. ByteToStruct(deviceInfo.deviceSpecificInfo.gigeDeviceInfo,
  185. typeof(IMVDefine.IMV_GigEDeviceInfo));
  186. cameras.Add(new Models.CameraInfo()
  187. {
  188. CameraNo = i + 1,
  189. CameraName = deviceInfo.cameraName,
  190. CameraBrand = CameraBrand.IRayple,
  191. CameraType = CameraType.GIGE,
  192. ManufacturerName = deviceInfo.manufactureInfo,
  193. Model = deviceInfo.modelName,
  194. SerialNumber = deviceInfo.serialNumber,
  195. CameraIp = gigEDeviceInfo.ipAddress,
  196. IsFindByIp = true,
  197. });
  198. }
  199. else if (deviceInfo.nCameraType == IMV_ECameraType.typeU3vCamera)
  200. {
  201. cameras.Add(new Models.CameraInfo()
  202. {
  203. CameraNo = i + 1,
  204. CameraName = deviceInfo.cameraName,
  205. CameraBrand = CameraBrand.IRayple,
  206. CameraType = CameraType.USB,
  207. ManufacturerName = deviceInfo.cameraName,
  208. Model = deviceInfo.modelName,
  209. SerialNumber = deviceInfo.serialNumber,
  210. CameraIp = "",
  211. });
  212. }
  213. else if (deviceInfo.nCameraType == IMV_ECameraType.typeCLCamera)
  214. {
  215. cameras.Add(new Models.CameraInfo()
  216. {
  217. CameraNo = i + 1,
  218. CameraName = deviceInfo.cameraName,
  219. CameraBrand = CameraBrand.IRayple,
  220. CameraType = CameraType.Link,
  221. ManufacturerName = deviceInfo.cameraName,
  222. Model = deviceInfo.modelName,
  223. SerialNumber = deviceInfo.serialNumber,
  224. CameraIp = "",
  225. });
  226. }
  227. else
  228. {
  229. cameras.Add(new Models.CameraInfo()
  230. {
  231. CameraNo = i + 1,
  232. CameraName = deviceInfo.cameraName,
  233. CameraBrand = CameraBrand.IRayple,
  234. CameraType = CameraType.Unknown,
  235. ManufacturerName = deviceInfo.cameraName,
  236. Model = deviceInfo.modelName,
  237. SerialNumber = deviceInfo.serialNumber,
  238. CameraIp = "",
  239. });
  240. }
  241. }
  242. }
  243. return cameras.ToArray();
  244. }
  245. /// <summary>
  246. /// 检查相机软件是否安装
  247. /// </summary>
  248. /// <returns></returns>
  249. public static (bool isInstalled, string version) CheckSoftwareInstalled()
  250. {
  251. string softwareName = "MV Viewer";
  252. string softwareVersion = "2.5.1.1";
  253. string[] registryPaths = new[]
  254. {
  255. @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  256. @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
  257. };
  258. foreach (var path in registryPaths)
  259. {
  260. using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path))
  261. {
  262. if (key == null) continue;
  263. foreach (string subKeyName in key.GetSubKeyNames())
  264. {
  265. using (RegistryKey subKey = key.OpenSubKey(subKeyName))
  266. {
  267. string displayName = subKey.GetValue("DisplayName")?.ToString();
  268. if (displayName != null && displayName.Contains(softwareName))
  269. {
  270. string version = subKey.GetValue("DisplayVersion")?.ToString();
  271. var match = Regex.Match(version, @"^(\d+\.\d+\.\d+\.\d+)");
  272. if (match.Success)
  273. {
  274. version = match.Groups[1].Value;
  275. }
  276. else
  277. {
  278. continue;
  279. }
  280. Version v1 = new Version(version);
  281. Version v2 = new Version(softwareVersion);
  282. if (v1 >= v2)
  283. {
  284. return (true, version);
  285. }
  286. else
  287. {
  288. return (false, version);
  289. }
  290. }
  291. }
  292. }
  293. }
  294. }
  295. return (false, "");
  296. }
  297. /// <summary>
  298. /// 打开相机
  299. /// </summary>
  300. /// <returns></returns>
  301. /// <exception cref="Exception"></exception>
  302. public bool OpenDevice()
  303. {
  304. EnterOperation();
  305. try
  306. {
  307. IsConnected = false;
  308. //if (!IsHaveCamera)
  309. //{
  310. var list = GetDevices();
  311. foreach (var device in list)
  312. {
  313. if (device.CameraType == CameraType.GIGE)
  314. {
  315. if (IsFindByIp)
  316. {
  317. if (device.CameraIp == CameraIp)
  318. {
  319. IsHaveCamera = true;
  320. ManufacturerName = device.ManufacturerName;
  321. ModelName = device.Model;
  322. SerialNumber = device.SerialNumber;
  323. CameraType = device.CameraType;
  324. int res = mvCameraAcq.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByCameraKey, 0, SerialNumber);
  325. if (res == IMVDefine.IMV_OK)
  326. {
  327. }
  328. break;
  329. }
  330. }
  331. else
  332. {
  333. if (device.SerialNumber == SerialNumber)
  334. {
  335. IsHaveCamera = true;
  336. ManufacturerName = device.ManufacturerName;
  337. ModelName = device.Model;
  338. SerialNumber = device.SerialNumber;
  339. CameraType = device.CameraType;
  340. CameraIp = device.CameraIp;
  341. int res = mvCameraAcq.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByCameraKey, 0, SerialNumber);
  342. if (res == IMVDefine.IMV_OK)
  343. {
  344. }
  345. break;
  346. }
  347. }
  348. }
  349. else
  350. {
  351. if (device.SerialNumber == SerialNumber)
  352. {
  353. IsHaveCamera = true;
  354. ManufacturerName = device.ManufacturerName;
  355. ModelName = device.Model;
  356. SerialNumber = device.SerialNumber;
  357. CameraType = device.CameraType;
  358. int res = mvCameraAcq.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByCameraKey, 0, SerialNumber);
  359. if (res == IMVDefine.IMV_OK)
  360. {
  361. }
  362. break;
  363. }
  364. }
  365. }
  366. if (!IsHaveCamera)
  367. {
  368. //throw new Exception("没有发现相机");
  369. return false;
  370. }
  371. //}
  372. // 打开设备
  373. // open device
  374. int res1 = mvCameraAcq.IMV_Open();
  375. if (res1 != IMVDefine.IMV_OK)
  376. {
  377. return IsConnected;
  378. }
  379. if (!IsConnected)
  380. {
  381. CameraConnectChangedEvent?.Invoke(ID, true);
  382. }
  383. long width = 0;
  384. long height = 0;
  385. // 获取宽
  386. // Get Width
  387. res1 = mvCameraAcq.IMV_GetIntFeatureValue("Width", ref width);
  388. if (res1 != IMVDefine.IMV_OK)
  389. {
  390. //MessageBox.Show("Get Width failed");
  391. }
  392. // 获取高
  393. // Get Height
  394. res1 = mvCameraAcq.IMV_GetIntFeatureValue("Height", ref height);
  395. if (res1 != IMVDefine.IMV_OK)
  396. {
  397. //MessageBox.Show("Get Height failed");
  398. }
  399. ImageWidth = (uint)width;
  400. ImageHeight = (uint)height;
  401. m_picSize = width * height;
  402. res1 = mvCameraAcq.IMV_SetEnumFeatureSymbol("AcquisitionMode", "Continuous");
  403. if (res1 != IMVDefine.IMV_OK)
  404. {
  405. //MessageBox.Show("Set AcquisitionMode failed");
  406. }
  407. // 关闭触发模式
  408. // set trigger mode as off
  409. res1 = mvCameraAcq.IMV_SetEnumFeatureSymbol("TriggerMode", "Off");
  410. if (res1 != IMVDefine.IMV_OK)
  411. {
  412. //MessageBox.Show("Set TriggerMode failed");
  413. }
  414. // 开启码流
  415. // start grabbing
  416. res1 = mvCameraAcq.IMV_StartGrabbing();
  417. if (res1 != IMVDefine.IMV_OK)
  418. {
  419. //MessageBox.Show("Start grabbing failed!");
  420. }
  421. IsConnected = mvCameraAcq.IMV_IsOpen();
  422. return IsConnected;
  423. }
  424. finally
  425. {
  426. ExitOperation();
  427. }
  428. }
  429. /// <summary>
  430. /// 打开相机异步
  431. /// </summary>
  432. /// <returns></returns>
  433. public Task<bool> OpenDeviceAsync()
  434. {
  435. return Task.Run(() =>
  436. {
  437. return OpenDevice();
  438. });
  439. }
  440. /// <summary>
  441. /// 关闭相机
  442. /// </summary>
  443. public void CloseDevice()
  444. {
  445. EnterOperation();
  446. try
  447. {
  448. if (mvCameraAcq.IMV_IsOpen())
  449. {
  450. // ch:关闭设备 | en:Close Device
  451. mvCameraAcq.IMV_Close();
  452. mvCameraAcq.IMV_DestroyHandle();
  453. }
  454. }
  455. finally
  456. {
  457. ExitOperation();
  458. }
  459. }
  460. private long m_picSize = 0;
  461. IMVDefine.IMV_Frame frame = new IMVDefine.IMV_Frame();
  462. IntPtr pTemp = IntPtr.Zero;
  463. IntPtr pConvertDstBuffer = IntPtr.Zero;
  464. int nConvertBufSize = 0;
  465. private IMVDefine.IMV_PixelConvertParam stPixelConvertParam = new IMVDefine.IMV_PixelConvertParam();
  466. private IMVDefine.IMV_EPixelType type = IMVDefine.IMV_EPixelType.gvspPixelMono8;
  467. /// <summary>
  468. /// 采集图像
  469. /// </summary>
  470. /// <returns></returns>
  471. public ICogImage Grab(bool isRealtime = true)
  472. {
  473. EnterOperation();
  474. try
  475. {
  476. Byte[] byteArrImageData = new Byte[m_picSize * 3];
  477. Stopwatch sw = Stopwatch.StartNew();
  478. int res = IMVDefine.IMV_OK;
  479. for (int i = 0; i < 5; i++)
  480. {
  481. try
  482. {
  483. if (!mvCameraAcq.IMV_IsOpen())
  484. {
  485. OpenDevice();
  486. }
  487. mvCameraAcq.IMV_ClearFrameBuffer();
  488. res = mvCameraAcq.IMV_GetFrame(ref frame, 1000);
  489. if (res == IMVDefine.IMV_OK)
  490. {
  491. try
  492. {
  493. // Mono图像处理
  494. if (IsMonoPixelFormat(frame.frameInfo.pixelFormat))
  495. {
  496. type = IMVDefine.IMV_EPixelType.gvspPixelMono8;
  497. if (frame.frameInfo.pixelFormat == IMVDefine.IMV_EPixelType.gvspPixelMono8)
  498. {
  499. pTemp = frame.pData;
  500. }
  501. else
  502. {
  503. if (pConvertDstBuffer == IntPtr.Zero || nConvertBufSize < (frame.frameInfo.width * frame.frameInfo.height))
  504. {
  505. if (pConvertDstBuffer != IntPtr.Zero)
  506. {
  507. Marshal.FreeHGlobal(pConvertDstBuffer);
  508. pConvertDstBuffer = IntPtr.Zero;
  509. }
  510. pConvertDstBuffer = Marshal.AllocHGlobal((int)(frame.frameInfo.width * frame.frameInfo.height));
  511. if (pConvertDstBuffer == IntPtr.Zero)
  512. {
  513. break;
  514. }
  515. nConvertBufSize = (int)(frame.frameInfo.width * frame.frameInfo.height);
  516. }
  517. // 其他格式Mono转为Mono8
  518. stPixelConvertParam.nWidth = frame.frameInfo.width;
  519. stPixelConvertParam.nHeight = frame.frameInfo.height;
  520. stPixelConvertParam.ePixelFormat = frame.frameInfo.pixelFormat;
  521. stPixelConvertParam.pSrcData = frame.pData;
  522. stPixelConvertParam.nSrcDataLen = frame.frameInfo.size;
  523. stPixelConvertParam.nPaddingX = frame.frameInfo.paddingX;
  524. stPixelConvertParam.nPaddingY = frame.frameInfo.paddingY;
  525. stPixelConvertParam.eBayerDemosaic = IMVDefine.IMV_EBayerDemosaic.demosaicNearestNeighbor;
  526. stPixelConvertParam.eDstPixelFormat = IMVDefine.IMV_EPixelType.gvspPixelMono8;
  527. stPixelConvertParam.pDstBuf = pConvertDstBuffer;
  528. stPixelConvertParam.nDstBufSize = frame.frameInfo.width * frame.frameInfo.height;
  529. res = mvCameraAcq.IMV_PixelConvert(ref stPixelConvertParam);
  530. if (res != IMVDefine.IMV_OK)
  531. {
  532. break;
  533. }
  534. pTemp = pConvertDstBuffer;
  535. }
  536. }
  537. // 彩色图像处理
  538. else if (IsColorPixelFormat(frame.frameInfo.pixelFormat))
  539. {
  540. type = IMVDefine.IMV_EPixelType.gvspPixelRGB8;
  541. if (frame.frameInfo.pixelFormat == IMVDefine.IMV_EPixelType.gvspPixelRGB8)
  542. {
  543. pTemp = frame.pData;
  544. }
  545. else
  546. {
  547. if (pConvertDstBuffer == IntPtr.Zero || nConvertBufSize < (frame.frameInfo.width * frame.frameInfo.height * 3))
  548. {
  549. if (pConvertDstBuffer != IntPtr.Zero)
  550. {
  551. Marshal.FreeHGlobal(pConvertDstBuffer);
  552. pConvertDstBuffer = IntPtr.Zero;
  553. }
  554. pConvertDstBuffer = Marshal.AllocHGlobal((int)(frame.frameInfo.width * frame.frameInfo.height * 3));
  555. if (pConvertDstBuffer == IntPtr.Zero)
  556. {
  557. break;
  558. }
  559. nConvertBufSize = (int)(frame.frameInfo.width * frame.frameInfo.height * 3);
  560. }
  561. // 其他格式彩色图像转为RGB
  562. stPixelConvertParam.nWidth = frame.frameInfo.width;
  563. stPixelConvertParam.nHeight = frame.frameInfo.height;
  564. stPixelConvertParam.ePixelFormat = frame.frameInfo.pixelFormat;
  565. stPixelConvertParam.pSrcData = frame.pData;
  566. stPixelConvertParam.nSrcDataLen = frame.frameInfo.size;
  567. stPixelConvertParam.nPaddingX = frame.frameInfo.paddingX;
  568. stPixelConvertParam.nPaddingY = frame.frameInfo.paddingY;
  569. stPixelConvertParam.eBayerDemosaic = IMVDefine.IMV_EBayerDemosaic.demosaicNearestNeighbor;
  570. stPixelConvertParam.eDstPixelFormat = IMVDefine.IMV_EPixelType.gvspPixelRGB8;
  571. stPixelConvertParam.pDstBuf = pConvertDstBuffer;
  572. stPixelConvertParam.nDstBufSize = frame.frameInfo.width * frame.frameInfo.height * 3;
  573. res = mvCameraAcq.IMV_PixelConvert(ref stPixelConvertParam);
  574. if (res != IMVDefine.IMV_OK)
  575. {
  576. break;
  577. }
  578. pTemp = pConvertDstBuffer;
  579. }
  580. unsafe
  581. {
  582. byte* pBufForSaveImage = (byte*)pTemp;
  583. UInt32 nSupWidth = (uint)((frame.frameInfo.width + (UInt32)3) & 0xfffffffc);
  584. for (int nRow = 0; nRow < frame.frameInfo.height; nRow++)
  585. {
  586. for (int col = 0; col < frame.frameInfo.width; col++)
  587. {
  588. byteArrImageData[nRow * nSupWidth + col] = pBufForSaveImage[nRow * frame.frameInfo.width * 3 + (3 * col)];
  589. byteArrImageData[frame.frameInfo.width * frame.frameInfo.height + nRow * nSupWidth + col] = pBufForSaveImage[nRow * frame.frameInfo.width * 3 + (3 * col + 1)];
  590. byteArrImageData[frame.frameInfo.width * frame.frameInfo.height * 2 + nRow * nSupWidth + col] = pBufForSaveImage[nRow * frame.frameInfo.width * 3 + (3 * col + 2)];
  591. }
  592. }
  593. pTemp = Marshal.UnsafeAddrOfPinnedArrayElement(byteArrImageData, 0);
  594. }
  595. }
  596. else
  597. {
  598. continue;
  599. }
  600. Image = ConvertImage(frame.frameInfo.width, frame.frameInfo.height, pTemp, type);
  601. if (Image != null)
  602. {
  603. ErrorMessage = "";
  604. TotalTime = sw.Elapsed;
  605. return Image;
  606. }
  607. }
  608. catch (Exception)
  609. {
  610. }
  611. finally
  612. {
  613. // 释放帧数据
  614. // release frame
  615. mvCameraAcq.IMV_ReleaseFrame(ref frame);
  616. }
  617. }
  618. else
  619. {
  620. ErrorMessage = res.ToString();
  621. CloseDevice();
  622. OpenDevice();
  623. }
  624. }
  625. catch (Exception ex)
  626. {
  627. CloseDevice();
  628. OpenDevice();
  629. ErrorMessage = ex.Message;
  630. }
  631. }
  632. if (IsConnected)
  633. {
  634. IsConnected = false;
  635. CameraConnectChangedEvent?.Invoke(ID, false);
  636. }
  637. return null;
  638. }
  639. finally
  640. {
  641. ExitOperation();
  642. }
  643. }
  644. /// <summary>
  645. /// 开始采集图像
  646. /// </summary>
  647. public void StartGrabbing()
  648. {
  649. lock (_stateLock)
  650. {
  651. if (IsGrabbing)
  652. return;
  653. IsGrabbing = true;
  654. }
  655. m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true };
  656. m_hReceiveThread.Start();
  657. }
  658. /// <summary>
  659. /// 停止采集图像
  660. /// </summary>
  661. public void StopGrabbing()
  662. {
  663. try
  664. {
  665. lock (_stateLock)
  666. {
  667. IsGrabbing = false;
  668. }
  669. Thread.Sleep(1000);
  670. if (m_hReceiveThread != null)
  671. {
  672. m_hReceiveThread.Abort();
  673. m_hReceiveThread = null;
  674. }
  675. }
  676. catch (Exception)
  677. {
  678. }
  679. }
  680. /// <summary>
  681. /// 设置曝光时间
  682. /// </summary>
  683. /// <param name="ExposureTime"></param>
  684. /// <returns></returns>
  685. public bool SetExposureTime(float ExposureTime)
  686. {
  687. if (!mvCameraAcq.IMV_IsOpen())
  688. return false;
  689. if (GetExposureTime() != ExposureTime)
  690. {
  691. bool success = false;
  692. for (int i = 0; i < 5; i++)
  693. {
  694. int res = mvCameraAcq.IMV_SetDoubleFeatureValue("ExposureTime", (double)ExposureTime);
  695. if (IMVDefine.IMV_OK == res)
  696. {
  697. success = true;
  698. Thread.Sleep(100);
  699. break;
  700. }
  701. }
  702. return success;
  703. }
  704. return true;
  705. }
  706. /// <summary>
  707. /// 获取曝光时间
  708. /// </summary>
  709. /// <returns></returns>
  710. public float GetExposureTime()
  711. {
  712. if (!mvCameraAcq.IMV_IsOpen())
  713. return 0;
  714. // 获取曝光值
  715. // set ExposureTime
  716. double exposureTime = 0;
  717. int res = mvCameraAcq.IMV_GetDoubleFeatureValue("ExposureTime", ref exposureTime);
  718. if (IMVDefine.IMV_OK != res)
  719. {
  720. return 0;
  721. }
  722. return (float)exposureTime;
  723. }
  724. /// <summary>
  725. /// 设置增益
  726. /// </summary>
  727. /// <param name="Gain"></param>
  728. /// <returns></returns>
  729. public bool SetGain(float Gain)
  730. {
  731. if (!mvCameraAcq.IMV_IsOpen())
  732. return false;
  733. if (GetGain() != Gain)
  734. {
  735. // 设置增益
  736. // set Gain
  737. bool success = false;
  738. for (int i = 0; i < 5; i++)
  739. {
  740. int res = mvCameraAcq.IMV_SetDoubleFeatureValue("GainRaw", (double)Gain);
  741. if (IMVDefine.IMV_OK == res)
  742. {
  743. success = true;
  744. break;
  745. }
  746. }
  747. return success;
  748. }
  749. return true;
  750. }
  751. /// <summary>
  752. /// 获取增益
  753. /// </summary>
  754. /// <returns></returns>
  755. public float GetGain()
  756. {
  757. if (!mvCameraAcq.IMV_IsOpen())
  758. return 0;
  759. // 获取增益
  760. double gain = 0;
  761. int res = mvCameraAcq.IMV_GetDoubleFeatureValue("GainRaw", ref gain);
  762. if (IMVDefine.IMV_OK != res)
  763. {
  764. return 0;
  765. }
  766. return (float)gain;
  767. }
  768. private void GetStreamThreadProc()
  769. {
  770. while (IsGrabbing)
  771. {
  772. try
  773. {
  774. Grab();
  775. ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage, ID);
  776. }
  777. catch (Exception)
  778. {
  779. }
  780. Thread.Sleep(10);
  781. }
  782. IsGrabbing = false;
  783. }
  784. /// <summary>
  785. /// 图像是否为Mono格式
  786. /// </summary>
  787. /// <param name="enType"></param>
  788. /// <returns></returns>
  789. private bool IsMonoPixelFormat(IMVDefine.IMV_EPixelType enType)
  790. {
  791. switch (enType)
  792. {
  793. case IMVDefine.IMV_EPixelType.gvspPixelMono8:
  794. case IMVDefine.IMV_EPixelType.gvspPixelMono10:
  795. case IMVDefine.IMV_EPixelType.gvspPixelMono10Packed:
  796. case IMVDefine.IMV_EPixelType.gvspPixelMono12:
  797. case IMVDefine.IMV_EPixelType.gvspPixelMono12Packed:
  798. return true;
  799. default:
  800. return false;
  801. }
  802. }
  803. /// <summary>
  804. /// 图像是否为彩色
  805. /// </summary>
  806. /// <param name="enType"></param>
  807. /// <returns></returns>
  808. private bool IsColorPixelFormat(IMVDefine.IMV_EPixelType enType)
  809. {
  810. switch (enType)
  811. {
  812. case IMVDefine.IMV_EPixelType.gvspPixelRGB8:
  813. case IMVDefine.IMV_EPixelType.gvspPixelBGR8:
  814. case IMVDefine.IMV_EPixelType.gvspPixelRGBA8:
  815. case IMVDefine.IMV_EPixelType.gvspPixelBGRA8:
  816. case IMVDefine.IMV_EPixelType.gvspPixelYUV422_8:
  817. case IMVDefine.IMV_EPixelType.gvspPixelYUV422_8_UYVY:
  818. case IMVDefine.IMV_EPixelType.gvspPixelBayGR8:
  819. case IMVDefine.IMV_EPixelType.gvspPixelBayRG8:
  820. case IMVDefine.IMV_EPixelType.gvspPixelBayGB8:
  821. case IMVDefine.IMV_EPixelType.gvspPixelBayBG8:
  822. case IMVDefine.IMV_EPixelType.gvspPixelBayGB10:
  823. case IMVDefine.IMV_EPixelType.gvspPixelBayGB10Packed:
  824. case IMVDefine.IMV_EPixelType.gvspPixelBayBG10:
  825. case IMVDefine.IMV_EPixelType.gvspPixelBayBG10Packed:
  826. case IMVDefine.IMV_EPixelType.gvspPixelBayRG10:
  827. case IMVDefine.IMV_EPixelType.gvspPixelBayRG10Packed:
  828. case IMVDefine.IMV_EPixelType.gvspPixelBayGR10:
  829. case IMVDefine.IMV_EPixelType.gvspPixelBayGR10Packed:
  830. case IMVDefine.IMV_EPixelType.gvspPixelBayGB12:
  831. case IMVDefine.IMV_EPixelType.gvspPixelBayGB12Packed:
  832. case IMVDefine.IMV_EPixelType.gvspPixelBayBG12:
  833. case IMVDefine.IMV_EPixelType.gvspPixelBayBG12Packed:
  834. case IMVDefine.IMV_EPixelType.gvspPixelBayRG12:
  835. case IMVDefine.IMV_EPixelType.gvspPixelBayRG12Packed:
  836. case IMVDefine.IMV_EPixelType.gvspPixelBayGR12:
  837. case IMVDefine.IMV_EPixelType.gvspPixelBayGR12Packed:
  838. return true;
  839. default:
  840. return false;
  841. }
  842. }
  843. /// <summary>
  844. /// 转换图片
  845. /// </summary>
  846. /// <param name="nHeight">高</param>
  847. /// <param name="nWidth">宽</param>
  848. /// <param name="pImageBuf">图片数据</param>
  849. /// <param name="enPixelType">像素格式</param>
  850. public ICogImage ConvertImage(UInt32 nWidth, UInt32 nHeight, IntPtr pImageBuf, IMVDefine.IMV_EPixelType enPixelType)
  851. {
  852. try
  853. {
  854. if (enPixelType == IMVDefine.IMV_EPixelType.gvspPixelMono8)
  855. {
  856. CogImage8Root cogImage8Root = new CogImage8Root();
  857. cogImage8Root.Initialize((Int32)nWidth, (Int32)nHeight, pImageBuf, (Int32)nWidth, null);
  858. CogImage8Grey cogImage8Grey = new CogImage8Grey();
  859. cogImage8Grey.SetRoot(cogImage8Root);
  860. var image = cogImage8Grey.ScaleImage((int)nWidth, (int)nHeight);
  861. System.GC.Collect();
  862. return image;
  863. }
  864. else
  865. {
  866. CogImage8Root image0 = new CogImage8Root();
  867. IntPtr ptr0 = new IntPtr(pImageBuf.ToInt64());
  868. image0.Initialize((int)nWidth, (int)nHeight, ptr0, (int)nWidth, null);
  869. CogImage8Root image1 = new CogImage8Root();
  870. IntPtr ptr1 = new IntPtr(pImageBuf.ToInt64() + m_picSize);
  871. image1.Initialize((int)nWidth, (int)nHeight, ptr1, (int)nWidth, null);
  872. CogImage8Root image2 = new CogImage8Root();
  873. IntPtr ptr2 = new IntPtr(pImageBuf.ToInt64() + m_picSize * 2);
  874. image2.Initialize((int)nWidth, (int)nHeight, ptr2, (int)nWidth, null);
  875. CogImage24PlanarColor colorImage = new CogImage24PlanarColor();
  876. colorImage.SetRoots(image0, image1, image2);
  877. var image = colorImage.ScaleImage((int)nWidth, (int)nHeight);
  878. System.GC.Collect();
  879. return image;
  880. }
  881. }
  882. catch (System.Exception)
  883. {
  884. return null;
  885. }
  886. }
  887. public static object ByteToStruct(Byte[] bytes, Type type)
  888. {
  889. int size = Marshal.SizeOf(type);
  890. if (size > bytes.Length)
  891. {
  892. return null;
  893. }
  894. // 分配结构体内存空间
  895. IntPtr structPtr = Marshal.AllocHGlobal(size);
  896. // 将byte数组拷贝到分配好的内存空间
  897. Marshal.Copy(bytes, 0, structPtr, size);
  898. // 将内存空间转换为目标结构体
  899. object obj = Marshal.PtrToStructure(structPtr, type);
  900. // 释放内存空间
  901. Marshal.FreeHGlobal(structPtr);
  902. return obj;
  903. }
  904. #endregion
  905. #region 属性通知
  906. /// <summary>
  907. /// Occurs when a property value changes.
  908. /// </summary>
  909. public event PropertyChangedEventHandler PropertyChanged;
  910. /// <summary>
  911. /// Checks if a property already matches a desired value. Sets the property and
  912. /// notifies listeners only when necessary.
  913. /// </summary>
  914. /// <typeparam name="T">Type of the property.</typeparam>
  915. /// <param name="storage">Reference to a property with both getter and setter.</param>
  916. /// <param name="value">Desired value for the property.</param>
  917. /// <param name="propertyName">Name of the property used to notify listeners. This
  918. /// value is optional and can be provided automatically when invoked from compilers that
  919. /// support CallerMemberName.</param>
  920. /// <returns>True if the value was changed, false if the existing value matched the
  921. /// desired value.</returns>
  922. protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
  923. {
  924. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  925. storage = value;
  926. RaisePropertyChanged(propertyName);
  927. return true;
  928. }
  929. /// <summary>
  930. /// Checks if a property already matches a desired value. Sets the property and
  931. /// notifies listeners only when necessary.
  932. /// </summary>
  933. /// <typeparam name="T">Type of the property.</typeparam>
  934. /// <param name="storage">Reference to a property with both getter and setter.</param>
  935. /// <param name="value">Desired value for the property.</param>
  936. /// <param name="propertyName">Name of the property used to notify listeners. This
  937. /// value is optional and can be provided automatically when invoked from compilers that
  938. /// support CallerMemberName.</param>
  939. /// <param name="onChanged">Action that is called after the property value has been changed.</param>
  940. /// <returns>True if the value was changed, false if the existing value matched the
  941. /// desired value.</returns>
  942. protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
  943. {
  944. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  945. storage = value;
  946. onChanged?.Invoke();
  947. RaisePropertyChanged(propertyName);
  948. return true;
  949. }
  950. /// <summary>
  951. /// Raises this object's PropertyChanged event.
  952. /// </summary>
  953. /// <param name="propertyName">Name of the property used to notify listeners. This
  954. /// value is optional and can be provided automatically when invoked from compilers
  955. /// that support <see cref="CallerMemberNameAttribute"/>.</param>
  956. protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
  957. {
  958. OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
  959. }
  960. /// <summary>
  961. /// Raises this object's PropertyChanged event.
  962. /// </summary>
  963. /// <param name="args">The PropertyChangedEventArgs</param>
  964. protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
  965. {
  966. PropertyChanged?.Invoke(this, args);
  967. }
  968. #endregion
  969. }
  970. }