c#与Halcon的联合编程-----零件交互检测(细的不行不行版)(c#部分)

一.这里我简单的搞一个winform交互界面

左边是一个listview控件用来将我们的检测的数据输出显示在该控件上

中间是一个pictureBox1将我们的图像数据显示在该控件上

二.配置我们的联合编程环境

(1)

注意:这里要看的halcon版本x64的就吧这个首选32为取消掉,x86的可以勾上,不然会报以下错误:

entrypointnotfoundexception: 无法在 dll“halcon”中找到名为“hlireleaseexternalownership”的入口点。

(2)

找到我们halcon的文档位置我的是"C:\Program Files\MVTec\HALCON-17.12-Progress\bin\dotnet35"给你们借鉴,找到下面的文件复制到我们winform的debug目录下

找不到debug文件的可以有右键我们winform项目有个在资源文件管理器中打开文件夹

在bin文件夹里复制到debug目录中

建议将我们的图像资源也放到debug目录下方便我们后面的路径书写

(3)

添加我们的引用

1.右键引用点击添加引用2.点击最近然后点击浏览找到我们的文档进行添加3.勾选上

三.打开我们在halcon中导出来的c#代码进行逻辑编程(不知道怎么导出的看halcon部分有详细教程)

//
// File generated by HDevelop for HALCON/.NET (C#) Version 17.12
//

using HalconDotNet;

public partial class HDevelopExport
{
#if !(NO_EXPORT_MAIN || NO_EXPORT_APP_MAIN)
  public HDevelopExport()
  {
    // Default settings used in HDevelop 
    HOperatorSet.SetSystem("width", 512);
    HOperatorSet.SetSystem("height", 512);
    if (HalconAPI.isWindows)
      HOperatorSet.SetSystem("use_window_thread","true");
    action();
  }
#endif

#if !NO_EXPORT_MAIN
  // Main procedure 
  private void action()
  {


    // Local iconic variables 

    HObject ho_Image, ho_ResultImage=null, ho_ResultRegions=null;
    HObject ho_ResultConnectedRegions=null, ho_ResultSelectedRegions1=null;
    HObject ho_ResultCircle=null, ho_ResultContour=null;

    // Local control variables 

    HTuple hv_ImageFiles = null, hv_Width = null;
    HTuple hv_Height = null, hv_WindowHandle = null, hv_MetrologyHandle = null;
    HTuple hv_Row = null, hv_Column = null, hv_Radius = null;
    HTuple hv_CirCleRadiusTolerance = null, hv_Index = null;
    HTuple hv_ResultArea = new HTuple(), hv_ResultRow = new HTuple();
    HTuple hv_ResultColumn = new HTuple(), hv_MetrologyCircleIndice = new HTuple();
    HTuple hv_CircleRadiusResult = new HTuple();
    // Initialize local and output iconic variables 
    HOperatorSet.GenEmptyObj(out ho_Image);
    HOperatorSet.GenEmptyObj(out ho_ResultImage);
    HOperatorSet.GenEmptyObj(out ho_ResultRegions);
    HOperatorSet.GenEmptyObj(out ho_ResultConnectedRegions);
    HOperatorSet.GenEmptyObj(out ho_ResultSelectedRegions1);
    HOperatorSet.GenEmptyObj(out ho_ResultCircle);
    HOperatorSet.GenEmptyObj(out ho_ResultContour);
    HOperatorSet.ListFiles("C:/Users/14350/Desktop/halcon1/联合编程/img/img", (new HTuple("files")).TupleConcat(
        "follow_links"), out hv_ImageFiles);
    ho_Image.Dispose();
    HOperatorSet.ReadImage(out ho_Image, hv_ImageFiles.TupleSelect(0));

    //获取图像大小
    HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);

    HOperatorSet.SetWindowAttr("background_color","black");
    HOperatorSet.OpenWindow(0,0,hv_Width/4,hv_Height/4,0,"visible","",out hv_WindowHandle);
    HDevWindowStack.Push(hv_WindowHandle);
    if (HDevWindowStack.IsOpen())
    {
      HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
    }
    //创建测量模型
    HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
    //设置测量模型的大小
    HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

    HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);

    //也可以配置其他的参数,例如测量对象的宽度允许范围
    hv_CirCleRadiusTolerance = 100;

    //对多张图像进行测量
    for (hv_Index=0; (int)hv_Index<=(int)((new HTuple(hv_ImageFiles.TupleLength()
        ))-1); hv_Index = (int)hv_Index + 1)
    {
      ho_ResultImage.Dispose();
      HOperatorSet.ReadImage(out ho_ResultImage, hv_ImageFiles.TupleSelect(hv_Index));
      //阈值分割,挑选出来配件部分
      ho_ResultRegions.Dispose();
      HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegions, 3, 60);
      //连通性
      ho_ResultConnectedRegions.Dispose();
      HOperatorSet.Connection(ho_ResultRegions, out ho_ResultConnectedRegions);
      //特征提取:用面积,和圆两个指标提取  area
      ho_ResultSelectedRegions1.Dispose();
      HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions1, 
          (new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
          0.9), (new HTuple(320000)).TupleConcat(1));
      //获取
      HOperatorSet.AreaCenter(ho_ResultSelectedRegions1, out hv_ResultArea, out hv_ResultRow, 
          out hv_ResultColumn);
      //设置输出的颜色
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.SetColor(HDevWindowStack.GetActive(), "green");
      }
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
      }
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.DispObj(ho_ResultImage, HDevWindowStack.GetActive());
      }
      //生成圆:注意,这里借助了上方两个特征提取出来的坐标
      ho_ResultCircle.Dispose();
      HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn, 
          hv_Radius);
      //把圆添加到模型中
      HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow, 
          hv_ResultColumn, hv_Radius, hv_CirCleRadiusTolerance, 5, 1.5, 30, (new HTuple("measure_transition")).TupleConcat(
          "min_score"), (new HTuple("all")).TupleConcat(0.4), out hv_MetrologyCircleIndice);
      //测量并拟合集合形状
      HOperatorSet.ApplyMetrologyModel(ho_ResultImage, hv_MetrologyHandle);
      //获取测量模型中的测量轮廓,方便后期显示
      ho_ResultContour.Dispose();
      HOperatorSet.GetMetrologyObjectResultContour(out ho_ResultContour, hv_MetrologyHandle, 
          "all", "all", 1.5);
      //在轮廓基础上获得此次测量的结果:第二个参数是每个图象的索引
      HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice, 
          "all", "result_type", "radius", out hv_CircleRadiusResult);

      //显示图像
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.DispObj(ho_ResultImage, HDevWindowStack.GetActive());
      }
      //显示测量轮廓
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.DispObj(ho_ResultContour, HDevWindowStack.GetActive());
      }

      //设置文字位置
      HOperatorSet.SetTposition(hv_WindowHandle, 0, 0);
      //在指定位置显示信息
      HOperatorSet.WriteString(hv_WindowHandle, "圆的半径:"+hv_CircleRadiusResult);
      // stop(...); only in hdevelop
    }
    //清除测量模型
    HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);




    ho_Image.Dispose();
    ho_ResultImage.Dispose();
    ho_ResultRegions.Dispose();
    ho_ResultConnectedRegions.Dispose();
    ho_ResultSelectedRegions1.Dispose();
    ho_ResultCircle.Dispose();
    ho_ResultContour.Dispose();

  }

#endif


}
#if !(NO_EXPORT_MAIN || NO_EXPORT_APP_MAIN)
public class HDevelopExportApp
{
  static void Main(string[] args)
  {
    new HDevelopExport();
  }
}
#endif

看着挺长但是很多会用不到只需要粘我们需要的就行

四.c#代码编程

(1)完整代码

using HalconDotNet;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Threading;
using System.Windows.Forms;

