求出轮廓多边形的Size进行筛选并绘制轮廓

来源:互联网 发布:金蝶智慧记 知乎 编辑:程序博客网 时间:2024/05/16 06:56

代码:

            OpenFileDialog of = new OpenFileDialog();
            if (of.ShowDialog() != DialogResult.OK)
            { return; }
            Image<Gray, byte> img = new Image<Gray, byte>(of.FileName);
            Mat dst1 = new Mat();
            CvInvoke.Canny(img, dst1, 120, 180);//查找轮廓 
            imageBox2.Image = dst1;
            VectorOfVectorOfPoint vvp = new VectorOfVectorOfPoint();
            VectorOfVectorOfPoint use_vvp = new VectorOfVectorOfPoint();
            CvInvoke.FindContours(dst1, vvp, null, Emgu.CV.CvEnum.RetrType.List    /*提取最外层轮廓,经常使用也有取所有轮廓List*/, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);//轮廓提取
            int number = vvp.ToArrayOfArray().Length;//取得轮廓的数量.
            for (int i = 0; i < number; i++)
            {
                VectorOfPoint vp = vvp[i];
                VectorOfPoint approx_vp = new VectorOfPoint();
                CvInvoke.ApproxPolyDP(vp , approx_vp, CvInvoke.ArcLength(vp, false) * 0.05, true);//计算周长
                //经常几何逼近,精度为连通域轮廓周长的0.05倍
               if (approx_vp.Size >3)//以实际的图片按周长进行筛选
                { 
                   use_vvp.Push(vp); }
            }
            Mat result = new Mat(img.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 3);
            result.SetTo(new MCvScalar(0, 0, 0));
            CvInvoke.DrawContours(result, use_vvp, -1, new MCvScalar(0, 255, 0));//绘制轮廓
            imageBox3.Image = result;
            imageBox1.Image = img;


API:

 /// <summary>
        /// Canny算法查找输入图像上的轮廓查找
        /// </summary>
        /// <param name="image">源图</param>
        /// <param name="edges">输出图像</param>
        /// <param name="threshold1">第一个阈值</param>
        /// <param name="threshold2">第二个阈值</param>
        /// <param name="apertureSize">光圈大小:用Sobel算子孔径参数(默认)</param>
        /// <param name="l2Gradient">一个标志位,指示是否应该使用一个更精确的规范来计算图像的梯度幅值(l2gradient = true),或是默认(l2gradient = false)</param>
        public static void Canny(IInputArray image, IOutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool l2Gradient = false);
       

        /// <summary>
        /// 提取轮廓
        /// </summary>
        /// <param name="image">输入一个二进制的图像</param>
        /// <param name="contours">输出的是一个轮廓图像</param>
        /// <param name="hierarchy">可选择的输出向量,包含图像的拓扑信息不使用的时候可以用null填充,每个独立的轮廓(连通域)对应4个hieratchy元素</param>
        /// <param name="mode">枚举类型  轮廓检索模式</param>
        /// <param name="method">枚举类型 轮廓近似方法</param>
        /// <param name="offset">每个轮廓 点的偏移量,对RoI图像中长出轮廓,并要在整片中分析,那第就会使用到这个偏移量</param>
     public static void FindContours(IInputOutputArray image, IOutputArray contours, IOutputArray hierarchy, RetrType mode, ChainApproxMethod method, Point offset = null);

        /// <summary>
        /// 绘制轮廓
        /// </summary>
        /// <param name="image">输入一个图片,也是传出来的图片</param>
        /// <param name="contours">new VectorOfVectorOfPoint</param>
        /// <param name="contourIdx">-1为绘制所有轮廓</param>
        /// <param name="color">绘制轮廓的颜色</param>
        /// <param name="thickness">线宽</param>
        /// <param name="lineType">defult</param>
        /// <param name="hierarchy">defult</param>
        /// <param name="maxLevel">defult</param>
        /// <param name="offset">defult</param>
        //public static void DrawContours(IInputOutputArray image, IInputArrayOfArrays contours, int contourIdx, MCvScalar color, int thickness = 1, LineType lineType = LineType.EightConnected, IInputArray hierarchy = null, int maxLevel = 2147483647, Point offset = null);

        /// <summary>
        /// 使用特定精度逼近多边形.
        /// </summary>
        /// <param name="curve">输入需要逼近的轮廓,VectorOfPoint</param>
        /// <param name="approxCurve">逼近的结果,与输入的类型一致.</param>
        /// <param name="epsilon">逼近精度</param>
        /// <param name="closed">是否封闭多边形</param>
        public static void ApproxPolyDP(IInputArray curve, IOutputArray approxCurve, double epsilon, bool closed);

       /// <summary>
        /// 返回double类型的长度
        /// </summary>
        /// <param name="curve">输入计算周长的轮廓,类型为VectorOfPoint</param>
        /// <param name="isClosed">表示计算周长的轮廓是否封闭.isClosed=true:计算封闭轮廓 的周长</param>
        /// <returns></returns>
       public static double ArcLength(IInputArray curve, bool isClosed);




0 0
原创粉丝点击