Emgu CV3+C#图像处理(六):霍夫圆检测/线检测 & 矩形/三角形检测

环境Win7-64+VS2012+EmguCV3.0.0

霍夫圆检测

使用Hough变换在灰度图像中查找圆圈:HoughCircles()

public static CircleF[] HoughCircles(
    IInputArray image,//输入图像,8位单通道灰度图像
    HoughType method,//检测方法使用。目前,唯一实现的方法是CV_HOUGH_GRADIENT
    double dp,//累加器分辨率与图像分辨率的反比。例如,如果dp = 1,则累加器具有与输入图像相同的分辨率。如果dp = 2,则累加器的宽度和高度都是一半
    double minDist,//检测到的圆的中心之间的最小距离。太小会多检,太大会漏检
    double param1 = 100,//传递给Canny()检测器的两个阈值中的较高的阈值(较高的是较低的两倍左右)
    double param2 = 100,//检测阶段圆心的累加器阈值。越小,可得到越多的圆
    int minRadius = 0,//最小圆半径
    int maxRadius = 0//最大圆半径
)
示例

按照Emgu CV3+C#图像处理(一)新建一个C#控制台应用程序,然后引用相应的dll文件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Drawing;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using Emgu.CV.Util;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //从文件加载图像
            String imagePath = "E:\\image\\01.jpg";
            Image<Bgr, Byte> src = new Image<Bgr, byte>(@imagePath);
            CvInvoke.Imshow("src", src);
            //将图像转换为灰度
            UMat grayImage = new UMat();
            CvInvoke.CvtColor(src, grayImage, ColorConversion.Bgr2Gray);

            //使用高斯滤波去除噪声
            CvInvoke.GaussianBlur(grayImage, grayImage, new Size(5, 5), 3);
            //CvInvoke.Imshow("Blur Image", grayImage);
            //霍夫圆检测
            CircleF[] circles = CvInvoke.HoughCircles(grayImage, HoughType.Gradient, 2.0, 20.0, 100.0, 180.0, 5);
            #region draw circles
            Image<Bgr, Byte> circleImage = src.Clone();
            foreach (CircleF circle in circles)
                circleImage.Draw(circle, new Bgr(Color.Blue), 4);
            CvInvoke.Imshow("HoughCircles", circleImage);
            CvInvoke.WaitKey(0);
            #endregion
        }
    }
}

这里写图片描述
这里写图片描述

霍夫线检测

使用概率Hough变换在二进制图像中查找线段:HoughLinesP()

public static LineSegment2D[] HoughLinesP(
    IInputArray image,//8位单通道二进制图像
    double rho,//累加器的距离分辨率,以像素为单位
    double theta,累加器的角度分辨率,以弧度表示
    int threshold,//累加器阈值参数,只返回达到票数的
    double minLineLength = 0,//最小线长,过短的线段被放弃
    double maxGap = 0//在同一行上的点之间允许的最大距离
)
示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Drawing;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using Emgu.CV.Util;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //从文件加载图像
            String imagePath = "E:\\image\\line.jpg";
            Image<Bgr, Byte> src = new Image<Bgr, byte>(@imagePath);
            CvInvoke.Imshow("src", src);
            //将图像转换为灰度
            UMat grayImage = new UMat();
            CvInvoke.CvtColor(src, grayImage, ColorConversion.Bgr2Gray);
            //使用高斯滤波去除噪声
            CvInvoke.GaussianBlur(grayImage, grayImage, new Size(5, 5), 3);
            //CvInvoke.Imshow("Blur Image", grayImage);

            #region Lines detection
            UMat cannyEdges = new UMat();
            CvInvoke.Canny(grayImage, cannyEdges, 100, 120);
            //CvInvoke.Imshow("Canny Image", cannyEdges);
            LineSegment2D[] lines = CvInvoke.HoughLinesP(cannyEdges, 1, Math.PI / 20.0, 30, 80, 30);
            #endregion

            #region draw lines
            Image<Bgr, Byte> lineImage = src.Clone();
            foreach (LineSegment2D line in lines)
                lineImage.Draw(line, new Bgr(Color.HotPink), 2);
            CvInvoke.Imshow("lineImage", lineImage);
            CvInvoke.WaitKey();
            #endregion
        }
    }
}