namespace halcon检测项目
{
    public partial class Form1 : Form
    {
        HTuple hv_Row = null, hv_Column = null, hv_Radius = null;
        HObject image;
        HTuple windowID;
        Thread t1;
        HObject[] ImageArr = new HObject[8];
        bool t1_Stop = false;
        bool t1_Pause = false; // 添加暂停标志变量

        public Form1()
        {
            InitializeComponent();
            // 初始化ListView相关设置
            InitializeListView();
        }

        private void InitializeListView()
        {
            listView1.View = View.Details;
            listView1.GridLines = true;
            listView1.FullRowSelect = true;

            listView1.Columns.Add("编号", 80);
            listView1.Columns.Add("半径", 100);
            listView1.Columns.Add("结果", 100);
        }

        // 其他原有的代码区域(资源加载、窗口创建等代码保持不变)
        #region 先把资源加载进来
        private void LoadBateImage()
        {
            for (int i = 0; i < 8; i++)
            {
                HOperatorSet.ReadImage(out ImageArr[i], $"img/{i}.bmp");
            }
        }
        #endregion

        #region 加载窗体
        private void CreateHalconWindow()
        {
            HTuple winforms = this.pictureBox1.Handle;
            HOperatorSet.SetWindowAttr("background_color", "red");
            HOperatorSet.OpenWindow(0, 0, this.pictureBox1.Width, this.pictureBox1.Height, winforms, "", "", out windowID);
        }
        #endregion

        #region 加载默认图片
        private void LoadImage()
        {
            HOperatorSet.ReadImage(out image, "img/0.bmp");
            HTuple Width = null, Height = null;
            HOperatorSet.GetImageSize(image, out Width, out Height);
            HOperatorSet.SetColor(windowID, "red");
            HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
            HOperatorSet.DispObj(image, windowID);
        }
        #endregion

        #region 加载配置环境
        private void Form1_Load(object sender, EventArgs e)
        {
            LoadBateImage();
            CreateHalconWindow();
            LoadImage();

            t1 = new Thread(new ThreadStart(PlayThread));
        }
        #endregion

        #region 开始测量
        private void button1_Click(object sender, EventArgs e)
        {
            t1_Stop = false;
            if (t1.ThreadState == ThreadState.Unstarted)
            {
                t1.Start();
            }
            if (t1.ThreadState == ThreadState.Stopped || t1.ThreadState == ThreadState.Aborted)
            {
                t1 = new Thread(new ThreadStart(PlayThread));
                t1.Start();
            }
        }

        private void PlayThread()
        {
            int i = 0;
            t1_Stop = false;
            t1_Pause = false; // 初始化暂停标志变量

            while (!t1_Stop)
            {
                if (t1_Pause) // 检查暂停标志变量
                {
                    // 等待直到暂停标志被清除或线程停止
                    while (t1_Pause && !t1_Stop)
                    {
                        Thread.Sleep(100); // 休眠一小段时间,避免过度占用CPU
                    }
                }

                HOperatorSet.DispObj(ImageArr[i], windowID);
                HTuple Width = null, Height = null;
                HOperatorSet.GetImageSize(ImageArr[i], out Width, out Height);
                HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
                double CriRad = ImageMeasure(ImageArr[i]);

                string result = CriRad > 311 && CriRad < 313 ? "OK" : "NG";
                // 将测量数据添加到ListView
                AddDataToListView(i, CriRad, result);

                if (CriRad > 311 && CriRad < 313)
                {
                    string filePath = @"OK\OK.txt"; // 指定完整路径,包括目录和文件名

                    // 确保目录存在
                    Directory.CreateDirectory(Path.GetDirectoryName(filePath));

                    // 写入内容(如果文件不存在会自动创建)
                    string ok = $" OK, 序号{i}零件测得半径:{CriRad}\n";
                    File.AppendAllText(filePath, ok);
                }
                else
                {
                    string filePath = @"NG\NG.txt"; // 指定完整路径,包括目录和文件名

                    // 确保目录存在
                    Directory.CreateDirectory(Path.GetDirectoryName(filePath));

                    // 写入内容(如果文件不存在会自动创建)
                    string ng = $" NG, 序号{i}零件测得半径:{CriRad}\n";
                    File.AppendAllText(filePath, ng);
                }

                Thread.Sleep(1000);
                i++;
                if (i >= 8)
                {
                    i = 0;
                }
            }
        }

