" />

小言_互联网的博客

C# HalconDotNet 工业视觉处理

324人阅读  评论(0)

1.引入Halcon组件

2.项目配置文件


  
  1. <runtime>
  2. <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  3. <dependentAssembly>
  4. <assemblyIdentity name="halcondotnet" publicKeyToken="4973BED59DDBF2B8"/>
  5. <bindingRedirect oldVersion="12.0.0.0-12.0.65535.65535" newVersion="12.0.0.0"/>
  6. </dependentAssembly>
  7. <dependentAssembly>
  8. <assemblyIdentity name="halcondotnetxl" publicKeyToken="4973BED59DDBF2B8"/>
  9. <bindingRedirect oldVersion="12.0.0.0-12.0.65535.65535" newVersion="12.0.0.0"/>
  10. </dependentAssembly>
  11. <dependentAssembly>
  12. <assemblyIdentity name="hdevenginedotnet" publicKeyToken="4973BED59DDBF2B8"/>
  13. <bindingRedirect oldVersion="12.0.0.0-12.0.65535.65535" newVersion="12.0.0.0"/>
  14. </dependentAssembly>
  15. <dependentAssembly>
  16. <assemblyIdentity name="hdevenginedotnetxl" publicKeyToken="4973BED59DDBF2B8"/>
  17. <bindingRedirect oldVersion="12.0.0.0-12.0.65535.65535" newVersion="12.0.0.0"/>
  18. </dependentAssembly>
  19. </assemblyBinding>
  20. </runtime>

 

3.页面配置

