SSZNCamera.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. using Cognex.VisionPro;
  2. using Cognex.VisionPro.ToolBlock;
  3. using CSScripting;
  4. using Microsoft.Win32;
  5. using NPOI.SS.Formula.Functions;
  6. using SR7Link;
  7. using SRAPI;
  8. using SRCSharpDemo;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.ComponentModel;
  12. using System.Diagnostics;
  13. using System.IO;
  14. using System.Linq;
  15. using System.Runtime.CompilerServices;
  16. using System.Runtime.InteropServices;
  17. using System.Text;
  18. using System.Threading;
  19. using System.Threading.Tasks;
  20. using System.Windows.Forms;
  21. using TeamAAS_VP.Enums;
  22. using TeamAAS_VP.Interfaces;
  23. using TeamAAS_VP.Models;
  24. namespace TeamAAS_VP.Core.Cameras
  25. {
  26. public class SSZNCamera : ICamera, INotifyPropertyChanged
  27. {
  28. #region 字段
  29. private Thread m_hReceiveThread;
  30. // 用于序列化对同一相机实例的操作,防止同一实例被并发操作
  31. //private readonly SemaphoreSlim _operationSemaphore = new SemaphoreSlim(1, 1);
  32. // 用于保护状态变量(例如 IsGrabbing)的并发访问
  33. private readonly object _stateLock = new object();
  34. private SR7ApiOneTimeCallbackImpl iSR7APi = new SR7ApiOneTimeCallbackImpl();
  35. public SRCSharpTools srcsharpTools = new SRCSharpTools();
  36. private SR7IFGetDataCallBack GetDataDelegate;
  37. private ErrConnectCallBack _errConnectDelegate;
  38. // 用于 Grab() 的一次性等待/完成通知
  39. private TaskCompletionSource<ICogImage> _grabTcs;
  40. #endregion
  41. #region define
  42. private int lastTotalPoints = 0; // 记录上次的总点数 / Record the last total points
  43. public int coutCallbackPoints;//统计总回调行数 / Count the total number of callback rows
  44. public uint profile16Bits = 0;//0:32bit 1:16bit
  45. //define
  46. public const int INVALID_VALUE_MIN = -1000000000;
  47. public const int INVALID_VALUE_MAX = 1000000000;
  48. #endregion
  49. #region Image cache variable
  50. //image cache
  51. public int[][] ImgBuff32; // 32-bit height data
  52. public short[][] ImgBuff16; // 16-bit height data
  53. public byte[][] GrayBuff; // Grayscale data
  54. public int[][] Encoder; // Encoder data
  55. public int coutCallbackPoints_B;
  56. #endregion
  57. #region 属性
  58. /// <summary>
  59. /// 是否是3D相机
  60. /// </summary>
  61. public bool Is3D { get; } = true;
  62. public CameraBrand CameraBrand { get => CameraBrand.SSZN; }
  63. public string Name { get; private set; }
  64. public Guid ID { get; private set; }
  65. public int Index { get; set; }
  66. public string ManufacturerName { get; private set; }
  67. public bool IsFindByIp { get; private set; }
  68. public string ModelName { get; private set; }
  69. public string SerialNumber { get; private set; }
  70. public string CameraIp { get; private set; }
  71. public CameraType CameraType { get; private set; }
  72. public UInt32 ImageWidth { get; private set; }
  73. public UInt32 ImageHeight { get; private set; }
  74. private bool _IsGrabbing;
  75. /// <summary>
  76. /// 正在采集
  77. /// </summary>
  78. public bool IsGrabbing
  79. {
  80. get { return _IsGrabbing; }
  81. private set { SetProperty(ref _IsGrabbing, value); }
  82. }
  83. private ICogImage _Image;
  84. public ICogImage Image
  85. {
  86. get { return _Image; }
  87. private set { SetProperty(ref _Image, value); }
  88. }
  89. public bool IsConnected { get; private set; }
  90. /// <summary>
  91. /// 采集用时
  92. /// </summary>
  93. public TimeSpan TotalTime { get; private set; }
  94. /// <summary>
  95. /// 错误信息
  96. /// </summary>
  97. public string ErrorMessage { get; private set; }
  98. private bool _CameraRevFinish;
  99. /// <summary>
  100. /// 图像接收完成
  101. /// </summary>
  102. public bool CameraRevFinish
  103. {
  104. get { return _CameraRevFinish; }
  105. set { SetProperty(ref _CameraRevFinish, value); }
  106. }
  107. /// <summary>
  108. /// 图像接收超时时间30s
  109. /// </summary>
  110. private double Timeout = 30;
  111. #endregion
  112. #region 事件
  113. public event Action<ICogImage, TimeSpan, string,Guid> ImageCallbackEvent;
  114. public event Action<Guid, bool> CameraConnectChangedEvent;
  115. #endregion
  116. public SSZNCamera(Guid id, int index, string name, string serialNumber, string cameraip, bool isFindByIp)
  117. {
  118. ID = id;
  119. Name = serialNumber;
  120. Index = index;
  121. CameraIp = cameraip;
  122. SerialNumber = serialNumber;
  123. IsFindByIp = isFindByIp;
  124. IsConnected = false;
  125. }
  126. #region 方法
  127. /// <summary>
  128. /// 外部设置批处理点数(例如从 UI 的 PlcPoint.Camera_Data)
  129. /// </summary>
  130. /// <param name="batchPoints"></param>
  131. public void SetBatchPoints(int batchPoints)
  132. {
  133. // 保证线程安全
  134. //_operationSemaphore.Wait();
  135. try
  136. {
  137. try
  138. {
  139. // 如果 SDK 对象支持 BatchPoints 字段,则设置
  140. iSR7APi.BatchPoints = batchPoints;
  141. }
  142. catch { }
  143. try
  144. {
  145. // 将值写回相机配置(保持与 OpenDevice 一致的行为)
  146. iSR7APi.SetParams(0, (int)SAVEPOWEROFF.ESAPO_SAVE, -1, SR7IF_SETTING_ITEM.BATCH_POINT, batchPoints);
  147. //SR7LinkFunc.SR7IF_StartMeasureWithCallback(0, 1);
  148. }
  149. catch { }
  150. }
  151. finally
  152. {
  153. //_operationSemaphore.Release();
  154. }
  155. }
  156. /// <summary>
  157. /// 获取设备
  158. /// </summary>
  159. /// <returns></returns>
  160. public static CameraInfo[] GetDevices()
  161. {
  162. List<CameraInfo> cameras = new List<CameraInfo>();
  163. try
  164. {
  165. if (!CheckSoftwareInstalled().isInstalled)
  166. {
  167. LogHelper.WriteLogInfo("未安装MVS");
  168. return cameras.ToArray();
  169. }
  170. SR7ApiOneTimeCallbackImpl sR7Api = new SR7ApiOneTimeCallbackImpl();
  171. List<string> cameraIPs = new List<string>();
  172. if (!sR7Api.SearchCameraIP(out cameraIPs))
  173. {
  174. return cameras.ToArray();
  175. }
  176. else
  177. {
  178. for (int i = 0; i < cameraIPs.Count; i++)
  179. {
  180. cameras.Add(new CameraInfo()
  181. {
  182. CameraNo = i + 1,
  183. CameraName = "SSZN_" + cameraIPs[i],
  184. CameraBrand = CameraBrand.SSZN,
  185. CameraType = CameraType.GIGE,
  186. ManufacturerName = "SSZN",
  187. Model = "SSZN_Model",
  188. SerialNumber = "SSZN_SerialNumber",
  189. CameraIp = cameraIPs[i],
  190. IsFindByIp = true,
  191. });
  192. }
  193. }
  194. }
  195. catch (Exception ex)
  196. {
  197. LogHelper.WriteLogError("搜索深视3D相机列表时出错!", ex);
  198. }
  199. return cameras.ToArray();
  200. }
  201. /// <summary>
  202. /// 检查相机软件是否安装
  203. /// </summary>
  204. /// <returns></returns>
  205. public static (bool isInstalled, string version) CheckSoftwareInstalled()
  206. {
  207. return (true, "");
  208. }
  209. /// <summary>
  210. /// 打开相机
  211. /// </summary>
  212. /// <returns></returns>
  213. /// <exception cref="Exception"></exception>
  214. public bool OpenDevice()
  215. {
  216. //_operationSemaphore.Wait();
  217. try
  218. {
  219. if (!iSR7APi.CameraBOnline)
  220. {
  221. //SR7Link.ErrConnectCallBack ErrConnectDelegate = new SR7Link.ErrConnectCallBack(ErrConnectFunc);
  222. //ErrConnectDelegate = new ErrConnectCallBack(ErrConnectFunc);
  223. //int nOpenRet = iSR7APi.Open(Index - 1, CameraIp, 2000, ErrConnectDelegate);
  224. if(_errConnectDelegate==null)
  225. {
  226. _errConnectDelegate=new ErrConnectCallBack(ErrConnectFunc);
  227. }
  228. int nOpenRet = iSR7APi.Open(Index - 1, CameraIp, 2000, _errConnectDelegate);
  229. if (nOpenRet == (int)SR7Link.SR7IF_ERROR.SR7IF_OK)
  230. {
  231. //设置相机参数,否则无法取图 / Set the camera parameters, otherwise you will not be able to take pictures
  232. //一次回调和无限回调可以设置批处理测量On,批处理数据接收无和循环 / One-time callback and infinite callback can set batch measurement On, batch data receiving None and loop
  233. //异步回调必须在Ed软件中设置 / Asynchronous callbacks must be set in the EdgeImaging software
  234. int nReadBastchValue = -1;
  235. int nSetParamRet = -1;
  236. int getParamRet = iSR7APi.GetParams(Index - 1, -1, SR7IF_SETTING_ITEM.BATCH_ON_OFF, out nReadBastchValue);
  237. if (nReadBastchValue != 1)
  238. {
  239. nSetParamRet = iSR7APi.SetParams(Index - 1, (int)SAVEPOWEROFF.ESAPO_SAVE, -1, SR7IF_SETTING_ITEM.BATCH_ON_OFF, 1);
  240. LogHelper.WriteLogInfo($"Set Batch On Off: {nSetParamRet}");
  241. }
  242. int _BatchPoints = 0;
  243. getParamRet = iSR7APi.GetParams(Index - 1, -1, SR7IF_SETTING_ITEM.BATCH_POINT, out _BatchPoints);
  244. iSR7APi.BatchPoints = _BatchPoints;
  245. nSetParamRet = iSR7APi.SetParams(Index - 1, (int)SAVEPOWEROFF.ESAPO_SAVE, -1, SR7IF_SETTING_ITEM.CYCLICAL_PATTERN, 0);
  246. int nSetParamRet1 = iSR7APi.SetParams(Index - 1, (int)SAVEPOWEROFF.ESAPO_SAVE, -1, SR7IF_SETTING_ITEM.SEGMENT_BUFER, 0);
  247. LogHelper.WriteLogInfo($"Set Batch Data Receive: {nSetParamRet1}{nSetParamRet1}");
  248. GetDataDelegate = new SR7IFGetDataCallBack(GetDataCallBack);
  249. iSR7APi.Init(Index - 1, 0, 2000, GetDataDelegate);
  250. }
  251. LogHelper.WriteLogInfo($"Connect Camera {nOpenRet} {GetSDKErrMsgByCode(nOpenRet)}");
  252. }
  253. if (!IsConnected)
  254. {
  255. if (iSR7APi.CameraAOnline)
  256. {
  257. CameraConnectChangedEvent?.Invoke(ID, true);
  258. }
  259. }
  260. IsConnected = iSR7APi.CameraAOnline;
  261. return IsConnected;
  262. }
  263. finally
  264. {
  265. //_operationSemaphore.Release();
  266. }
  267. }
  268. /// <summary>
  269. /// 打开相机异步
  270. /// </summary>
  271. /// <returns></returns>
  272. public Task<bool> OpenDeviceAsync()
  273. {
  274. return Task.Run(() =>
  275. {
  276. return OpenDevice();
  277. });
  278. }
  279. /// <summary>
  280. /// 关闭相机
  281. /// </summary>
  282. public void CloseDevice()
  283. {
  284. // ch:关闭设备 | en:Close Device
  285. //_operationSemaphore.Wait();
  286. try
  287. {
  288. if (iSR7APi == null)
  289. {
  290. return;
  291. }
  292. iSR7APi.Stop();
  293. int nRet = iSR7APi.Close();
  294. LogHelper.WriteLogInfo($"Close Camera: {nRet}{GetSDKErrMsgByCode(nRet)}");
  295. }
  296. finally
  297. {
  298. //_operationSemaphore.Release();
  299. }
  300. }
  301. /// <summary>
  302. /// 采集图像(同步阻塞实现:发送一次启动,等待回调或超时,返回图像)
  303. /// </summary>
  304. /// <returns></returns>
  305. public ICogImage Grab(bool isRealtime=true)
  306. {
  307. // 采用同步阻塞方式实现,一次采集等待回调完成或超时返回
  308. //_operationSemaphore.Wait();
  309. try
  310. {
  311. if (!isRealtime)
  312. return Image;
  313. DateTime now = DateTime.Now;
  314. while (!CameraRevFinish)
  315. {
  316. Thread.Sleep(10);
  317. if (DateTime.Now.Subtract(now).TotalSeconds>Timeout)
  318. {
  319. LogHelper.WriteLogDebug("图像采集超时");
  320. return null;
  321. }
  322. }
  323. return Image;
  324. }
  325. catch (Exception ex)
  326. {
  327. LogHelper.WriteLogError("Grab 出错", ex);
  328. return null;
  329. }
  330. finally
  331. {
  332. _grabTcs = null;
  333. //_operationSemaphore.Release();
  334. }
  335. }
  336. #region Init Memory
  337. public void InitImageBufferMem(bool isExistCameraB, int nWidth, int nHeight)
  338. {
  339. int nTotalPoints = nWidth * nHeight;
  340. if (nTotalPoints <= 0 || nTotalPoints <= lastTotalPoints)
  341. {
  342. for (int i = 0; i < 2; i++)
  343. {
  344. for (int j = 0; j < nTotalPoints; j++)
  345. {
  346. ImgBuff32[i][j] = -1000000000; // 初始化为 -1000000000
  347. }
  348. for (int j = 0; j < nTotalPoints; j++)
  349. {
  350. ImgBuff16[i][j] = 0;
  351. GrayBuff[i][j] = 0;
  352. }
  353. for (int j = 0; j < nHeight; j++)
  354. {
  355. Encoder[i][j] = 0;
  356. }
  357. }
  358. if (nTotalPoints == lastTotalPoints)
  359. {
  360. return;
  361. }
  362. // 避免重复初始化 / Avoid repeated initialization
  363. }
  364. // 如果 nTotalPoints 发生变化,才重新分配内存
  365. // If nTotalPoints changes, reallocate memory
  366. FreeMemory();
  367. ImgBuff32 = new int[2][];
  368. ImgBuff16 = new short[2][];
  369. GrayBuff = new byte[2][];
  370. Encoder = new int[2][];
  371. for (int i = 0; i < 2; i++)
  372. {
  373. ImgBuff32[i] = new int[nTotalPoints]; // 32-bit 高度数据 / height data
  374. for (int j = 0; j < nTotalPoints; j++)
  375. {
  376. ImgBuff32[i][j] = -1000000000; // 初始化为 -1000000000
  377. }
  378. ImgBuff16[i] = new short[nTotalPoints]; // 16-bit 高度数据 / height data
  379. GrayBuff[i] = new byte[nTotalPoints]; // 灰度数据 / grayscale data
  380. Encoder[i] = new int[nHeight]; // 编码器数据 / Encoder data
  381. }
  382. lastTotalPoints = nTotalPoints;
  383. }
  384. public void FreeMemory()
  385. {
  386. if (ImgBuff32 != null)
  387. {
  388. ImgBuff32 = null;
  389. ImgBuff16 = null;
  390. GrayBuff = null;
  391. Encoder = null;
  392. lastTotalPoints = 0;
  393. GC.Collect();
  394. }
  395. }
  396. #endregion
  397. /// <summary>
  398. /// 开始采集图像
  399. /// </summary>
  400. public void StartGrabbing()
  401. {
  402. //lock (_stateLock)
  403. //{
  404. // if (IsGrabbing)
  405. // return;
  406. // IsGrabbing = true;
  407. //}
  408. //m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true };
  409. //m_hReceiveThread.Start();
  410. }
  411. /// <summary>
  412. /// 停止采集图像
  413. /// </summary>
  414. public void StopGrabbing()
  415. {
  416. //try
  417. //{
  418. // lock (_stateLock)
  419. // {
  420. // IsGrabbing = false;
  421. // }
  422. // Thread.Sleep(1000);
  423. // if (m_hReceiveThread != null)
  424. // {
  425. // m_hReceiveThread.Abort();
  426. // m_hReceiveThread = null;
  427. // }
  428. //}
  429. //catch (Exception)
  430. //{
  431. //}
  432. }
  433. /// <summary>
  434. /// 设置曝光时间
  435. /// </summary>
  436. /// <param name="ExposureTime"></param>
  437. /// <returns></returns>
  438. public bool SetExposureTime(float ExposureTime)
  439. {
  440. //_operationSemaphore.Wait();
  441. //try
  442. //{
  443. // if (!mvCameraAcq.bIsOpened)
  444. // return false;
  445. // mvCameraAcq.ExposureTime = (double)ExposureTime;
  446. // return true;
  447. //}
  448. //finally
  449. //{
  450. // _operationSemaphore.Release();
  451. //}
  452. return true;
  453. }
  454. /// <summary>
  455. /// 获取曝光时间
  456. /// </summary>
  457. /// <returns></returns>
  458. public float GetExposureTime()
  459. {
  460. //_operationSemaphore.Wait();
  461. //try
  462. //{
  463. // if (!mvCameraAcq.bIsOpened)
  464. // return 0;
  465. // return (float)mvCameraAcq.ExposureTime;
  466. //}
  467. //finally
  468. //{
  469. // _operationSemaphore.Release();
  470. //}
  471. return 0;
  472. }
  473. /// <summary>
  474. /// 设置增益
  475. /// </summary>
  476. /// <param name="Gain"></param>
  477. /// <returns></returns>
  478. public bool SetGain(float Gain)
  479. {
  480. //_operationSemaphore.Wait();
  481. //try
  482. //{
  483. // if (!mvCameraAcq.bIsOpened)
  484. // return false;
  485. // mvCameraAcq.AnalogGain = (double)Gain;
  486. // return true;
  487. //}
  488. //finally
  489. //{
  490. // _operationSemaphore.Release();
  491. //}
  492. return true;
  493. }
  494. /// <summary>
  495. /// 获取增益
  496. /// </summary>
  497. /// <returns></returns>
  498. public float GetGain()
  499. {
  500. //_operationSemaphore.Wait();
  501. //try
  502. //{
  503. // if (!mvCameraAcq.bIsOpened)
  504. // return 0;
  505. // return (float)mvCameraAcq.AnalogGain;
  506. //}
  507. //finally
  508. //{
  509. // _operationSemaphore.Release();
  510. //}
  511. return 0;
  512. }
  513. private void GetStreamThreadProc()
  514. {
  515. while (IsGrabbing)
  516. {
  517. try
  518. {
  519. Grab();
  520. ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage,ID);
  521. }
  522. catch (Exception)
  523. {
  524. }
  525. Thread.Sleep(10);
  526. }
  527. IsGrabbing = false;
  528. }
  529. /// <summary>
  530. ///
  531. /// </summary>
  532. /// <param name="nProfileWidth">单条轮廓宽度数据 / Returns a single contour width data</param>
  533. /// <param name="nHighlen">返回的批处理行数 / The number of rows in the batch returned</param>
  534. /// <param name="nFlag">回调函数执行状态,根据不同模式自定义 / Callback function execution status, customized according to different modes</param>
  535. /// <param name="nStatusCode">错误码,0无错误 / Error code, 0 no error</param>
  536. /// <param name="ProfileBits">Sync callback 0:32bit data, 1:16bit data</param>
  537. public void GetDataCallBack(int nProfileWidth, int nHighlen, int nFlag, int nStatusCode, int ProfileBits)
  538. {
  539. profile16Bits = (uint)ProfileBits;
  540. if (nStatusCode == 0)
  541. {
  542. Console.WriteLine($"Into GetDataFunc W:{nProfileWidth},H:{nHighlen},ErrCode:{nStatusCode}({GetSDKErrMsgByCode(nStatusCode)})");
  543. //这里拿到相机数据做显示,可以根据其他具体业务实现自己的逻辑
  544. //The camera data is obtained here for display, and you can implement your own logic according to other specific businesses
  545. int nTempWidth = nProfileWidth;// iSR7APi.GetProfileDataWidth();
  546. //双相机时,一次回调和异步回调nProfileWidth=3200,无限循环回调nProfileWidth=6400
  547. //For dual cameras, nProfileWidth=3200 for one-time callback and asynchronous callback, and nProfileWidth=6400 for infinite loop callback
  548. //if (iSR7APi.CameraBOnline && m_callbackMode == 2)//双相机 / dual camera
  549. // nTempWidth /= 2;
  550. int offset = coutCallbackPoints * nTempWidth;
  551. //int offset = 0;
  552. //iSR7APi.BatchPoints = nHighlen;
  553. SImagePro.SPointCloudHead pcHead = new SImagePro.SPointCloudHead(0, 0, 0, 0, 0);
  554. pcHead.width = (uint)nTempWidth;
  555. pcHead.height = (uint)iSR7APi.BatchPoints;
  556. pcHead.xInterval = iSR7APi.GetProfileData_XPitch();
  557. pcHead.yInterval = iSR7APi.GetProfileData_XPitch();
  558. //if (coutCallbackPoints != coutCallbackPoints_B)
  559. //{
  560. InitImageBufferMem(iSR7APi.CameraAOnline, nProfileWidth, iSR7APi.BatchPoints);
  561. // //ShowRGBImage(ImgBuff32[0], pcHead, pictureBoxA);
  562. //}
  563. //else if(coutCallbackPoints==0)
  564. //{
  565. // InitImageBufferMem(iSR7APi.CameraAOnline, nProfileWidth, iSR7APi.BatchPoints);
  566. //}
  567. // coutCallbackPoints_B = coutCallbackPoints;
  568. if (ProfileBits == 0)
  569. {
  570. //nHighlen = iSR7APi.BatchPoints;
  571. int[] tempHeightDataA = new int[nTempWidth * nHighlen];
  572. byte[] tempGrayDataA = new byte[nTempWidth * nHighlen];
  573. iSR7APi.GetData(tempHeightDataA, tempGrayDataA, Encoder[0], (int)pcHead.width, (int)nHighlen, 0);
  574. Array.Copy(tempHeightDataA, 0, ImgBuff32[0], 0, nTempWidth * nHighlen);
  575. Array.Copy(tempGrayDataA, 0, GrayBuff[0], 0, nTempWidth * nHighlen);
  576. if (ImgBuff32 != null && ImgBuff32.Length != 0 && ImgBuff32[0] != null)
  577. {
  578. //ShowRGBImage(ImgBuff32[0], pcHead, pictureBoxA);
  579. CogImage16Range cogImage16Range = SSZNCognexParser.SSZNParser.LoadSSZN3DImage(ImgBuff32[0], (int)pcHead.width, (int)pcHead.height, pcHead.xInterval, pcHead.yInterval);
  580. Image = cogImage16Range;
  581. CameraRevFinish = true;
  582. ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage, ID);
  583. }
  584. }
  585. else
  586. {
  587. short[] temp16bitDataA = new short[nTempWidth * nHighlen];
  588. byte[] tempGrayDataA = new byte[nTempWidth * nHighlen];
  589. iSR7APi.GetData(temp16bitDataA, tempGrayDataA, Encoder[0], (int)pcHead.width, (int)nHighlen, 0);
  590. Array.Copy(temp16bitDataA, 0, ImgBuff16[0], offset, nTempWidth * nHighlen);
  591. Array.Copy(tempGrayDataA, 0, GrayBuff[0], offset, nTempWidth * nHighlen);
  592. int[] showtemp16bitDataA = new int[pcHead.width * pcHead.height];
  593. //ShowTiff16Data(ImgBuff16[0], showtemp16bitDataA);
  594. if (ImgBuff16 != null && ImgBuff16.Length != 0 && ImgBuff16[0] != null)
  595. {
  596. //ShowRGBImage(showtemp16bitDataA, pcHead, pictureBoxA);
  597. }
  598. }
  599. if (iSR7APi.CameraBOnline && ImgBuff32[1] != null)
  600. {
  601. if (ProfileBits == 0)
  602. {
  603. int[] tempHeightDataB = new int[nTempWidth * nHighlen];
  604. byte[] tempGrayDataB = new byte[nTempWidth * nHighlen];
  605. iSR7APi.GetData(tempHeightDataB, tempGrayDataB, Encoder[1], (int)pcHead.width, (int)nHighlen, 1);
  606. Array.Copy(tempHeightDataB, 0, ImgBuff32[1], offset, nTempWidth * nHighlen);
  607. Array.Copy(tempGrayDataB, 0, GrayBuff[1], offset, nTempWidth * nHighlen);
  608. //ShowRGBImage(ImgBuff32[1], pcHead, pictureBoxB);
  609. }
  610. else
  611. {
  612. short[] tempHeightDataB = new short[nTempWidth * nHighlen];
  613. byte[] tempGrayDataB = new byte[nTempWidth * nHighlen];
  614. iSR7APi.GetData(tempHeightDataB, tempGrayDataB, Encoder[1], (int)pcHead.width, (int)nHighlen, 1);
  615. Array.Copy(tempHeightDataB, 0, ImgBuff16[1], offset, nTempWidth * nHighlen);
  616. Array.Copy(tempGrayDataB, 0, GrayBuff[1], offset, nTempWidth * nHighlen);
  617. int[] showtemp16bitDataB = new int[pcHead.width * pcHead.height];
  618. //ShowTiff16Data(ImgBuff16[1], showtemp16bitDataB);
  619. //ShowRGBImage(showtemp16bitDataB, pcHead, pictureBoxB);
  620. }
  621. }
  622. coutCallbackPoints += nHighlen;
  623. }
  624. else
  625. {
  626. Console.WriteLine($"Data CallBack Exception:{nStatusCode}({GetSDKErrMsgByCode(nStatusCode)})");
  627. }
  628. }
  629. public void ErrConnectFunc(int dwDeviceId, int nErrCode)
  630. {
  631. LogHelper.WriteLogInfo($"Into ConnectExceptionCallback Error Code: {nErrCode}{GetSDKErrMsgByCode(nErrCode)}");
  632. iSR7APi.CameraAOnline = false;
  633. iSR7APi.CameraBOnline = false;
  634. //:1:Data overflow,3:Disconnect, 4:Wrong version
  635. //Non-asynchronous mode: -1 represents a general error, such as link failure, setup failure, data acquisition failure, etc., -1000;
  636. switch (nErrCode)
  637. {
  638. case 1:
  639. LogHelper.WriteLogInfo($"Into ConnectExceptionCallback Error Code: {nErrCode}{srcsharpTools.GetTranslation("CAMERA_EXCEPTION_1")}");
  640. break;
  641. case 3:
  642. LogHelper.WriteLogInfo($"Into ConnectExceptionCallback Error Code: {nErrCode}{srcsharpTools.GetTranslation("CAMERA_EXCEPTION_3")}");
  643. break;
  644. case 4:
  645. LogHelper.WriteLogInfo($"Into ConnectExceptionCallback Error Code: {nErrCode}{srcsharpTools.GetTranslation("CAMERA_EXCEPTION_3")}");
  646. break;
  647. case -1:
  648. LogHelper.WriteLogInfo($"Into ConnectExceptionCallback Error Code: {nErrCode}{srcsharpTools.GetTranslation("CAMERA_EXCEPTION_N1")}");
  649. break;
  650. default:
  651. break;
  652. }
  653. }
  654. public string GetSDKErrMsgByCode(int nErrCode)
  655. {
  656. string strErrMsg;
  657. switch ((SR7Link.SR7IF_ERROR)nErrCode)
  658. {
  659. case SR7IF_ERROR.SR7IF_ERROR_NOT_FOUND: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_NOT_FOUND"); break;
  660. case SR7IF_ERROR.SR7IF_ERROR_COMMAND: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_COMMAND"); break;
  661. case SR7IF_ERROR.SR7IF_ERROR_PARAMETER: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_PARAMETER"); break;
  662. case SR7IF_ERROR.SR7IF_ERROR_UNIMPLEMENTED: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_UNIMPLEMENTED"); break;
  663. case SR7IF_ERROR.SR7IF_ERROR_HANDLE: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_HANDLE"); break;
  664. case SR7IF_ERROR.SR7IF_ERROR_MEMORY: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_MEMORY"); break;
  665. case SR7IF_ERROR.SR7IF_ERROR_TIMEOUT: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_TIMEOUT"); break;
  666. case SR7IF_ERROR.SR7IF_ERROR_DATABUFFER: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_DATABUFFER"); break;
  667. case SR7IF_ERROR.SR7IF_ERROR_STREAM: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_STREAM"); break;
  668. case SR7IF_ERROR.SR7IF_ERROR_CLOSED: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_CLOSED"); break;
  669. case SR7IF_ERROR.SR7IF_ERROR_VERSION: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_VERSION"); break;
  670. case SR7IF_ERROR.SR7IF_ERROR_ABORT: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_ABORT"); break;
  671. case SR7IF_ERROR.SR7IF_ERROR_ALREADY_EXISTS: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_ALREADY_EXISTS"); break;
  672. case SR7IF_ERROR.SR7IF_ERROR_FRAME_LOSS: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_FRAME_LOSS"); break;
  673. case SR7IF_ERROR.SR7IF_ERROR_ROLL_DATA_OVERFLOW: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_ROLL_DATA_OVERFLOW"); break;
  674. case SR7IF_ERROR.SR7IF_ERROR_ROLL_BUSY: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_ROLL_BUSY"); break;
  675. case SR7IF_ERROR.SR7IF_ERROR_MODE: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_MODE"); break;
  676. case SR7IF_ERROR.SR7IF_ERROR_CAMERA_NOT_ONLINE: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR_CAMERA_NOT_ONLINE"); break;
  677. case SR7IF_ERROR.SR7IF_ERROR: strErrMsg = srcsharpTools.GetTranslation("SR7IF_ERROR"); break;
  678. case SR7IF_ERROR.SR7IF_NORMAL_STOP: strErrMsg = srcsharpTools.GetTranslation("SR7IF_NORMAL_STOP"); break;
  679. case SR7IF_ERROR.SR7IF_OK: strErrMsg = ""; break;
  680. default:
  681. strErrMsg = "";
  682. break;
  683. }
  684. return strErrMsg;
  685. }
  686. #endregion
  687. #region 属性通知
  688. /// <summary>
  689. /// Occurs when a property value changes.
  690. /// </summary>
  691. public event PropertyChangedEventHandler PropertyChanged;
  692. /// <summary>
  693. /// Checks if a property already matches a desired value. Sets the property and
  694. /// notifies listeners only when necessary.
  695. /// </summary>
  696. /// <typeparam name="T">Type of the property.</typeparam>
  697. /// <param name="storage">Reference to a property with both getter and setter.</param>
  698. /// <param name="value">Desired value for the property.</param>
  699. /// <param name="propertyName">Name of the property used to notify listeners. This
  700. /// value is optional and can be provided automatically when invoked from compilers that
  701. /// support CallerMemberName.</param>
  702. /// <returns>True if the value was changed, false if the existing value matched the
  703. /// desired value.</returns>
  704. protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
  705. {
  706. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  707. storage = value;
  708. RaisePropertyChanged(propertyName);
  709. return true;
  710. }
  711. /// <summary>
  712. /// Checks if a property already matches a desired value. Sets the property and
  713. /// notifies listeners only when necessary.
  714. /// </summary>
  715. /// <typeparam name="T">Type of the property.</typeparam>
  716. /// <param name="storage">Reference to a property with both getter and setter.</param>
  717. /// <param name="value">Desired value for the property.</param>
  718. /// <param name="propertyName">Name of the property used to notify listeners. This
  719. /// value is optional and can be provided automatically when invoked from compilers that
  720. /// support CallerMemberName.</param>
  721. /// <param name="onChanged">Action that is called after the property value has been changed.</param>
  722. /// <returns>True if the value was changed, false if the existing value matched the
  723. /// desired value.</returns>
  724. protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
  725. {
  726. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  727. storage = value;
  728. onChanged?.Invoke();
  729. RaisePropertyChanged(propertyName);
  730. return true;
  731. }
  732. /// <summary>
  733. /// Raises this object's PropertyChanged event.
  734. /// </summary>
  735. /// <param name="propertyName">Name of the property used to notify listeners. This
  736. /// value is optional and can be provided automatically when invoked from compilers
  737. /// that support <see cref="CallerMemberNameAttribute"/>.</param>
  738. protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
  739. {
  740. OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
  741. }
  742. /// <summary>
  743. /// Raises this object's PropertyChanged event.
  744. /// </summary>
  745. /// <param name="args">The PropertyChangedEventArgs</param>
  746. protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
  747. {
  748. PropertyChanged?.Invoke(this, args);
  749. }
  750. #endregion
  751. }
  752. }