        private void AddDataToListView(int index, double radius, string result)
        {
            if (this.InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    ListViewItem item = new ListViewItem(index.ToString());
                    item.SubItems.Add(radius.ToString());
                    item.SubItems.Add(result);
                    listView1.Items.Add(item);
                });
            }
            else
            {
                ListViewItem item = new ListViewItem(index.ToString());
                item.SubItems.Add(radius.ToString());
                item.SubItems.Add(result);
                listView1.Items.Add(item);
            }
        }

        private double ImageMeasure(HObject ho_ResultImage)
        {
            // 原有的测量代码逻辑保持不变
            HObject ho_ResultRegions = null;
            HObject ho_ResultConnectedRegions = null;
            HObject ho_ResultSelectedRegions1 = null;
            HObject ho_ResultCircle = null;
            HObject ho_ResultContour = null;

            HTuple hv_Width = null, hv_Height = null;

            HTuple hv_CirCleRadiusTolerance = new HTuple(100);
            HTuple hv_ResultArea = null, hv_ResultRow = null;
            HTuple hv_ResultColumn = null, hv_MetrologyCircleIndice = null;
            HTuple hv_CircleRadiusResult = null;
            HTuple hv_MetrologyHandle = new HTuple();

            HOperatorSet.GetImageSize(ho_ResultImage, out hv_Width, out hv_Height);

            // 开始测量
            HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
            HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

            // 特征提取
            HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegions, 3, 60);
            HOperatorSet.Connection(ho_ResultRegions, out ho_ResultConnectedRegions);
            HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions1,
                (new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
                0.9), (new HTuple(320000)).TupleConcat(1));
            HOperatorSet.AreaCenter(ho_ResultSelectedRegions1, out hv_ResultArea, out hv_ResultRow, out hv_ResultColumn);

            HOperatorSet.SetColor(windowID, "green");
            HOperatorSet.SetDraw(windowID, "margin");
            HOperatorSet.DispObj(ho_ResultImage, windowID);

            // 生成圆
            HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn, hv_Radius.D);
            // 把圆添加到模型中
            HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow,
                hv_ResultColumn, hv_Radius.D, hv_CirCleRadiusTolerance, 5, 1.5, 30, (new HTuple("measure_transition")).TupleConcat(
                "min_score"), (new HTuple("all")).TupleConcat(0.4), out hv_MetrologyCircleIndice);
            // 测量并拟合集合形状
            HOperatorSet.ApplyMetrologyModel(ho_ResultImage, hv_MetrologyHandle);

            HOperatorSet.GetMetrologyObjectResultContour(out ho_ResultContour, hv_MetrologyHandle,
                "all", "all", 1.5);
            // 在轮廓基础上获得此次测量的结果
            HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
                "all", "result_type", "radius", out hv_CircleRadiusResult);

            // 显示图像
            HOperatorSet.DispObj(ho_ResultImage, windowID);
            // 显示测量轮廓
            HOperatorSet.DispObj(ho_ResultContour, windowID);
            HOperatorSet.SetTposition(windowID, 0, 0);
            HOperatorSet.WriteString(windowID, "圆的半径:" + hv_CircleRadiusResult);
            HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);

            // 释放资源
            ho_ResultRegions.Dispose();
            ho_ResultConnectedRegions.Dispose();
            ho_ResultSelectedRegions1.Dispose();
            ho_ResultCircle.Dispose();
            ho_ResultContour.Dispose();

            // 返回结果
            return hv_CircleRadiusResult.D;
        }
        #endregion

        private void button2_Click(object sender, EventArgs e)
        {
            // 停止检测
            t1_Stop = true;
            t1_Pause = false; // 清除暂停标志变量
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //清空OK和NG文件夹
            DirectoryInfo di = new DirectoryInfo("OK");
            foreach (FileInfo file in di.GetFiles())
            {
                file.Delete();
            }
            di = new DirectoryInfo("NG");
            foreach (FileInfo file in di.GetFiles())
            {
                file.Delete();
            }

            // 交互测量绘制模型圆
            InteractiveMeasure(image);
        }

        private void InteractiveMeasure(HObject ho_Image)
        {
            // 原有的交互测量代码逻辑保持不变
            HTuple hv_WindowHandle = windowID;

            HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);
            // 显示交互绘制的圆
            HObject ho_InteractiveCircle = null;
            HOperatorSet.GenCircle(out ho_InteractiveCircle, hv_Row, hv_Column, hv_Radius);
            HOperatorSet.SetColor(windowID, "blue");
            HOperatorSet.DispObj(ho_InteractiveCircle, windowID);

            // 使用交互绘制的圆进行测量
            HTuple hv_MetrologyHandle = new HTuple();
            HTuple hv_MetrologyCircleIndice = new HTuple();
            HTuple hv_CirCleRadiusTolerance = new HTuple(100);
            HTuple hv_CircleRadiusResult = new HTuple();

            // 创建测量模型
            HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
            HTuple hv_Width = null, hv_Height = null;
            HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
            HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

            // 添加交互绘制的圆到测量模型中
            HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_Row, hv_Column, hv_Radius, hv_CirCleRadiusTolerance, 5, 1.5, 30, (new HTuple("measure_transition")).TupleConcat(
                "min_score"), (new HTuple("all")).TupleConcat(0.4), out hv_MetrologyCircleIndice);

            // 测量并拟合集合形状
            HOperatorSet.ApplyMetrologyModel(ho_Image, hv_MetrologyHandle);

            // 获取测量结果
            HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
                "all", "result_type", "radius", out hv_CircleRadiusResult);

            // 显示测量结果
            HOperatorSet.SetTposition(windowID, 0, 0);
            HOperatorSet.WriteString(windowID, "交互测量的圆的半径:" + hv_CircleRadiusResult);

            // 释放资源
            ho_InteractiveCircle.Dispose();
            HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
        }
    }
}