4.halcon接口调用


  
  1. public partial class HDevelopExport
  2. {
  3. public int ResultN;
  4. public double usedTime;
  5. public double[] Px;
  6. public double[] Py;
  7. public double Fx, Fy;
  8. public double Cr = 9;
  9. public double Cx, Cy;
  10. public bool IsStart = false;
  11. HTuple hv_R;
  12. List<HTuple> Aa = new List<HTuple>();
  13. HTuple hv_Angle, hv_Score, hv_Runtime;
  14. HTuple hv_ModelID, hv_Row, hv_Column;
  15. HObject ho_Mask;
  16. HTuple hv_S1, hv_S2;
  17. HObject ho_Image, ho_Rectangle, ho_ImageReduced;
  18. public HTuple hv_ExpDefaultWinHandle;
  19. HWindowControl HWindowControl;
  20. /// <summary>
  21. /// 打开相机
  22. /// </summary>
  23. public void OpenCamera()
  24. {
  25. //hv_ExpDefaultWinHandle = Window;
  26. HOperatorSet.GenEmptyObj( out ho_Image); // 生ho_Image数据区
  27. // Grabbing images from a Daheng USB 2.0 camera
  28. HOperatorSet.CloseAllFramegrabbers();
  29. HOperatorSet.OpenFramegrabber( "DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
  30. -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_Angle);
  31. HOperatorSet.SetFramegrabberParam(hv_Angle, "tilt", -3);
  32. HOperatorSet.GrabImageStart(hv_Angle, -1);
  33. //open camera with default settings
  34. }
  35. /// <summary>
  36. /// 关闭相机
  37. /// </summary>
  38. public void CloseCamera()
  39. {
  40. HOperatorSet.CloseAllFramegrabbers();
  41. }
  42. /// <summary>
  43. /// 实时播放
  44. /// </summary>
  45. public void RealTimePlayback()
  46. {
  47. IsStart = true;
  48. //HObject ho_Image = null;
  49. //HTuple hv_AcqHandle = new HTuple();
  50. Initialize local and output iconic variables
  51. //HOperatorSet.GenEmptyObj(out ho_Image);
  52. Image Acquisition 01: Code generated by Image Acquisition 01
  53. //HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
  54. // -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_AcqHandle);
  55. //HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
  56. Task task = new Task(() =>
  57. {
  58. while (IsStart)
  59. {
  60. ho_Image.Dispose();
  61. HOperatorSet.GrabImageAsync( out ho_Image, hv_Angle, -1);
  62. HTuple hv_Width, hv_Height;
  63. HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height); // 获取图片的尺寸
  64. double ratioWidth = ( 1.0) * hv_Width[ 0].I / HWindowControl.Width;
  65. double ratioHeight = ( 1.0) * hv_Height[ 0].I / HWindowControl.Height;
  66. HTuple row1, column1, row2, column2;
  67. if (ratioWidth >= ratioHeight)
  68. {
  69. row1 = -( 1.0) * ((HWindowControl.Height * ratioWidth) - hv_Height) / 2;
  70. column1 = 0;
  71. row2 = row1 + HWindowControl.Height * ratioWidth;
  72. column2 = column1 + HWindowControl.Width * ratioWidth;
  73. HOperatorSet.SetPart(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
  74. HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
  75. }
  76. }
  77. });
  78. task.Start();
  79. }
  80. /// <summary>
  81. /// 拍照
  82. /// </summary>
  83. public void Photograph()
  84. {
  85. IsStart = true;
  86. HTuple hv_Width, hv_Height;
  87. ho_Image.Dispose(); // 清除ho_Image中的数据
  88. HOperatorSet.GrabImage( out ho_Image, hv_AcqHandle); // 采集图像
  89. HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height); // 获取图片的尺寸
  90. double ratioWidth = ( 1.0) * hv_Width[ 0].I / HWindowControl.Width;
  91. double ratioHeight = ( 1.0) * hv_Height[ 0].I / HWindowControl.Height;
  92. HTuple row1, column1, row2, column2;
  93. if (ratioWidth >= ratioHeight)
  94. {
  95. row1 = -( 1.0) * ((HWindowControl.Height * ratioWidth) - hv_Height) / 2;
  96. column1 = 0;
  97. row2 = row1 + HWindowControl.Height * ratioWidth;
  98. column2 = column1 + HWindowControl.Width * ratioWidth;
  99. HOperatorSet.SetPart(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
  100. HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
  101. // 显示ho_Image中的图片
  102. HOperatorSet.SetDraw(hv_ExpDefaultWinHandle, "margin"); // 填充模式为只画框
  103. HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red"); // 画线颜色红
  104. HOperatorSet.DispRectangle1(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
  105. }
  106. }
  107. /// <summary>
  108. /// 初始化相机
  109. /// </summary>
  110. public void InitHalcon()
  111. {
  112. // Default settings used in HDevelop
  113. HOperatorSet.SetSystem( "width", 512);
  114. HOperatorSet.SetSystem( "height", 512);
  115. }
  116. /// <summary>
  117. /// 初始化Halcon
  118. /// </summary>
  119. /// <param name="Window"></param>
  120. public void RunHalcon(HWindowControl Window)
  121. {
  122. HWindowControl = Window;
  123. hv_ExpDefaultWinHandle = Window.HalconWindow;
  124. }
  125. /// <summary>
  126. /// 设置模板
  127. /// </summary>
  128. public void SetTemplate()
  129. {
  130. HTuple hv_Row1, hv_Column1, hv_Row2, hv_Column2;
  131. MessageBox.Show( "在红框中按下鼠标左键画方框选模板,按右键结束");
  132. HOperatorSet.DrawRectangle1(hv_ExpDefaultWinHandle,
  133. out hv_Row1, out hv_Column1, out hv_Row2, out hv_Column2);
  134. HOperatorSet.GenRectangle1( out ho_Rectangle, hv_Row1, hv_Column1, hv_Row2, hv_Column2);
  135. HOperatorSet.ReduceDomain(ho_Image, ho_Rectangle, out ho_ImageReduced);
  136. HOperatorSet.WriteImage(ho_ImageReduced, "png", 0, "E:/test.png");
  137. MessageBox.Show( "模板已保存");
  138. }
  139. /// <summary>
  140. /// 从文件中读取模板
  141. /// </summary>
  142. public void ReadTemplate()
  143. {
  144. HOperatorSet.GenEmptyObj( out ho_ImageReduced);
  145. ho_ImageReduced.Dispose();
  146. HOperatorSet.ReadImage( out ho_ImageReduced, "E:/test.png");
  147. }
  148. /// <summary>
  149. /// 模板匹配
  150. /// </summary>
  151. public void MatchTemplate()
  152. {
  153. int i, j;
  154. double temp;
  155. HOperatorSet.GenRectangle1( out ho_Rectangle, 320, 250, 630, 750);
  156. HOperatorSet.ReduceDomain(ho_Image, ho_Rectangle, out ho_Mask);
  157. //Reduce image range
  158. HOperatorSet.CreateShapeModel(ho_ImageReduced, "auto", ( new HTuple( -45)).TupleRad(), ( new HTuple( 90)).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto", out hv_ModelID);
  159. HOperatorSet.CountSeconds( out hv_S1); // Match start
  160. HOperatorSet.FindShapeModel(ho_Mask, hv_ModelID, ( new HTuple( -45)).TupleRad(), ( new HTuple( 90)).TupleRad(), 0.5, 3, 0.0, "least_squares", 0, 0.5, out hv_Row, out hv_Column, out hv_Angle, out hv_Score);
  161. HOperatorSet.CountSeconds( out hv_S2); // Match stop
  162. hv_Runtime = (hv_S2 - hv_S1) * 1000;
  163. usedTime = hv_Runtime;
  164. ResultN = new HTuple(hv_Row.TupleLength());
  165. // 获取匹配结果个数
  166. if (ResultN > 0)
  167. {
  168. Px = new double[ResultN];
  169. Py = new double[ResultN];
  170. hv_R = new HTuple(); //HTuple变量初始化
  171. for (i = 0; i < ResultN; i++)
  172. {
  173. Py[i] = hv_Row[i]; // 将搜索结果的中心坐标读出
  174. Px[i] = hv_Column[i];
  175. Aa.Add(hv_Angle[i]);
  176. hv_R[i] = 8; //设置圆半径
  177. }
  178. for (i = 0; i < ResultN; i++) // 从大到小排序
  179. {
  180. for (j = i + 1; j < ResultN; j++)
  181. {
  182. if (Px[i] < Px[j])
  183. {
  184. temp = Px[i];
  185. Px[i] = Px[j];
  186. Px[j] = temp;
  187. temp = Py[i];
  188. Py[i] = Py[j];
  189. Py[j] = temp;
  190. temp = Aa[i];
  191. Aa[i] = Aa[j];
  192. Aa[j] = temp;
  193. }
  194. }
  195. }
  196. HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red"); // 显示匹配结果位置
  197. HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, hv_Row, hv_Column, hv_R);
  198. HOperatorSet.ClearShapeModel(hv_ModelID);
  199. Cy = Py[ 0] + 10; // offset的初始值
  200. Cx = Px[ 0] + 60;
  201. }
  202. else
  203. {
  204. MessageBox.Show( "匹配失败!?");
  205. }
  206. }
  207. /// <summary>
  208. /// 显示偏移点位置
  209. /// </summary>
  210. public void DisplayOffset()
  211. {
  212. HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red");
  213. HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
  214. HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, hv_Row, hv_Column, hv_R);
  215. HOperatorSet.DispLine(hv_ExpDefaultWinHandle, hv_Row[ 0], hv_Column[ 0], hv_Row[ 1], hv_Column[ 1]);
  216. HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "yellow");
  217. HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, Cy, Cx, Cr);
  218. }
  219. /// <summary>
  220. /// /显示计算角度,划线
  221. /// </summary>
  222. public void DisplayLine()
  223. {
  224. HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "yellow");
  225. HOperatorSet.DispLine(hv_ExpDefaultWinHandle, Cy, Cx, Fy, Fx);
  226. }
  227. }

 

