C# HalconDotNet 工业视觉处理

1.引入Halcon组件

C# HalconDotNet 工业视觉处理_第1张图片

2.项目配置文件

  
    
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
      
    
  

 

3.页面配置

C# HalconDotNet 工业视觉处理_第2张图片

4.halcon接口调用

    public partial class HDevelopExport
    {
        public int ResultN;
        public double usedTime;
        public double[] Px;
        public double[] Py;
        public double Fx, Fy;
        public double Cr = 9;
        public double Cx, Cy;
        public bool IsStart = false;

        HTuple hv_R;
        List Aa = new List();
        HTuple hv_Angle, hv_Score, hv_Runtime;
        HTuple hv_ModelID, hv_Row, hv_Column;

        HObject ho_Mask;
        HTuple hv_S1, hv_S2;
        HObject ho_Image, ho_Rectangle, ho_ImageReduced;
        public HTuple hv_ExpDefaultWinHandle;
        HWindowControl HWindowControl;

        /// 
        /// 打开相机
        /// 
        public void OpenCamera()
        {
            //hv_ExpDefaultWinHandle = Window;
            HOperatorSet.GenEmptyObj(out ho_Image); // 生ho_Image数据区
            // Grabbing images from a Daheng USB 2.0 camera
            HOperatorSet.CloseAllFramegrabbers();
            HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
                -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_Angle);
            HOperatorSet.SetFramegrabberParam(hv_Angle, "tilt", -3);
            HOperatorSet.GrabImageStart(hv_Angle, -1);
            //open camera with default settings
        }

        /// 
        /// 关闭相机
        /// 
        public void CloseCamera()
        {
            HOperatorSet.CloseAllFramegrabbers();
        }

        /// 
        /// 实时播放
        /// 
        public void RealTimePlayback()
        {
            IsStart = true;
            //HObject ho_Image = null;

            //HTuple hv_AcqHandle = new HTuple();
             Initialize local and output iconic variables 
            //HOperatorSet.GenEmptyObj(out ho_Image);
            Image Acquisition 01: Code generated by Image Acquisition 01
            //HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
            //    -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_AcqHandle);
            //HOperatorSet.GrabImageStart(hv_AcqHandle, -1);

            Task task = new Task(() =>
            {
                while (IsStart)
                {
                    ho_Image.Dispose();
                    
                    HOperatorSet.GrabImageAsync(out ho_Image, hv_Angle, -1);
                    HTuple hv_Width, hv_Height;
                    HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height); // 获取图片的尺寸

                    double ratioWidth = (1.0) * hv_Width[0].I / HWindowControl.Width;
                    double ratioHeight = (1.0) * hv_Height[0].I / HWindowControl.Height;
                    HTuple row1, column1, row2, column2;
                    if (ratioWidth >= ratioHeight)
                    {
                        row1 = -(1.0) * ((HWindowControl.Height * ratioWidth) - hv_Height) / 2;
                        column1 = 0;
                        row2 = row1 + HWindowControl.Height * ratioWidth;
                        column2 = column1 + HWindowControl.Width * ratioWidth;
                        HOperatorSet.SetPart(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
                        HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
                    }
                }
            });
            task.Start();
        }

        /// 
        /// 拍照
        /// 
        public void Photograph()
        {
            IsStart = true;
            

            HTuple hv_Width, hv_Height;
            ho_Image.Dispose(); // 清除ho_Image中的数据
            HOperatorSet.GrabImage(out ho_Image, hv_AcqHandle); // 采集图像
            HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height); // 获取图片的尺寸

            double ratioWidth = (1.0) * hv_Width[0].I / HWindowControl.Width;
            double ratioHeight = (1.0) * hv_Height[0].I / HWindowControl.Height;
            HTuple row1, column1, row2, column2;
            if (ratioWidth >= ratioHeight)
            {
                row1 = -(1.0) * ((HWindowControl.Height * ratioWidth) - hv_Height) / 2;
                column1 = 0;
                row2 = row1 + HWindowControl.Height * ratioWidth;
                column2 = column1 + HWindowControl.Width * ratioWidth;


                HOperatorSet.SetPart(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
                HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);

                // 显示ho_Image中的图片
                HOperatorSet.SetDraw(hv_ExpDefaultWinHandle, "margin"); // 填充模式为只画框
                HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red"); // 画线颜色红
                HOperatorSet.DispRectangle1(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
            }
        }

        /// 
        /// 初始化相机
        /// 
        public void InitHalcon()
        {
            // Default settings used in HDevelop 
            HOperatorSet.SetSystem("width", 512);
            HOperatorSet.SetSystem("height", 512);
        }

        /// 
        /// 初始化Halcon
        /// 
        /// 
        public void RunHalcon(HWindowControl Window)
        {
            HWindowControl = Window;
            hv_ExpDefaultWinHandle = Window.HalconWindow;
        }

        /// 
        /// 设置模板
        /// 
        public void SetTemplate()
        {
            HTuple hv_Row1, hv_Column1, hv_Row2, hv_Column2;

            MessageBox.Show("在红框中按下鼠标左键画方框选模板,按右键结束");
            HOperatorSet.DrawRectangle1(hv_ExpDefaultWinHandle,
            out hv_Row1, out hv_Column1, out hv_Row2, out hv_Column2);
            HOperatorSet.GenRectangle1(out ho_Rectangle, hv_Row1, hv_Column1, hv_Row2, hv_Column2);
            HOperatorSet.ReduceDomain(ho_Image, ho_Rectangle, out ho_ImageReduced);
            HOperatorSet.WriteImage(ho_ImageReduced, "png", 0, "E:/test.png");
            MessageBox.Show("模板已保存");
        }


        /// 
        /// 从文件中读取模板
        /// 
        public void ReadTemplate()
        {
            HOperatorSet.GenEmptyObj(out ho_ImageReduced);
            ho_ImageReduced.Dispose();
            HOperatorSet.ReadImage(out ho_ImageReduced, "E:/test.png");
        }

        /// 
        /// 模板匹配
        /// 
        public void MatchTemplate()
        {
            int i, j;
            double temp;

            HOperatorSet.GenRectangle1(out ho_Rectangle, 320, 250, 630, 750);
            HOperatorSet.ReduceDomain(ho_Image, ho_Rectangle, out ho_Mask);

            //Reduce image range
            HOperatorSet.CreateShapeModel(ho_ImageReduced, "auto", (new HTuple(-45)).TupleRad(), (new HTuple(90)).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto", out hv_ModelID);
            HOperatorSet.CountSeconds(out hv_S1); // Match start
            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);

            HOperatorSet.CountSeconds(out hv_S2); // Match stop
            hv_Runtime = (hv_S2 - hv_S1) * 1000;
            usedTime = hv_Runtime;
            ResultN = new HTuple(hv_Row.TupleLength());

            

            // 获取匹配结果个数
            if (ResultN > 0)
            {
                Px = new double[ResultN];
                Py = new double[ResultN];
                hv_R = new HTuple(); //HTuple变量初始化
                for (i = 0; i < ResultN; i++)
                {
                    Py[i] = hv_Row[i]; // 将搜索结果的中心坐标读出
                    Px[i] = hv_Column[i];
                    Aa.Add(hv_Angle[i]);
                    hv_R[i] = 8; //设置圆半径
                }

                for (i = 0; i < ResultN; i++) // 从大到小排序
                {
                    for (j = i + 1; j < ResultN; j++)
                    {
                        if (Px[i] < Px[j])
                        {
                            temp = Px[i];
                            Px[i] = Px[j];
                            Px[j] = temp;
                            temp = Py[i];
                            Py[i] = Py[j];
                            Py[j] = temp;
                            temp = Aa[i];
                            Aa[i] = Aa[j];
                            Aa[j] = temp;
                        }
                    }
                }

                HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red"); // 显示匹配结果位置
                HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, hv_Row, hv_Column, hv_R);
                HOperatorSet.ClearShapeModel(hv_ModelID);
                Cy = Py[0] + 10; // offset的初始值
                Cx = Px[0] + 60;
            }
            else
            {
                MessageBox.Show("匹配失败!?");
            }
        }

        /// 
        /// 显示偏移点位置
        /// 
        public void DisplayOffset()
        {
            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red");
            HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
            HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, hv_Row, hv_Column, hv_R);
            HOperatorSet.DispLine(hv_ExpDefaultWinHandle, hv_Row[0], hv_Column[0], hv_Row[1], hv_Column[1]);
            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "yellow");
            HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, Cy, Cx, Cr);
        }

        /// 
        /// /显示计算角度,划线
        /// 
        public void DisplayLine()
        {
            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "yellow");
            HOperatorSet.DispLine(hv_ExpDefaultWinHandle, Cy, Cx, Fy, Fx);
        }
    }

 