(2).在Form1_Load中加载配置环境

    // 其他原有的代码区域(资源加载、窗口创建等代码保持不变)
    #region 先把资源加载进来
    private void LoadBateImage()
    {
        for (int i = 0; i < 8; i++)
        {
            HOperatorSet.ReadImage(out ImageArr[i], $"img/{i}.bmp");
        }
    }
    #endregion

    #region 加载窗体
    private void CreateHalconWindow()
    {
        HTuple winforms = this.pictureBox1.Handle;
        HOperatorSet.SetWindowAttr("background_color", "red");
        HOperatorSet.OpenWindow(0, 0, this.pictureBox1.Width, this.pictureBox1.Height, winforms, "", "", out windowID);
    }
    #endregion

    #region 加载默认图片
    private void LoadImage()
    {
        HOperatorSet.ReadImage(out image, "img/0.bmp");
        HTuple Width = null, Height = null;
        HOperatorSet.GetImageSize(image, out Width, out Height);
        HOperatorSet.SetColor(windowID, "red");
        HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
        HOperatorSet.DispObj(image, windowID);
    }
    #endregion

    #region 加载配置环境
    private void Form1_Load(object sender, EventArgs e)
    {
        LoadBateImage();
        CreateHalconWindow();
        LoadImage();

        t1 = new Thread(new ThreadStart(PlayThread));
    }
    #endregion

