您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

784 行
33 KiB

  1. //#define Defect3
  2. //#define OpenSizeDefectComp
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Reflection;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. using MaiMuAOI.SysCtrl;
  15. using MaiMuControl.Device;
  16. using Microsoft.ML.OnnxRuntime;
  17. using Microsoft.ML.OnnxRuntime.Tensors;
  18. using Newtonsoft.Json;
  19. using OpenCvSharp;
  20. using Yolo5;
  21. namespace MaiMuAOI.ImageProcessing
  22. {
  23. public class DefectLib : IDisposable
  24. {
  25. public Action<WarningEnum, string> WarningEvent;
  26. /// <summary>
  27. /// 检测结果JSON(原图,结果)
  28. /// </summary>
  29. public Action<DefectTask> finishEvent;
  30. /// <summary>
  31. /// 是否打开设备成功
  32. /// </summary>
  33. public bool IsInit { get; private set; } = false;
  34. //private System.Timers.Timer timer = new System.Timers.Timer();
  35. private Yolo_Class yolo1;
  36. private InferenceSession _onnxSession;
  37. private Yolo_Class yolo2;
  38. private InferenceSession _onnxSession2;
  39. private Yolo_Class yolo3;
  40. private InferenceSession _onnxSession3;
  41. //
  42. private Thread t_task, t_task_operation, t_task_operation2, t_task_operation3, t_task_tag;
  43. //=======task list
  44. private List<DefectTask> taskList = new List<DefectTask>();
  45. private List<DefectTask> taskOperationList = new List<DefectTask>();
  46. private List<DefectTask> taskTagList = new List<DefectTask>();
  47. public DefectLib()
  48. {
  49. }
  50. public bool start()
  51. {
  52. try
  53. {
  54. yolo1 = new Yolo_Class();
  55. yolo2 = new Yolo_Class();
  56. #if Defect3
  57. yolo3 = new Yolo_Class();
  58. #endif
  59. //加载模型(只加载一次即可)
  60. //string modelFilePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DevCfg\\best.onnx";
  61. //_onnxSession = yolo1.LoadModel(modelFilePath, true);//false-CPU true-显卡
  62. IsInit = true;
  63. //timer.Elapsed += Timer_Elapsed;
  64. //timer.Interval = 100;
  65. //timer.Enabled = true;
  66. taskList.Clear();
  67. taskOperationList.Clear();
  68. taskTagList.Clear();
  69. //MessageBox.Show("11");
  70. t_task = new System.Threading.Thread(runStep);
  71. t_task.IsBackground = true;
  72. t_task.Start();
  73. //MessageBox.Show("22");
  74. t_task_operation = new System.Threading.Thread(run2);
  75. t_task_operation.IsBackground = true;
  76. t_task_operation.Start();
  77. //MessageBox.Show("33");
  78. t_task_operation2 = new System.Threading.Thread(run3);
  79. t_task_operation2.IsBackground = true;
  80. t_task_operation2.Start();
  81. //MessageBox.Show("44");
  82. #if Defect3
  83. t_task_operation3 = new System.Threading.Thread(run4);
  84. t_task_operation3.IsBackground = true;
  85. t_task_operation3.Start();
  86. #endif
  87. //MessageBox.Show("55");
  88. return true;
  89. }
  90. catch (Exception ex)
  91. {
  92. WarningEvent?.Invoke(WarningEnum.High, ex.Message);
  93. return false;
  94. }
  95. }
  96. public void stop()
  97. {
  98. if (!IsInit) return;
  99. try
  100. {
  101. IsInit = false;
  102. //timer.Elapsed -= Timer_Elapsed;
  103. //释放模型
  104. if (_onnxSession != null)
  105. {
  106. _onnxSession.Dispose();
  107. _onnxSession = null;
  108. }
  109. if (_onnxSession2 != null)
  110. {
  111. _onnxSession2.Dispose();
  112. _onnxSession2 = null;
  113. }
  114. #if Defect3
  115. if (_onnxSession3 != null)
  116. {
  117. _onnxSession3.Dispose();
  118. _onnxSession3 = null;
  119. }
  120. #endif
  121. _preLoadONNXFilePath = null;
  122. if (t_task != null)
  123. {
  124. bool b = t_task.Join(5000);
  125. if (!b) t_task.Abort();
  126. t_task = null;
  127. }
  128. if (t_task_operation != null)
  129. {
  130. bool b = t_task_operation.Join(5000);
  131. if (!b) t_task_operation.Abort();
  132. t_task_operation = null;
  133. }
  134. if (t_task_operation2 != null)
  135. {
  136. bool b = t_task_operation2.Join(5000);
  137. if (!b) t_task_operation2.Abort();
  138. t_task_operation2 = null;
  139. }
  140. #if Defect3
  141. if (t_task_operation3 != null)
  142. {
  143. bool b = t_task_operation3.Join(5000);
  144. if (!b) t_task_operation3.Abort();
  145. t_task_operation3 = null;
  146. }
  147. #endif
  148. if (t_task_tag != null)
  149. {
  150. bool b = t_task_tag.Join(5000);
  151. if (!b) t_task_tag.Abort();
  152. t_task_tag = null;
  153. }
  154. taskList.Clear();
  155. taskOperationList.Clear();
  156. taskTagList.Clear();
  157. }
  158. catch { }
  159. }
  160. private string _preLoadONNXFilePath;//记录上次成功加载的模型,不重复加载
  161. public void loadModelFile(string onnxFilePath)
  162. {
  163. try
  164. {
  165. //string modelFilePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DevCfg\\best.onnx";
  166. //不重复加载
  167. if (!string.IsNullOrWhiteSpace(_preLoadONNXFilePath) && _preLoadONNXFilePath.ToLower() == onnxFilePath.ToLower())
  168. return;
  169. //MessageBox.Show("1");
  170. //Task.Run(async () =>
  171. //{
  172. // if (_onnxSession != null)
  173. // {
  174. // _onnxSession.Dispose();
  175. // _onnxSession = null;
  176. // }
  177. // _onnxSession = yolo1.LoadModel(onnxFilePath, true);//false-CPU true-显卡
  178. // _preLoadONNXFilePath = onnxFilePath;
  179. //});
  180. if (_onnxSession != null)
  181. {
  182. _onnxSession.Dispose();
  183. _onnxSession = null;
  184. }
  185. _onnxSession = yolo1.LoadModel(onnxFilePath, true);//false-CPU true-显卡
  186. //MessageBox.Show("2");
  187. if (_onnxSession2 != null)
  188. {
  189. _onnxSession2.Dispose();
  190. _onnxSession2 = null;
  191. }
  192. _onnxSession2 = yolo2.LoadModel(onnxFilePath, true);//false-CPU true-显卡
  193. #if Defect3
  194. //MessageBox.Show("3");
  195. if (_onnxSession3 != null)
  196. {
  197. _onnxSession3.Dispose();
  198. _onnxSession3 = null;
  199. }
  200. _onnxSession3 = yolo3.LoadModel(onnxFilePath, true);//false-CPU true-显卡
  201. #endif
  202. //MessageBox.Show("4");
  203. _preLoadONNXFilePath = onnxFilePath;
  204. }
  205. catch (Exception ex)
  206. {
  207. MessageBox.Show(ex.Message);
  208. }
  209. }
  210. /// <summary>
  211. /// 保存图片
  212. /// </summary>
  213. /// <param name="Img"></param>图片
  214. /// <param name="pictureUrl"></param>保存路径
  215. /// <param name="pictureName"></param>保存名称
  216. private void SaveImage(Bitmap Img, string pictureUrl, string pictureName)
  217. {
  218. if (!Directory.Exists(pictureUrl))
  219. {
  220. Directory.CreateDirectory(pictureUrl);
  221. }
  222. FileInfo FileUrl = new FileInfo(pictureUrl);//防止路径中有日期导致路径错误
  223. try
  224. {
  225. using (Bitmap bitmap = new Bitmap(Img))
  226. {
  227. using (MemoryStream stream = new MemoryStream())
  228. {
  229. bitmap.Save(stream, ImageFormat.Bmp);
  230. System.Drawing.Image img = System.Drawing.Image.FromStream(stream);
  231. //img.Save(FileUrl +"\\"+ pictureName);
  232. //img.Dispose();
  233. string szURL = FileUrl + "\\" + pictureName;
  234. img.Save(szURL, ImageFormat.Bmp);
  235. img.Dispose();
  236. }
  237. }
  238. }
  239. catch (Exception)
  240. {
  241. if (Img != null)
  242. {
  243. Img.Dispose();
  244. }
  245. }
  246. }
  247. private void runStep()
  248. {
  249. while (IsInit)
  250. {
  251. if (taskList.Count < 1 || _onnxSession == null)
  252. {
  253. Thread.Sleep(5);
  254. continue;
  255. }
  256. //
  257. var task = pop();
  258. try
  259. {
  260. if (task != null)
  261. {
  262. Stopwatch stopwatch = Stopwatch.StartNew();
  263. //源图
  264. //Bitmap bmp = yolo1.Read2Bmp(file_path);
  265. //切割图像,输入图像格式14208*10640
  266. stopwatch.Start();
  267. task.bmps_cut = yolo1.OpenCVToCutsMat(task.bmp, task.cut_size.Width, task.cut_size.Height);
  268. stopwatch.Stop();
  269. task.stopwatch[0] = stopwatch.ElapsedMilliseconds;
  270. //Resize图像
  271. stopwatch.Restart();
  272. task.bmps_resize = yolo1.OpenCVToResizesMat(task.bmps_cut, task.resize.Width, task.resize.Height);
  273. stopwatch.Stop();
  274. task.stopwatch[1] = stopwatch.ElapsedMilliseconds;
  275. //预处理模型
  276. stopwatch.Restart();
  277. task.tensors = yolo1.PreprocessImageMat(task.bmps_resize);
  278. stopwatch.Stop();
  279. task.stopwatch[2] = stopwatch.ElapsedMilliseconds;
  280. lock (taskOperationList)
  281. taskOperationList.Add(task);
  282. }
  283. Thread.Sleep(5);
  284. }
  285. catch (Exception ex)
  286. {
  287. WarningEvent?.Invoke(WarningEnum.Low, "DefectLib task1 err:" + ex.Message);
  288. task.isSucceed = false;
  289. task.resultInfo = ex.Message;
  290. callback(task);
  291. }
  292. }
  293. }
  294. private void run2()
  295. {
  296. while (IsInit)
  297. {
  298. if (taskOperationList.Count < 1)
  299. {
  300. Thread.Sleep(5);
  301. continue;
  302. }
  303. //
  304. var task = pop2();
  305. int liStep = 0;
  306. try
  307. {
  308. if (task != null)
  309. {
  310. Stopwatch stopwatch = Stopwatch.StartNew();
  311. //====运行推理(必需单队列)
  312. WarningEvent?.Invoke(WarningEnum.Normal, $"DefectLib task2 进入推理:{task.modelType}-{task.thresholds}, {task.thresholdsClass}, {JsonConvert.SerializeObject(task.recAreaThreshold)}");
  313. stopwatch.Start();
  314. IDisposableReadOnlyCollection<DisposableNamedOnnxValue>[] results = yolo1.RunModlel(_onnxSession, task.tensors);
  315. liStep = 1;
  316. if (task.modelType == "rj")
  317. task.informationList = yolo1.ScreeningResults_YD_RJ(results, task.bmps_resize, task.thresholds, task.thresholdsClass, task.recAreaThreshold);
  318. else
  319. task.informationList = yolo1.ScreeningResults_YD(results, task.bmps_resize, task.thresholds, task.thresholdsClass, task.recAreaThreshold);
  320. liStep = 2;
  321. //当前大图上缺陷个数
  322. int currPicDefectCount = 0;
  323. for (int x = 0; x < task.informationList.Count(); x++)
  324. currPicDefectCount += task.informationList[x].Count();
  325. task.defectCount = currPicDefectCount;
  326. stopwatch.Stop();
  327. task.stopwatch[3] = stopwatch.ElapsedMilliseconds;
  328. liStep = 3;
  329. if (task.informationList.Count > 0)
  330. {
  331. liStep = 4;
  332. //lock (taskTagList)
  333. // taskTagList.Add(task);
  334. //====打标 ,有缺陷返回缺陷图片数组,没缺陷返回所有图片数组
  335. stopwatch.Restart();
  336. #if OpenSizeDefectComp
  337. task.bmps_tag = yolo1.DrawYoloPrediction2Mat(task.bmps_cut, task.informationList, 27, SixLabors.ImageSharp.Color.OrangeRed, task.resize.Width,
  338. task.Xmm, task.Ymm, out task.defectInfor2RestorationDesk, out task.defectInfor2BigImage);
  339. #else
  340. task.bmps_tag = yolo1.DrawYoloPrediction2Mat(task.bmps_cut, task.informationList, 27, SixLabors.ImageSharp.Color.OrangeRed, task.resize.Width,
  341. task.Xmm, task.Ymm, out task.defectInfor2RestorationDesk);
  342. #endif
  343. liStep = 5;
  344. //List<List<string>> SizedefectInfor2RestorationDesk = SysMgr.Instance.GetSizeDefectData(task.Xmm, task.Ymm);
  345. //task.defectInfor2RestorationDesk = yolo3.FilteringOverlappingDefects(task.defectInfor2RestorationDesk, SizedefectInfor2RestorationDesk);
  346. //liStep = 51;
  347. if (ConfMgr.Instance.SysConfigParams.OpenFlawDistribution)
  348. {
  349. //大图缺陷坐标转换到图纸坐标
  350. if (!string.IsNullOrWhiteSpace(task.drawingPagePath) && task.defectInfor2RestorationDesk != null && task.defectInfor2RestorationDesk.Count > 0)
  351. task.defectInfor2RestorationDeskPage = yolo1.DefectDrawGerberImage(task.drawingPagePath, task.defectInfor2RestorationDesk);
  352. }
  353. stopwatch.Stop();
  354. task.stopwatch[4] = stopwatch.ElapsedMilliseconds;
  355. liStep = 6;
  356. task.bmpCompress = yolo1.ResizesMat_4(task.bmp);
  357. //if (!ConfMgr.Instance.SysConfigParams.OpenColorB)
  358. // task.bmpCompress = yolo1.ResizesMat_4(task.bmp);
  359. //else
  360. // task.bmpCompress = yolo1.ResizesMat_4(task.srcbmp);
  361. task.isSucceed = true;
  362. callback(task);
  363. }
  364. else
  365. {
  366. task.isSucceed = true;
  367. callback(task);
  368. }
  369. }
  370. Thread.Sleep(5);
  371. }
  372. catch (Exception ex)
  373. {
  374. WarningEvent?.Invoke(WarningEnum.Low, $"DefectLib task2 err({liStep}):" + ex.Message + $"||{task.modelType}-{task.thresholds}, {task.thresholdsClass}, {JsonConvert.SerializeObject(task.recAreaThreshold)}");
  375. task.isSucceed = false;
  376. task.resultInfo = ex.Message;
  377. callback(task);
  378. }
  379. }
  380. }
  381. private void run3()
  382. {
  383. while (IsInit)
  384. {
  385. if (taskOperationList.Count < 1)
  386. {
  387. Thread.Sleep(5);
  388. continue;
  389. }
  390. //
  391. var task = pop2();
  392. int liStep = 0;
  393. try
  394. {
  395. if (task != null)
  396. {
  397. Stopwatch stopwatch = Stopwatch.StartNew();
  398. //====运行推理(必需单队列)
  399. WarningEvent?.Invoke(WarningEnum.Normal, $"DefectLib task3 进入推理:{task.modelType}-{task.thresholds}, {task.thresholdsClass}, {JsonConvert.SerializeObject(task.recAreaThreshold)}");
  400. stopwatch.Start();
  401. IDisposableReadOnlyCollection<DisposableNamedOnnxValue>[] results = yolo2.RunModlel(_onnxSession2, task.tensors);
  402. liStep = 1;
  403. if (task.modelType == "rj")
  404. task.informationList = yolo2.ScreeningResults_YD_RJ(results, task.bmps_resize, task.thresholds, task.thresholdsClass, task.recAreaThreshold);
  405. else
  406. task.informationList = yolo2.ScreeningResults_YD(results, task.bmps_resize, task.thresholds, task.thresholdsClass, task.recAreaThreshold);
  407. liStep = 2;
  408. //当前大图上缺陷个数
  409. int currPicDefectCount = 0;
  410. for (int x = 0; x < task.informationList.Count(); x++)
  411. currPicDefectCount += task.informationList[x].Count();
  412. task.defectCount = currPicDefectCount;
  413. stopwatch.Stop();
  414. task.stopwatch[3] = stopwatch.ElapsedMilliseconds;
  415. liStep = 3;
  416. if (task.informationList.Count > 0)
  417. {
  418. liStep = 4;
  419. //lock (taskTagList)
  420. // taskTagList.Add(task);
  421. //====打标 ,有缺陷返回缺陷图片数组,没缺陷返回所有图片数组
  422. stopwatch.Restart();
  423. #if OpenSizeDefectComp
  424. task.bmps_tag = yolo2.DrawYoloPrediction2Mat(task.bmps_cut, task.informationList, 27, SixLabors.ImageSharp.Color.OrangeRed, task.resize.Width,
  425. task.Xmm, task.Ymm, out task.defectInfor2RestorationDesk, out task.defectInfor2BigImage);
  426. #else
  427. task.bmps_tag = yolo2.DrawYoloPrediction2Mat(task.bmps_cut, task.informationList, 27, SixLabors.ImageSharp.Color.OrangeRed, task.resize.Width,
  428. task.Xmm, task.Ymm, out task.defectInfor2RestorationDesk);
  429. #endif
  430. liStep = 5;
  431. //List<List<string>> SizedefectInfor2RestorationDesk = SysMgr.Instance.GetSizeDefectData(task.Xmm, task.Ymm);
  432. //task.defectInfor2RestorationDesk = yolo3.FilteringOverlappingDefects(task.defectInfor2RestorationDesk, SizedefectInfor2RestorationDesk);
  433. //liStep = 51;
  434. if (ConfMgr.Instance.SysConfigParams.OpenFlawDistribution)
  435. {
  436. //大图缺陷坐标转换到图纸坐标
  437. if (!string.IsNullOrWhiteSpace(task.drawingPagePath) && task.defectInfor2RestorationDesk != null && task.defectInfor2RestorationDesk.Count > 0)
  438. task.defectInfor2RestorationDeskPage = yolo2.DefectDrawGerberImage(task.drawingPagePath, task.defectInfor2RestorationDesk);
  439. }
  440. stopwatch.Stop();
  441. task.stopwatch[4] = stopwatch.ElapsedMilliseconds;
  442. liStep = 6;
  443. task.bmpCompress = yolo2.ResizesMat_4(task.bmp);
  444. task.isSucceed = true;
  445. callback(task);
  446. }
  447. else
  448. {
  449. task.isSucceed = true;
  450. callback(task);
  451. }
  452. }
  453. Thread.Sleep(5);
  454. }
  455. catch (Exception ex)
  456. {
  457. WarningEvent?.Invoke(WarningEnum.Low, $"DefectLib task3 err({liStep}):" + ex.Message + $"||{task.modelType}-{task.thresholds}, {task.thresholdsClass}, {JsonConvert.SerializeObject(task.recAreaThreshold)}");
  458. task.isSucceed = false;
  459. task.resultInfo = ex.Message;
  460. callback(task);
  461. }
  462. }
  463. }
  464. private void run4()
  465. {
  466. while (IsInit)
  467. {
  468. if (taskOperationList.Count < 1)
  469. {
  470. Thread.Sleep(5);
  471. continue;
  472. }
  473. //
  474. var task = pop2();
  475. int liStep = 0;
  476. try
  477. {
  478. if (task != null)
  479. {
  480. Stopwatch stopwatch = Stopwatch.StartNew();
  481. //====运行推理(必需单队列)
  482. stopwatch.Start();
  483. IDisposableReadOnlyCollection<DisposableNamedOnnxValue>[] results = yolo3.RunModlel(_onnxSession3, task.tensors);
  484. liStep = 1;
  485. if (task.modelType == "rj")
  486. task.informationList = yolo3.ScreeningResults_YD_RJ(results, task.bmps_resize, task.thresholds, task.thresholdsClass, task.recAreaThreshold);
  487. else
  488. task.informationList = yolo3.ScreeningResults_YD(results, task.bmps_resize, task.thresholds, task.thresholdsClass, task.recAreaThreshold);
  489. liStep = 2;
  490. //当前大图上缺陷个数
  491. int currPicDefectCount = 0;
  492. for (int x = 0; x < task.informationList.Count(); x++)
  493. currPicDefectCount += task.informationList[x].Count();
  494. task.defectCount = currPicDefectCount;
  495. stopwatch.Stop();
  496. task.stopwatch[3] = stopwatch.ElapsedMilliseconds;
  497. liStep = 3;
  498. if (task.informationList.Count > 0)
  499. {
  500. liStep = 4;
  501. //lock (taskTagList)
  502. // taskTagList.Add(task);
  503. //====打标 ,有缺陷返回缺陷图片数组,没缺陷返回所有图片数组
  504. stopwatch.Restart();
  505. #if OpenSizeDefectComp
  506. task.bmps_tag = yolo3.DrawYoloPrediction2Mat(task.bmps_cut, task.informationList, 27, SixLabors.ImageSharp.Color.OrangeRed, task.resize.Width,
  507. task.Xmm, task.Ymm, out task.defectInfor2RestorationDesk, out task.defectInfor2BigImage);
  508. #else
  509. task.bmps_tag = yolo3.DrawYoloPrediction2Mat(task.bmps_cut, task.informationList, 27, SixLabors.ImageSharp.Color.OrangeRed, task.resize.Width,
  510. task.Xmm, task.Ymm, out task.defectInfor2RestorationDesk);
  511. #endif
  512. liStep = 5;
  513. //List<List<string>> SizedefectInfor2RestorationDesk = SysMgr.Instance.GetSizeDefectData(task.Xmm, task.Ymm);
  514. //task.defectInfor2RestorationDesk = yolo3.FilteringOverlappingDefects(task.defectInfor2RestorationDesk, SizedefectInfor2RestorationDesk);
  515. //liStep = 51;
  516. if (ConfMgr.Instance.SysConfigParams.OpenFlawDistribution)
  517. {
  518. //大图缺陷坐标转换到图纸坐标
  519. if (!string.IsNullOrWhiteSpace(task.drawingPagePath) && task.defectInfor2RestorationDesk != null && task.defectInfor2RestorationDesk.Count > 0)
  520. task.defectInfor2RestorationDeskPage = yolo3.DefectDrawGerberImage(task.drawingPagePath, task.defectInfor2RestorationDesk);
  521. }
  522. stopwatch.Stop();
  523. task.stopwatch[4] = stopwatch.ElapsedMilliseconds;
  524. liStep = 6;
  525. task.bmpCompress = yolo3.ResizesMat_4(task.bmp);
  526. task.isSucceed = true;
  527. callback(task);
  528. }
  529. else
  530. {
  531. task.isSucceed = true;
  532. callback(task);
  533. }
  534. }
  535. Thread.Sleep(5);
  536. }
  537. catch (Exception ex)
  538. {
  539. WarningEvent?.Invoke(WarningEnum.Low, $"DefectLib task4 err({liStep}):" + ex.Message);
  540. task.isSucceed = false;
  541. task.resultInfo = ex.Message;
  542. callback(task);
  543. }
  544. }
  545. }
  546. /// <summary>
  547. /// 已不用
  548. /// </summary>
  549. private void run5()
  550. {
  551. while (IsInit)
  552. {
  553. if (taskTagList.Count < 1)
  554. {
  555. Thread.Sleep(0);
  556. continue;
  557. }
  558. //
  559. var task = pop3();
  560. try
  561. {
  562. if (task != null)
  563. {
  564. Stopwatch stopwatch = Stopwatch.StartNew();
  565. //====打标 ,有缺陷返回缺陷图片数组,没缺陷返回所有图片数组
  566. stopwatch.Start();
  567. task.bmps_tag = yolo1.DrawYoloPrediction2Mat(task.bmps_cut, task.informationList, 27, SixLabors.ImageSharp.Color.OrangeRed, task.resize.Width,
  568. task.Xmm,task.Ymm,out task.defectInfor2RestorationDesk);
  569. stopwatch.Stop();
  570. task.stopwatch[4] = stopwatch.ElapsedMilliseconds;
  571. task.isSucceed = true;
  572. callback(task);
  573. }
  574. }
  575. catch (Exception ex)
  576. {
  577. WarningEvent?.Invoke(WarningEnum.Low, "DefectLib task3 err:" + ex.Message);
  578. task.isSucceed = false;
  579. task.resultInfo = ex.Message;
  580. callback(task);
  581. }
  582. }
  583. }
  584. private void callback(DefectTask task)
  585. {
  586. //返回成功/失败,异步调用
  587. if (task.finishEvent != null || (task.finishEvent = finishEvent) != null)
  588. //task.finishEvent.BeginInvoke(result, errInfo, res => task.finishEvent.EndInvoke(res), null);
  589. System.Threading.ThreadPool.QueueUserWorkItem(waitCallback, task);
  590. }
  591. //异步回调
  592. WaitCallback waitCallback = new WaitCallback(o =>
  593. {
  594. var task = (DefectTask)o;
  595. task.finishEvent(task);
  596. });
  597. public class DefectTask
  598. {
  599. public int stepIndex;
  600. public string processName;
  601. //2024 03 22 加入模型类型 rj pt;
  602. public string modelType;
  603. public string drawingPagePath;//图纸路径bmp
  604. //图索引
  605. public int index = 0;
  606. /// <summary>
  607. /// 绝对位置-----X2轴
  608. /// </summary>
  609. public double Xmm;
  610. /// <summary>
  611. /// 绝对位置-----Y轴
  612. /// </summary>
  613. public double Ymm;
  614. /// <summary>
  615. /// 源文件
  616. /// </summary>
  617. public Mat bmp;
  618. public Mat srcbmp;
  619. public Mat bmpCompress;//压缩有缺陷大图
  620. public System.Drawing.Size cut_size = new System.Drawing.Size(592, 532);
  621. public System.Drawing.Size resize = new System.Drawing.Size(224, 224);
  622. /// <summary>
  623. /// 阈值
  624. /// </summary>
  625. public float thresholds = 0.4f;
  626. /// <summary>
  627. /// 种类阈值
  628. /// </summary>
  629. public string thresholdsClass;
  630. /// <summary>
  631. /// 缺陷在面积内数量
  632. /// </summary>
  633. public Dictionary<string, float> recAreaThreshold;
  634. /// <summary>
  635. /// 完成后回调
  636. /// </summary>
  637. public Action<DefectTask> finishEvent;
  638. //
  639. public long createTime = DateTime.Now.Ticks;
  640. public DateTime nowTime;
  641. //中间变量,供step2使用
  642. public Mat[] bmps_cut;
  643. public Mat[] bmps_resize;
  644. //预处理模型
  645. public Tensor<float>[] tensors;
  646. //==结果返回
  647. public List<Dictionary<int, List<string>[]>> informationList;
  648. public int defectCount;//informationList中的缺陷数
  649. public List<List<string>> defectInfor2RestorationDesk, defectInfor2RestorationDeskPage;//打标缺陷转为图纸的坐标
  650. public Bitmap[] bmps_tag; //打标小图 //bmps_tag.count<=bmps_cut.count bmps_tag.count=informationList.count
  651. public bool isSucceed;//转换是否成功
  652. public string resultInfo = "";//成功或失败信息
  653. public long[] stopwatch = new long[5];
  654. public List<List<string>> defectInfor2BigImage;
  655. //裁切原图
  656. public Mat CutSrcbmp;
  657. }
  658. public void add(DefectTask task)
  659. {
  660. lock (taskList)
  661. taskList.Add(task);
  662. }
  663. /// <summary>
  664. /// 打标 返回每张图的绝对位置X,Y
  665. /// </summary>
  666. /// <param name="defectBmpIndex">缺陷小图索引</param>
  667. /// <param name="X">拍照位绝对位置-----X2轴</param>
  668. /// <param name="Y">拍照位绝对位置-----Y轴</param>
  669. /// <param name="imagewidth">裁剪小图的宽592</param>
  670. /// <param name="imageheight">裁剪小图的高532</param>
  671. public List<double> makeTag(int defectBmpIndex, double X, double Y, int imagewidth, int imageheight)
  672. {
  673. return yolo1.ImageXY(defectBmpIndex, X, Y, imagewidth, imageheight);
  674. }
  675. /// <summary>
  676. /// 用相机1查看缺陷点
  677. /// </summary>
  678. /// <param name="defectBmpIndex"></param>
  679. /// <param name="X"></param>
  680. /// <param name="Y"></param>
  681. /// <param name="imagewidth"></param>
  682. /// <param name="imageheight"></param>
  683. /// <returns></returns>
  684. public List<double> viewTag(int defectBmpIndex, double X, double Y, int imagewidth, int imageheight)
  685. {
  686. return yolo1.ImageXY2(defectBmpIndex, X, Y, imagewidth, imageheight);
  687. }
  688. private DefectTask pop()
  689. {
  690. lock (taskList)
  691. {
  692. if (taskList.Count < 1)
  693. return null;
  694. //int index = 0;// taskList.FindIndex(p => { return p.isSync; });
  695. //if (index < 0) index = 0;
  696. var task = taskList[0];
  697. taskList.RemoveAt(0);
  698. return task;
  699. }
  700. }
  701. private DefectTask pop2()
  702. {
  703. lock (taskOperationList)
  704. {
  705. if (taskOperationList.Count < 1)
  706. return null;
  707. //int index = 0;// taskList.FindIndex(p => { return p.isSync; });
  708. //if (index < 0) index = 0;
  709. var task = taskOperationList[0];
  710. taskOperationList.RemoveAt(0);
  711. return task;
  712. }
  713. }
  714. private DefectTask pop3()
  715. {
  716. lock (taskTagList)
  717. {
  718. if (taskTagList.Count < 1)
  719. return null;
  720. //int index = 0;// taskList.FindIndex(p => { return p.isSync; });
  721. //if (index < 0) index = 0;
  722. var task = taskTagList[0];
  723. taskTagList.RemoveAt(0);
  724. return task;
  725. }
  726. }
  727. public void Dispose()
  728. {
  729. stop();
  730. }
  731. }
  732. }