这里写图片描述
这里写图片描述

矩形三角形检测

官方例程里有一个检测矩形三角形的,看着很不错,特此贴一下:

示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Drawing;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using Emgu.CV.Util;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //从文件加载图像
            String imagePath = "E:\\image\\010.jpg";
            Image<Bgr, Byte> src = new Image<Bgr, byte>(@imagePath);
            CvInvoke.Imshow("src", src);
            //将图像转换为灰度
            UMat grayImage = new UMat();
            CvInvoke.CvtColor(src, grayImage, ColorConversion.Bgr2Gray);
            //使用高斯滤波去除噪声
            CvInvoke.GaussianBlur(grayImage, grayImage, new Size(3, 3), 3);
            //CvInvoke.Imshow("Blur Image", grayImage);

            #region Canny and edge detection
            UMat cannyEdges = new UMat();
            CvInvoke.Canny(grayImage, cannyEdges, 60, 180);
            CvInvoke.Imshow("Canny Image", cannyEdges);
            #endregion


            #region Find triangles and rectangles
            List<Triangle2DF> triangleList = new List<Triangle2DF>();
            List<RotatedRect> boxList = new List<RotatedRect>(); //旋转的矩形框

            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                int count = contours.Size;
                for (int i = 0; i < count; i++)
                {
                    using (VectorOfPoint contour = contours[i])
                    using (VectorOfPoint approxContour = new VectorOfPoint())
                    {
                        CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.08, true);
                        //仅考虑面积大于50的轮廓
                        if (CvInvoke.ContourArea(approxContour, false) > 50) 
                        {
                            if (approxContour.Size == 3) //轮廓有3个顶点:三角形
                            {
                                Point[] pts = approxContour.ToArray();
                                triangleList.Add(new Triangle2DF(pts[0], pts[1], pts[2]));
                            }
                            else if (approxContour.Size == 4) //轮廓有4个顶点
                            {
                                #region determine if all the angles in the contour are within [80, 100] degree
                                bool isRectangle = true;
                                Point[] pts = approxContour.ToArray();
                                LineSegment2D[] edges = PointCollection.PolyLine(pts, true);

                                for (int j = 0; j < edges.Length; j++)
                                {
                                    double angle = Math.Abs(edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
                                    if (angle < 80 || angle > 100)
                                    {
                                        isRectangle = false;
                                        break;
                                    }
                                }
                                #endregion
                                if (isRectangle) boxList.Add(CvInvoke.MinAreaRect(approxContour));
                            }
                        }
                    }
                }
            }
            #endregion

            //显示结果
            #region draw triangles and rectangles
            Image<Bgr, Byte> triangleRectangleImage = src.CopyBlank();
            foreach (Triangle2DF triangle in triangleList)
                triangleRectangleImage.Draw(triangle, new Bgr(Color.DarkBlue), 2);

            CvInvoke.Imshow("triangleRectangleImage", triangleRectangleImage);

            Image<Bgr, Byte> RectangleImage = src.CopyBlank();
            foreach (RotatedRect box in boxList)
                RectangleImage.Draw(box, new Bgr(Color.DarkOrange), 2);

            CvInvoke.Imshow("RectangleImage", RectangleImage);
            CvInvoke.WaitKey();
            #endregion

        }
    }
}

这里写图片描述这里写图片描述
这里写图片描述这里写图片描述


Emgu CV Library Documentation::CvInvoke.HoughCircles Method
Emgu CV Library Documentation::CvInvoke.HoughLinesP Method
Emgu CV Library Documentation::Shape (Triangle, Rectangle, Circle, Line) Detection in CSharp

  • 10
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值