这一步为了1.加载窗体2.将初始的图像显示出来3.将图像资源加载出来(在我们生成的c#代码中都有选择粘贴出来)

(3)绘制模版

 private void button3_Click(object sender, EventArgs e)
 {
     //清空OK和NG文件夹
     DirectoryInfo di = new DirectoryInfo("OK");
     foreach (FileInfo file in di.GetFiles())
     {
         file.Delete();
     }
     di = new DirectoryInfo("NG");
     foreach (FileInfo file in di.GetFiles())
     {
         file.Delete();
     }

     // 交互测量绘制模型圆
     InteractiveMeasure(image);
 }

 private void InteractiveMeasure(HObject ho_Image)
 {
     // 原有的交互测量代码逻辑保持不变
     HTuple hv_WindowHandle = windowID;

     HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);
     // 显示交互绘制的圆
     HObject ho_InteractiveCircle = null;
     HOperatorSet.GenCircle(out ho_InteractiveCircle, hv_Row, hv_Column, hv_Radius);
     HOperatorSet.SetColor(windowID, "blue");
     HOperatorSet.DispObj(ho_InteractiveCircle, windowID);

     // 使用交互绘制的圆进行测量
     HTuple hv_MetrologyHandle = new HTuple();
     HTuple hv_MetrologyCircleIndice = new HTuple();
     HTuple hv_CirCleRadiusTolerance = new HTuple(100);
     HTuple hv_CircleRadiusResult = new HTuple();

     // 创建测量模型
     HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
     HTuple hv_Width = null, hv_Height = null;
     HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
     HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

     // 添加交互绘制的圆到测量模型中
     HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_Row, hv_Column, hv_Radius, hv_CirCleRadiusTolerance, 5, 1.5, 30, (new HTuple("measure_transition")).TupleConcat(
         "min_score"), (new HTuple("all")).TupleConcat(0.4), out hv_MetrologyCircleIndice);

     // 测量并拟合集合形状
     HOperatorSet.ApplyMetrologyModel(ho_Image, hv_MetrologyHandle);

     // 获取测量结果
     HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
         "all", "result_type", "radius", out hv_CircleRadiusResult);

     // 显示测量结果
     HOperatorSet.SetTposition(windowID, 0, 0);
     HOperatorSet.WriteString(windowID, "交互测量的圆的半径:" + hv_CircleRadiusResult);

     // 释放资源
     ho_InteractiveCircle.Dispose();
     HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
 }

当我们点击button3的时候进行绘制我们的模版圆用于后续的检测

HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);

主要就是这句

后续是将我们绘制的圆和数据显示出来