5.form1cs页面

        public Form1()
        {
            InitializeComponent();

            timer1.Tick += Timer1_Tick;
            timer1.Interval = 5000;
            this.Controls.Add(hWindowControl1);
            hWindowControl1.Location = new System.Drawing.Point(20, 20);
            hWindowControl1.Width = 500;
            hWindowControl1.Height = 500;
            hd.InitHalcon();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            hd.RunHalcon(hWindowControl1); // 摄像头初始化
        }
        /// 
        /// 打开相机
        /// 
        /// 
        /// 
        private void btnOpenCamera_Click(object sender, EventArgs e)
        {
            hd.OpenCamera();
            textBox1.Text = "";
            textBox1.Refresh();
        }
        /// 
        ///关闭相机
        /// 
        /// 
        /// 
        private void btnCloseCamera_Click(object sender, EventArgs e)
        {
            hd.CloseCamera();
        }
        /// 
        /// 匹配
        /// 
        /// 
        /// 
        private void btnMatch_Click(object sender, EventArgs e)
        {
            int j, m;
            double d;
            double[] x;
            double[] y;

            hd.MatchTemplate(); // 图像匹配
            m = hd.ResultN;
            x = new double[m];
            y = new double[m];
            for (j = 0; j < m; j++) // 获取匹配坐标
            {
                x[j] = hd.Px[j];
                y[j] = hd.Py[j];
            }
            textBox1.Text = "匹配时间:" + hd.usedTime.ToString("#####.##") + " ms" + "\r\n" + "\r\n";
            for (j = 0; j < m; j++)
            {
                if (j < m - 1) // 计算2点距离
                {
                    d = (y[j + 1] - y[j]) * (y[j + 1] - y[j]) + (x[j + 1] - x[j]) * (x[j + 1] - x[j]);
                    d = Math.Sqrt(d);
                    d = 0.0485 * d;
                    textBox1.Text = textBox1.Text + "d(" + Convert.ToString(j + 1) + ") = " + d.ToString("#####.##")+ "mm" + "\r\n";
                }
                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";
            }
        }
        /// 
        /// 设置模板
        /// 
        /// 
        /// 
        private void btnTemplate_Click(object sender, EventArgs e)
        {
            hd.SetTemplate();
        }

        /// 
        /// 加载模板
        /// 
        /// 
        /// 
        private void btnLoadTemplate_Click(object sender, EventArgs e)
        {
            hd.ReadTemplate();
        }
        /// 
        /// 实时播放
        /// 
        /// 
        /// 
        private void btnPlayback_Click(object sender, EventArgs e)
        {
            hd.RealTimePlayback();
        }

        /// 
        /// 显示结果
        /// 
        /// 
        /// 
        private void btnDisplayResults_Click(object sender, EventArgs e)
        {
            double a, b, c, d, m, n;
            double alpha, beta;
            a = hd.Px[0];
            b = hd.Py[0];
            c = hd.Px[0];
            d = hd.Py[0];
            alpha = Math.Atan((d - b) / (c - a));
            beta = theta + alpha;
            m = a + Lam * Math.Cos(beta);
            n = b + Lam * Math.Sin(beta);
            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);

            hd.Cx = m;
            hd.Cy = n;
            hd.Fx = m - 600 * Math.Cos(alpha); // 计算夹角斜线的终点坐标
            hd.Fy = n - 600 * Math.Sin(alpha);
            hd.DisplayOffset(); // 显示插针位置
            hd.DisplayLine(); // 显示工件夹角
        }
        /// 
        /// 拍照
        /// 
        /// 
        /// 
        private void btnPhotograph_Click(object sender, EventArgs e)
        {
            hd.Photograph();
        }

 

 

C# HalconDotNet 工业视觉处理_第3张图片

你可能感兴趣的:(C#,视觉,偏移)