5.form1cs页面


  
  1. public Form1()
  2. {
  3. InitializeComponent();
  4. timer1.Tick += Timer1_Tick;
  5. timer1.Interval = 5000;
  6. this.Controls.Add(hWindowControl1);
  7. hWindowControl1.Location = new System.Drawing.Point( 20, 20);
  8. hWindowControl1.Width = 500;
  9. hWindowControl1.Height = 500;
  10. hd.InitHalcon();
  11. }
  12. private void Form1_Load(object sender, EventArgs e)
  13. {
  14. hd.RunHalcon(hWindowControl1); // 摄像头初始化
  15. }
  16. /// <summary>
  17. /// 打开相机
  18. /// </summary>
  19. /// <param name="sender"></param>
  20. /// <param name="e"></param>
  21. private void btnOpenCamera_Click(object sender, EventArgs e)
  22. {
  23. hd.OpenCamera();
  24. textBox1.Text = "";
  25. textBox1.Refresh();
  26. }
  27. /// <summary>
  28. ///关闭相机
  29. /// </summary>
  30. /// <param name="sender"></param>
  31. /// <param name="e"></param>
  32. private void btnCloseCamera_Click(object sender, EventArgs e)
  33. {
  34. hd.CloseCamera();
  35. }
  36. /// <summary>
  37. /// 匹配
  38. /// </summary>
  39. /// <param name="sender"></param>
  40. /// <param name="e"></param>
  41. private void btnMatch_Click(object sender, EventArgs e)
  42. {
  43. int j, m;
  44. double d;
  45. double[] x;
  46. double[] y;
  47. hd.MatchTemplate(); // 图像匹配
  48. m = hd.ResultN;
  49. x = new double[m];
  50. y = new double[m];
  51. for (j = 0; j < m; j++) // 获取匹配坐标
  52. {
  53. x[j] = hd.Px[j];
  54. y[j] = hd.Py[j];
  55. }
  56. textBox1.Text = "匹配时间:" + hd.usedTime.ToString( "#####.##") + " ms" + "\r\n" + "\r\n";
  57. for (j = 0; j < m; j++)
  58. {
  59. if (j < m - 1) // 计算2点距离
  60. {
  61. d = (y[j + 1] - y[j]) * (y[j + 1] - y[j]) + (x[j + 1] - x[j]) * (x[j + 1] - x[j]);
  62. d = Math.Sqrt(d);
  63. d = 0.0485 * d;
  64. textBox1.Text = textBox1.Text + "d(" + Convert.ToString(j + 1) + ") = " + d.ToString( "#####.##")+ "mm" + "\r\n";
  65. }
  66. textBox1.Text = textBox1.Text + "x(" + Convert.ToString(j + 1) + ") = " + Convert.ToString(x[j]) + " y(" + Convert.ToString(j + 1) + ") = " + Convert.ToString(y[j]) + "\r\n" + "\r\n";
  67. }
  68. }
  69. /// <summary>
  70. /// 设置模板
  71. /// </summary>
  72. /// <param name="sender"></param>
  73. /// <param name="e"></param>
  74. private void btnTemplate_Click(object sender, EventArgs e)
  75. {
  76. hd.SetTemplate();
  77. }
  78. /// <summary>
  79. /// 加载模板
  80. /// </summary>
  81. /// <param name="sender"></param>
  82. /// <param name="e"></param>
  83. private void btnLoadTemplate_Click(object sender, EventArgs e)
  84. {
  85. hd.ReadTemplate();
  86. }
  87. /// <summary>
  88. /// 实时播放
  89. /// </summary>
  90. /// <param name="sender"></param>
  91. /// <param name="e"></param>
  92. private void btnPlayback_Click(object sender, EventArgs e)
  93. {
  94. hd.RealTimePlayback();
  95. }
  96. /// <summary>
  97. /// 显示结果
  98. /// </summary>
  99. /// <param name="sender"></param>
  100. /// <param name="e"></param>
  101. private void btnDisplayResults_Click(object sender, EventArgs e)
  102. {
  103. double a, b, c, d, m, n;
  104. double alpha, beta;
  105. a = hd.Px[ 0];
  106. b = hd.Py[ 0];
  107. c = hd.Px[ 0];
  108. d = hd.Py[ 0];
  109. alpha = Math.Atan((d - b) / (c - a));
  110. beta = theta + alpha;
  111. m = a + Lam * Math.Cos(beta);
  112. n = b + Lam * Math.Sin(beta);
  113. textBox1.Text = textBox1.Text + " m = " + Convert.ToString(m) + "\r\n" + "n = " + Convert.ToString(n) + "\r\n" + "alpha = " + Convert.ToString(alpha) + "\r\n" + " theta = " + Convert.ToString(theta) + "\r\n" + " beta = " + Convert.ToString(beta);
  114. hd.Cx = m;
  115. hd.Cy = n;
  116. hd.Fx = m - 600 * Math.Cos(alpha); // 计算夹角斜线的终点坐标
  117. hd.Fy = n - 600 * Math.Sin(alpha);
  118. hd.DisplayOffset(); // 显示插针位置
  119. hd.DisplayLine(); // 显示工件夹角
  120. }
  121. /// <summary>
  122. /// 拍照
  123. /// </summary>
  124. /// <param name="sender"></param>
  125. /// <param name="e"></param>
  126. private void btnPhotograph_Click(object sender, EventArgs e)
  127. {
  128. hd.Photograph();
  129. }

 

 


转载:https://blog.csdn.net/code_long/article/details/117256563
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场