(4)测量零件

 #region 开始测量
 private void button1_Click(object sender, EventArgs e)
 {
     t1_Stop = false;
     if (t1.ThreadState == ThreadState.Unstarted)
     {
         t1.Start();
     }
     if (t1.ThreadState == ThreadState.Stopped || t1.ThreadState == ThreadState.Aborted)
     {
         t1 = new Thread(new ThreadStart(PlayThread));
         t1.Start();
     }
 }

 private void PlayThread()
 {
     int i = 0;
     t1_Stop = false;
     t1_Pause = false; // 初始化暂停标志变量

     while (!t1_Stop)
     {
         if (t1_Pause) // 检查暂停标志变量
         {
             // 等待直到暂停标志被清除或线程停止
             while (t1_Pause && !t1_Stop)
             {
                 Thread.Sleep(100); // 休眠一小段时间,避免过度占用CPU
             }
         }

         HOperatorSet.DispObj(ImageArr[i], windowID);
         HTuple Width = null, Height = null;
         HOperatorSet.GetImageSize(ImageArr[i], out Width, out Height);
         HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
         double CriRad = ImageMeasure(ImageArr[i]);

         string result = CriRad > 311 && CriRad < 313 ? "OK" : "NG";
         // 将测量数据添加到ListView
         AddDataToListView(i, CriRad, result);

         if (CriRad > 311 && CriRad < 313)
         {
             string filePath = @"OK\OK.txt"; // 指定完整路径,包括目录和文件名

             // 确保目录存在
             Directory.CreateDirectory(Path.GetDirectoryName(filePath));

             // 写入内容(如果文件不存在会自动创建)
             string ok = $" OK, 序号{i}零件测得半径:{CriRad}\n";
             File.AppendAllText(filePath, ok);
         }
         else
         {
             string filePath = @"NG\NG.txt"; // 指定完整路径,包括目录和文件名

             // 确保目录存在
             Directory.CreateDirectory(Path.GetDirectoryName(filePath));

             // 写入内容(如果文件不存在会自动创建)
             string ng = $" NG, 序号{i}零件测得半径:{CriRad}\n";
             File.AppendAllText(filePath, ng);
         }

         Thread.Sleep(1000);
         i++;
         if (i >= 8)
         {
             i = 0;
         }
     }
 }

 private void AddDataToListView(int index, double radius, string result)
 {
     if (this.InvokeRequired)
     {
         this.Invoke((MethodInvoker)delegate
         {
             ListViewItem item = new ListViewItem(index.ToString());
             item.SubItems.Add(radius.ToString());
             item.SubItems.Add(result);
             listView1.Items.Add(item);
         });
     }
     else
     {
         ListViewItem item = new ListViewItem(index.ToString());
         item.SubItems.Add(radius.ToString());
         item.SubItems.Add(result);
         listView1.Items.Add(item);
     }
 }

 private double ImageMeasure(HObject ho_ResultImage)
 {
     // 原有的测量代码逻辑保持不变
     HObject ho_ResultRegions = null;
     HObject ho_ResultConnectedRegions = null;
     HObject ho_ResultSelectedRegions1 = null;
     HObject ho_ResultCircle = null;
     HObject ho_ResultContour = null;

     HTuple hv_Width = null, hv_Height = null;

     HTuple hv_CirCleRadiusTolerance = new HTuple(100);
     HTuple hv_ResultArea = null, hv_ResultRow = null;
     HTuple hv_ResultColumn = null, hv_MetrologyCircleIndice = null;
     HTuple hv_CircleRadiusResult = null;
     HTuple hv_MetrologyHandle = new HTuple();

     HOperatorSet.GetImageSize(ho_ResultImage, out hv_Width, out hv_Height);

     // 开始测量
     HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
     HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

     // 特征提取
     HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegions, 3, 60);
     HOperatorSet.Connection(ho_ResultRegions, out ho_ResultConnectedRegions);
     HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions1,
         (new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
         0.9), (new HTuple(320000)).TupleConcat(1));
     HOperatorSet.AreaCenter(ho_ResultSelectedRegions1, out hv_ResultArea, out hv_ResultRow, out hv_ResultColumn);

     HOperatorSet.SetColor(windowID, "green");
     HOperatorSet.SetDraw(windowID, "margin");
     HOperatorSet.DispObj(ho_ResultImage, windowID);

     // 生成圆
     HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn, hv_Radius.D);
     // 把圆添加到模型中
     HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow,
         hv_ResultColumn, hv_Radius.D, hv_CirCleRadiusTolerance, 5, 1.5, 30, (new HTuple("measure_transition")).TupleConcat(
         "min_score"), (new HTuple("all")).TupleConcat(0.4), out hv_MetrologyCircleIndice);
     // 测量并拟合集合形状
     HOperatorSet.ApplyMetrologyModel(ho_ResultImage, hv_MetrologyHandle);

     HOperatorSet.GetMetrologyObjectResultContour(out ho_ResultContour, hv_MetrologyHandle,
         "all", "all", 1.5);
     // 在轮廓基础上获得此次测量的结果
     HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
         "all", "result_type", "radius", out hv_CircleRadiusResult);

     // 显示图像
     HOperatorSet.DispObj(ho_ResultImage, windowID);
     // 显示测量轮廓
     HOperatorSet.DispObj(ho_ResultContour, windowID);
     HOperatorSet.SetTposition(windowID, 0, 0);
     HOperatorSet.WriteString(windowID, "圆的半径:" + hv_CircleRadiusResult);
     HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);

     // 释放资源
     ho_ResultRegions.Dispose();
     ho_ResultConnectedRegions.Dispose();
     ho_ResultSelectedRegions1.Dispose();
     ho_ResultCircle.Dispose();
     ho_ResultContour.Dispose();

     // 返回结果
     return hv_CircleRadiusResult.D;
 }
 #endregion
   private void InitializeListView()
   {
       listView1.View = View.Details;
       listView1.GridLines = true;
       listView1.FullRowSelect = true;

       listView1.Columns.Add("编号", 80);
       listView1.Columns.Add("半径", 100);
       listView1.Columns.Add("结果", 100);
   }

