工业视觉_59:霍夫(Hough)两个圆及其圆心距检测

 /* 工业视觉_59:霍夫(Hough)两个圆及其圆心距检测
           * 确定半径R的圆的检测,在工业生产中会用得更多.
           * 工业视觉,目标很明确:快,准,稳. 快:开发快,运行速度快;准:高精度;稳:稳健
           * 所以,目前"机器换人"项目大多采用工控电脑,搭建 Windows7+VS2019+EMGU(或AForge+Accord),这一方案见效最快.
           * Hacon,Emgu的视觉库都很强大,而AForge+Accord库更全面更丰富(如:数学,人工智能,机器学习).
           * 圆识别是工业视觉的入门,它常常包括两圆的几何关系:位置关系(外切,内切,外离,内离,相交).交相时的交点坐标等.
           * 圆的方程有直角坐标系与极坐标系两种.
           * Hough算法的核心思想是,在所有白色的点都画低灰度的圆,再进行大量的投票统计,圆心处一般丰度很高.
           * 另一思路:每取不在同一直线上的三点,找出二线段中垂线的交点,再计算圆心与半径,进行投票也是可行的,关键是速度与效益.
           * 在自动化行业的机器视觉,常常与机器人或车床协作,如钻孔,激光切割,计算各类数据都是必需的.
           * 霍夫(Hough)圆检测的官方参考(C#语言)在:
           http://accord-framework.net/docs/html/T_Accord_Imaging_HoughCircle.htm
                                  ---------     编撰:    项道德(微信:daode1212),2021-07-07
           */

            pictureBox1.Image = Image.FromFile("2D106_直线与圆.jpg"); //
            Bitmap bmp = (Bitmap)(pictureBox1.Image);
            int ww = bmp.Width;
            int hh = bmp.Height;
            //自定义函数MSG("")为内置函数MessageBox.Show("")的简写方式;
            MSG("图片宽度与高度:\r\n" + string.Format("w={0},h={1}", ww, hh) + "\r\n 接着,呈现处理结果");


            var gray = new Accord.Imaging.Filters.Grayscale(0.3, 0.6, 0.1).Apply(bmp); //转为灰度位图
            //gray = new Accord.Imaging.Filters.Threshold(100).Apply(gray);//调节亮度阈值
            //gray = new Accord.Imaging.Filters.Invert().Apply(gray);//翻转成:背景黑色,线段为白色. 若已经是背景黑色,线段为白色的图片不用再翻转        

            //转为非托管数据:
            Accord.Imaging.UnmanagedImage image = Accord.Imaging.UnmanagedImage.FromManagedImage(gray);

            //建立霍夫变换器(图片中一个圆的半径是93,另一圆的半径是157):
            List<HoughCircle[]> LH = new List<HoughCircle[]>();
            for (int r = 93; r <= 157; r+=(157-93))
            {
                HoughCircleTransformation circleTransform = new HoughCircleTransformation(r);

                //应用霍夫变换:
                circleTransform.ProcessImage(image);
                Bitmap houghCirlceImage = circleTransform.ToBitmap();
                pictureBox1.Image = houghCirlceImage;
                MSG("投票数据影像,确定后继续");

                //根据相对丰度获取圆: 
                HoughCircle[] circles = circleTransform.GetCirclesByRelativeIntensity(0.9);

                LH.Add(circles);
            }
            
            //创建非托管24位数据:
            var bmpData = Accord.Imaging.UnmanagedImage.Create(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb);
            //转到托管图像后,添加一些标注与注释:
            Bitmap bmp2 = bmpData.ToManagedImage();
            Graphics g = Graphics.FromImage(bmp2);
            Pen pen0 = new Pen(Color.FromArgb(255, 0, 0), 2);
            Pen pen1 = new Pen(Color.FromArgb(220, 220, 220), 2);
            Pen pen2 = new Pen(Color.FromArgb(0, 0, 220), 4);
            
            SolidBrush bh = new SolidBrush(Color.Bisque);
            string txt = "Radius\tCenter(x,y)";
            List<PointF> PP = new List<PointF>();//记录圆心
            foreach (var circles in LH)
            {
                foreach (HoughCircle circle in circles)
                {
                    txt += "\r\n" + circle.Radius + "\t(" + circle.X + "," + circle.Y + ")";
                    g.DrawEllipse(pen0, circle.X - circle.Radius, circle.Y - circle.Radius, 2 * circle.Radius, 2 * circle.Radius);
                    g.DrawEllipse(pen1, circle.X - 4, circle.Y - 4, 8, 8);//圆心
                    //标出半径:
                    g.DrawLine(pen2, circle.X, circle.Y,circle.X+ circle.Radius, circle.Y);                    
                    g.DrawString(string.Format("{0:#.##}", circle.Radius), new Font("", 14), bh, circle.X + circle.Radius/3, circle.Y-14);
                    PP.Add(new PointF(circle.X , circle.Y));
                }
            }
            g.DrawLine(pen1, PP.ElementAt(0), PP.ElementAt(1));
            double dis = Math.Sqrt((PP.ElementAt(1).X- PP.ElementAt(0).X) *(PP.ElementAt(1).X - PP.ElementAt(0).X) +(PP.ElementAt(1).Y - PP.ElementAt(0).Y) *(PP.ElementAt(1).Y - PP.ElementAt(0).Y));
            txt += "\r\n圆心距:" + dis;
            //计算连线的中点,打印文本:
            float xt = (PP.ElementAt(1).X + PP.ElementAt(0).X) / 2;
            float yt = (PP.ElementAt(1).Y + PP.ElementAt(0).Y) / 2;
            g.DrawString(string.Format("{0:#.##}",dis), new Font("", 14), bh, xt, yt-14);//标注圆心距

            g.DrawString("霍夫(Hough)两个圆及其圆心距检测", new Font("", 12), bh, bmp2.Width/3,bmp2.Height-50);

            textBox1.Text = txt;
            pictureBox1.Image = bmp2;

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值