FindLine.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. using System;
  2. using HalconDotNet;
  3. using static DataStruct.DataStructClass;
  4. using ToolBase;
  5. using CommonMethods;
  6. using System.Diagnostics;
  7. using ViewROI;
  8. namespace FindLineTool
  9. {
  10. [Serializable]
  11. public class FindLine:IToolBase
  12. {
  13. public bool toolEnable = true;
  14. /// <summary>
  15. /// 输入姿态
  16. /// </summary>
  17. public HTuple inputPoseHomMat2D = new HTuple();
  18. /// <summary>
  19. /// 位置修正姿态
  20. /// </summary>
  21. public HTuple changePoseHomMat2D = new HTuple();
  22. /// <summary>
  23. /// 修改的位姿
  24. /// </summary>
  25. public HTuple changedPose = new HTuple();
  26. /// <summary>
  27. /// 卡尺
  28. /// </summary>
  29. public HObject contoursDisp = null;
  30. /// <summary>
  31. /// 箭头
  32. /// </summary>
  33. public HObject arrowDisp = null;
  34. /// <summary>
  35. /// 交点
  36. /// </summary>
  37. public HObject crossDisp = null;
  38. /// <summary>
  39. /// 期望线起点行坐标
  40. /// </summary>
  41. public HTuple expectLineStartRow = 200;
  42. /// <summary>
  43. /// 期望线起点列坐标
  44. /// </summary>
  45. public HTuple expectLineStartCol = 200;
  46. /// <summary>
  47. /// 期望线终点行坐标
  48. /// </summary>
  49. public HTuple expectLineEndRow = 200;
  50. /// <summary>
  51. /// 期望线终点列坐标
  52. /// </summary>
  53. public HTuple expectLineEndCol = 600;
  54. /// <summary>
  55. /// 新的跟随姿态变化后的预期线信息
  56. /// </summary>
  57. public HTuple modelStartRow = new HTuple(200), modelStartCol = new HTuple(200), modelEndRow = new HTuple(200), modelEndCol = new HTuple(600);
  58. /// <summary>
  59. /// 新的跟随姿态变化后的预期线信息
  60. /// </summary>
  61. public HTuple newExpectLineStartRow = new HTuple(200), newExpectLineStartCol = new HTuple(200), newExpectLineEndRow = new HTuple(200), newExpectLineEndCol = new HTuple(600);
  62. ///// <summary>
  63. ///// 区域中心行坐标
  64. ///// </summary>
  65. //public HTuple recCenterRow = 200;
  66. ///// <summary>
  67. ///// 区域中心列坐标
  68. ///// </summary>
  69. //public HTuple recCenterCol = 200;
  70. //public HTuple recAngle = 0;
  71. //public HTuple recWidth = 100;
  72. //public HTuple recLength = 200;
  73. /// <summary>
  74. /// 找边极性,从明到暗或从暗到明
  75. /// </summary>
  76. public string polarity = "negative";
  77. /// <summary>
  78. /// 卡尺数量
  79. /// </summary>
  80. public int cliperNum = 20;
  81. /// <summary>
  82. /// 卡尺高
  83. /// </summary>
  84. public int length = 80;
  85. /// <summary>
  86. /// 卡尺宽
  87. /// </summary>
  88. public int weidth = 5;
  89. /// <summary>
  90. /// 边阈值
  91. /// </summary>
  92. public int threshold = 30;
  93. /// <summary>
  94. /// 边Sigma
  95. /// </summary>
  96. public double sigma = 1.0;
  97. /// <summary>
  98. /// 选择所查找到的边
  99. /// </summary>
  100. public string edgeSelect = "all";
  101. /// <summary>
  102. /// 分数阈值
  103. /// </summary>
  104. public double _minScore = 0.5;
  105. /// <summary>
  106. /// 矩形框显示
  107. /// </summary>
  108. public bool dispRec = true;
  109. /// <summary>
  110. /// 交点显示
  111. /// </summary>
  112. public bool dispCross = true;
  113. public double minScore
  114. {
  115. get
  116. {
  117. return _minScore;
  118. }
  119. set
  120. {
  121. if(minScore >= 1)
  122. {
  123. _minScore = 1;
  124. }
  125. else if(minScore <= 0)
  126. {
  127. _minScore = 0;
  128. }
  129. else
  130. {
  131. _minScore = value;
  132. }
  133. }
  134. }
  135. /// <summary>
  136. /// 找到的线段
  137. /// </summary>
  138. public Line resultLine = null;
  139. /// <summary>
  140. /// 显示的线
  141. /// </summary>
  142. public HObject LineDisp = null;
  143. /// <summary>
  144. /// 新的跟随姿态变化后的预期线信息
  145. /// </summary>
  146. HTuple newExpectCenterRow = new HTuple(200), newExpectCenterCol = new HTuple(200), newExpectAngle = new HTuple(0);
  147. /// <summary>
  148. /// 查找到的线的起点行坐标
  149. /// </summary>
  150. private HTuple _resultLineStartRow = 0;
  151. internal HTuple ResultLineStartRow
  152. {
  153. get
  154. {
  155. _resultLineStartRow = Math.Round((double)_resultLineStartRow, 3);
  156. return _resultLineStartRow;
  157. }
  158. set { _resultLineStartRow = value; }
  159. }
  160. /// <summary>
  161. /// 查找到的线的起点列坐标
  162. /// </summary>
  163. private HTuple _resultLineStartCol = 0;
  164. internal HTuple ResultLineStartCol
  165. {
  166. get
  167. {
  168. _resultLineStartCol = Math.Round((double)_resultLineStartCol, 3);
  169. return _resultLineStartCol;
  170. }
  171. set { _resultLineStartCol = value; }
  172. }
  173. /// <summary>
  174. /// 查找到的线的终点行坐标
  175. /// </summary>
  176. private HTuple _resultLineEndRow = 0;
  177. internal HTuple ResultLineEndRow
  178. {
  179. get
  180. {
  181. _resultLineEndRow = Math.Round((double)_resultLineEndRow, 3);
  182. return _resultLineEndRow;
  183. }
  184. set { _resultLineEndRow = value; }
  185. }
  186. /// <summary>
  187. /// 查找到的线的终点列坐标
  188. /// </summary>
  189. private HTuple _resultLineEndCol = 0;
  190. internal HTuple ResultLineEndCol
  191. {
  192. get
  193. {
  194. _resultLineEndCol = Math.Round((double)_resultLineEndCol, 3);
  195. return _resultLineEndCol;
  196. }
  197. set { _resultLineEndCol = value; }
  198. }
  199. /// <summary>
  200. /// 查找到线的方向
  201. /// </summary>
  202. private HTuple _angle = 0;
  203. internal HTuple Angle
  204. {
  205. get
  206. {
  207. _angle = Math.Round((double)_angle, 3);
  208. return _angle;
  209. }
  210. set { _angle = value; }
  211. }
  212. public override void DispImage()
  213. {
  214. if(inputImage != null)
  215. {
  216. FormFindLine.Instance.myHwindow.DispImage(new HImage(inputImage));
  217. }
  218. }
  219. public void UpdateImage()
  220. {
  221. FormFindLine.Instance.myHwindow.DispHWindow.ClearWindow();
  222. DispImage();
  223. }
  224. // 更新模板线的位置,并生成变换矩阵
  225. public void UpdateModelLineLocation()
  226. {
  227. // 计算新的位置线和转换之后位置线之间的差异,再将差异补偿到模板位置线中
  228. if(newExpectLineStartRow.Type != HTupleType.EMPTY)
  229. {
  230. HOperatorSet.VectorToSimilarity(new HTuple(newExpectLineStartRow, newExpectLineEndRow), new HTuple(newExpectLineStartCol, newExpectLineEndCol),
  231. new HTuple(expectLineStartRow, expectLineEndRow), new HTuple(expectLineStartCol, expectLineEndCol), out changePoseHomMat2D);
  232. // 更新位置
  233. HOperatorSet.AffineTransPixel(changePoseHomMat2D, modelStartRow, modelStartCol, out modelStartRow, out modelStartCol);
  234. HOperatorSet.AffineTransPixel(changePoseHomMat2D, modelEndRow, modelEndCol, out modelEndRow, out modelEndCol);
  235. }
  236. }
  237. public override void Run(SoftwareRunState softwareRunState)
  238. {
  239. Stopwatch sw = new Stopwatch();
  240. sw.Restart();
  241. HTuple homMat2DArrow = null;
  242. HObject arrow = null, arrowTrans = null;
  243. HObject drawLine = null, imageReducedLine;
  244. if (inputImage == null)
  245. {
  246. FormFindLine.Instance.SetToolStatus("工具输入图像为空", ToolRunStatu.Not_Input_Image);
  247. return;
  248. }
  249. try
  250. {
  251. if(softwareRunState == SoftwareRunState.Debug)
  252. {
  253. UpdateImage();
  254. }
  255. if (inputPoseHomMat2D.Type != HTupleType.EMPTY)
  256. {
  257. //对预期线的起始点做放射变换
  258. HOperatorSet.AffineTransPixel(inputPoseHomMat2D, modelStartRow, modelStartCol, out newExpectLineStartRow, out newExpectLineStartCol);
  259. HOperatorSet.AffineTransPixel(inputPoseHomMat2D, modelEndRow, modelEndCol, out newExpectLineEndRow, out newExpectLineEndCol);
  260. }
  261. else
  262. {
  263. newExpectLineStartRow = expectLineStartRow;
  264. newExpectLineStartCol = expectLineStartCol;
  265. newExpectLineEndRow = expectLineEndRow;
  266. newExpectLineEndCol = expectLineEndCol;
  267. }
  268. HTuple handleID;
  269. HOperatorSet.CreateMetrologyModel(out handleID);
  270. HTuple width, height;
  271. HOperatorSet.GetImageSize(inputImage, out width, out height);
  272. HOperatorSet.SetMetrologyModelImageSize(handleID, width[0], height[0]);
  273. HTuple index;
  274. HOperatorSet.AddMetrologyObjectLineMeasure(handleID, newExpectLineStartRow, newExpectLineStartCol, newExpectLineEndRow, newExpectLineEndCol, new HTuple(50), new HTuple(20), new HTuple(1), new HTuple(30), new HTuple(), new HTuple(), out index);
  275. //参数在这里设置
  276. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_transition"), new HTuple(polarity));
  277. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("num_measures"), new HTuple(cliperNum));
  278. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_length1"), new HTuple(length));
  279. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_length2"), new HTuple(weidth));
  280. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_threshold"), new HTuple(threshold));
  281. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_select"), new HTuple(edgeSelect));
  282. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_sigma"), new HTuple(sigma));
  283. HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("min_score"), new HTuple(minScore));
  284. HOperatorSet.ApplyMetrologyModel(inputImage, handleID);
  285. //显示所有卡尺
  286. HTuple pointRow, pointCol;
  287. HOperatorSet.GetMetrologyObjectMeasures(out contoursDisp, handleID, new HTuple("all"), new HTuple("all"), out pointRow, out pointCol);
  288. //显示指示找线方向的箭头
  289. #region 测试箭头
  290. HTuple arrowRow = null, arrowColumn = null;
  291. HOperatorSet.GenRegionLine(out drawLine, newExpectLineStartRow, newExpectLineStartCol, newExpectLineEndRow, newExpectLineEndCol);
  292. HOperatorSet.ReduceDomain(inputImage, drawLine, out imageReducedLine);
  293. HOperatorSet.GetRegionPoints(imageReducedLine, out arrowRow, out arrowColumn);
  294. if (arrowRow.Length < 200)
  295. {
  296. CommonMethods.CommonMethods.gen_arrow_contour_xld(out arrow, arrowRow[0], arrowColumn[0], arrowRow[arrowRow.Length - 1], arrowColumn[arrowRow.Length - 1], 20, 20);
  297. }
  298. else
  299. {
  300. CommonMethods.CommonMethods.gen_arrow_contour_xld(out arrow, arrowRow[0], arrowColumn[0], arrowRow[200], arrowColumn[200], 20, 20);
  301. }
  302. HOperatorSet.VectorAngleToRigid(newExpectLineStartRow, newExpectLineStartCol, 0, (newExpectLineStartRow + newExpectLineEndRow) / 2, (newExpectLineStartCol + newExpectLineEndCol) / 2, new HTuple(-90).TupleRad(), out homMat2DArrow);
  303. HOperatorSet.AffineTransContourXld(arrow, out arrowDisp, homMat2DArrow);
  304. #endregion
  305. //把点显示出来
  306. HOperatorSet.GenCrossContourXld(out crossDisp, pointRow, pointCol, new HTuple(12), new HTuple(0));
  307. //得到所找到的线
  308. HTuple parameter;
  309. HOperatorSet.GetMetrologyObjectResult(handleID, new HTuple("all"), new HTuple("all"), new HTuple("result_type"), new HTuple("all_param"), out parameter);
  310. HOperatorSet.GetMetrologyObjectResultContour(out LineDisp, handleID, new HTuple("all"), new HTuple("all"), new HTuple(1.5));
  311. if (parameter.Length >= 4)
  312. {
  313. ResultLineStartRow = parameter[0];
  314. ResultLineStartCol = parameter[1];
  315. ResultLineEndRow = parameter[2];
  316. ResultLineEndCol = parameter[3];
  317. Point start = new Point() { Row = ResultLineStartRow, Col = ResultLineStartCol };
  318. Point end = new Point() { Row = ResultLineEndRow, Col = ResultLineEndCol };
  319. resultLine = new Line() { StartPoint = start, EndPoint = end };
  320. HOperatorSet.AngleLx(ResultLineStartRow, ResultLineStartCol, ResultLineEndRow, ResultLineEndCol, out _angle);
  321. if (softwareRunState == SoftwareRunState.Debug)
  322. {
  323. DispMainWindow(FormFindLine.Instance.myHwindow);
  324. FormFindLine.Instance.tbx_resultStartRow.Text = ResultLineStartRow.ToString();
  325. FormFindLine.Instance.tbx_resultStartCol.Text = ResultLineEndCol.ToString();
  326. FormFindLine.Instance.tbx_resultEndRow.Text = ResultLineEndRow.ToString();
  327. FormFindLine.Instance.tbx_resultEndCol.Text = ResultLineEndCol.ToString();
  328. }
  329. runMessage = "工具运行成功,已找到线!";
  330. toolRunStatu = ToolRunStatu.Succeed;
  331. }
  332. else
  333. {
  334. runMessage = "工具运行失败,未找到线";
  335. toolRunStatu = ToolRunStatu.Tool_Run_Error;
  336. }
  337. // 参数传递
  338. ParamsTrans();
  339. sw.Stop();
  340. runTime = $"运行时间: {sw.ElapsedMilliseconds} ms";
  341. FormFindLine.Instance.SetToolStatus(runMessage, toolRunStatu);
  342. HOperatorSet.ClearMetrologyModel(handleID);
  343. }
  344. catch (Exception ex)
  345. {
  346. FormFindLine.Instance.SetToolStatus($"工具运行异常,异常原因: {ex}", ToolRunStatu.Tool_Run_Error);
  347. }
  348. finally
  349. {
  350. //homMat2DArrow.Dispose();
  351. //arrow.Dispose();
  352. //arrowTrans.Dispose();
  353. }
  354. }
  355. /// <summary>
  356. /// 将数据传递给FindlineToolInterface
  357. /// </summary>
  358. private void ParamsTrans()
  359. {
  360. FormFindLine.Instance.myToolInfo.toolOutput.Clear();
  361. FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("outputXld", resultLine, DataType.Line));
  362. FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("StartPoint.Row", ResultLineStartRow, DataType.IntValue));
  363. FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("StartPoint.Column", ResultLineStartCol, DataType.IntValue));
  364. FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("EndPoint.Row", ResultLineEndRow, DataType.IntValue));
  365. FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("EndPoint.Column", ResultLineEndCol, DataType.IntValue));
  366. }
  367. public override void DispMainWindow(HWindowTool_Smart window)
  368. {
  369. // 显示矩形
  370. if (dispRec)
  371. {
  372. window.DispHWindow.SetColor("blue");
  373. window.DispHWindow.DispObj(contoursDisp);
  374. }
  375. // 显示交点
  376. if (dispCross)
  377. {
  378. window.DispHWindow.SetColor("orange");
  379. window.DispHWindow.DispObj(crossDisp);
  380. }
  381. //显示找到的线
  382. window.DispHWindow.SetColor("green");
  383. window.DispHWindow.DispObj(LineDisp);
  384. }
  385. }
  386. }