这里hv_Radius.D来获取到我们模版圆的半径来绘制模版进行对比

其中我还加入了将测量结果分析后加载到listview控件中显示以及创建两个文件夹ok和ng分别存储不良和良品数据。

联合编程核心就是-------粘代码不要自己无脑写简化自己的操作

效果放在主页视频中了,退出按钮效果漏写了0.0

### 回答1: Halcon是一款工业视觉软件,可用于机器人视觉、自动化和品质控制等领域。而C语言作为一个底层语言,可以提供更高的性能和灵活性。 使用Halcon联合C,能够帮助开发者从底层开始构建自己的计算机视觉应用程序。C语言可以用来编写高效的算法,而Halcon则可以提供可视化编程界面和现成的图像处理函数库。开发者可以使用C语言实现自己的算法,然后将算法进行封装,以便在Halcon中使用。 使用Halcon联合C还有许多其他好处。例如,开发者可以利用C语言进行低级别的图像控制和数据_IO,然后使用Halcon进行高级别的控制(例如表面匹配,物体检测和识别,特征提取等)。 此外,Halcon联合C还可以帮助开发者提高性能并减少内存使用,尤其是在大型图像处理任务中。由于C语言提供更多的内存和速度控制,因此将其Halcon结合使用可以实现更多的资源优化。 总之,通过将HalconC结合使用,开发者可以在计算机视觉应用程序中获得性能和灵活性的最佳平衡。无论是将两者结合来创建底层算法,还是使用Halcon来实现高级别的控制,开发者都可以受益于这种组合。 ### 回答2: Halcon和C一起使用可以实现图像处理算法的高效开发和优化,从而实现高速、准确的图像处理和计算机视觉任务。Halcon作为一款成熟的图像处理软件,具有强大的图像处理算法库和用户界面,可以方便地进行图像采集、预处理、分析和展示。而C语言,则是一种通用、高效的编程语言,可以进行具有复杂性能要求的图像处理算法的优化和实现。Halcon提供了方便的接口,使得用户可以用C语言Halcon进行交互,实现自定义算法的快速开发和优化。同时,Halcon和C联合使用还可以实现对嵌入式设备或FPGA等硬件平台的支持,从而提高其运算速度和实现更多的计算能力。总而言之,Halcon和C的联合使用可以使得图像处理应用程序的开发更加高效和灵活,为许多领域,如机器视觉、自动化生产线、医疗影像等提供更好的解决方案。 ### 回答3: Halcon是一款强大的计算机视觉软件,具有很高的灵活性和可扩展性。Halcon可以其他软件和编程语言进行联合使用,其中包括C语言Halcon联合C语言的主要优点是,可以利用C语言进行高级算法的开发和优化,同时利用Halcon进行图像处理和计算机视觉应用的实现。这种联合使用可以提高程序的性能和效率,节省开发时间和成本。 Halcon提供了C语言进行集成的API接口,可以方便地进行数据传输和函数调用。同时,Halcon还支持C语言编写的DLL动态链接库,可以轻松地将Halcon集成到现有的C语言项目中。 除此之外,Halcon还提供了丰富的开发文档和示例程序,帮助开发人员快速掌握联合使用的技巧和方法。 综上所述,Halcon联合C语言可以充分发挥两者的优势,提高开发效率和程序性能,使图像处理和计算机视觉应用开发更加便捷和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值