第2个C# Winform实例,寻找三角形的位置

这里,在第一个例子的基础上,稍微做修改,达到最终定位三角形位置的目的。

先在网络上找一张包含有三角形的图片,我们这里使用一张有三个三角形和一些标记的图片来处理。

原图:

 

先贴结果图片:左侧,中间,右侧寻找的位置如下,用红色圆形来包围。

基本处理思路:1:先用上一节的二值化进行预处理,这里由于目标三角形式黑色,所以使用反向阈值化。

相关代码:

  private void Tobinimg_inv(Mat inimg,out Mat binimg)
        {
            binimg = new Mat();
            try
            {

                if (inimg != null)
                {
                    //转灰度
                    Mat grayimg;
                    if (inimg.Channels() == 3)
                    {
                        grayimg = inimg.CvtColor(ColorConversionCodes.BGR2GRAY);

                    }
                    else
                    {
                        grayimg = inimg.Clone();
                    }
                    Imgwindow.Showimg(grayimg);
                    //bin
                    double dvalue = 0;
                    double.TryParse(textBox_ThreshValue.Text, out dvalue);
                    if (dvalue == 0)
                    {
                        dvalue = 10;
                    }

                    binimg = grayimg.Threshold(dvalue, 255, ThresholdTypes.BinaryInv);
                    Imgwindow.Showimg(binimg);
                    grayimg.Dispose();
                    // binimg.Dispose();

                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

阈值200,反向二值化的效果如下:

:

2:筛选轮廓特征,选中三个三角形,并根据位置要求来进行输出。

相关代码:

 /// <summary>
        /// 通过矩形选择contours
        /// </summary>
        /// <param name="contours"></param>
        /// <param name="Minvaluelow"></param>
        /// <param name="Minvalueup"></param>
        /// <param name="Maxvaluelow"></param>
        /// <param name="Maxvalueup"></param>
        /// <returns></returns>
        public  List<OpenCvSharp.Point[]> SelectContoursByRect(Mat binimg, double Minvaluelow, double Minvalueup, double Maxvaluelow, double Maxvalueup)
        {
            OpenCvSharp.Point[][] contours;
            HierarchyIndex[] hierarchy;
            Cv2.FindContours(binimg, out contours, out hierarchy, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple);
            List<OpenCvSharp.Point[]> Resultcontours = new List<OpenCvSharp.Point[]>();
            int L = contours.Length;
            for (int i = 0; i < L; i++)
            {
                Rect recttemp = Cv2.BoundingRect(contours[i]);
                double Hmin, Wmax;
                Hmin = Math.Min(recttemp.Width, recttemp.Height);
                Wmax = Math.Max(recttemp.Width, recttemp.Height);
                if (Hmin > Minvaluelow && Hmin < Minvalueup && Wmax > Maxvaluelow && Wmax < Maxvalueup)
                {
                    //满足指定要求的contours
                    Resultcontours.Add(contours[i]);
                }
            }
            return Resultcontours;
        }
     private List<OpenCvSharp.Point[]> SelectContoursByRectPos(List<OpenCvSharp.Point[]> inputcontours,int pos)
        {
            List<OpenCvSharp.Point[]> resultpoints = new List<OpenCvSharp.Point[]>();
            try
            {
                
                List<float> colposition = new List<float>();
                for (int i = 0; i < inputcontours.Count; i++)
                {
                    Point2f cp;
                    float r;
                    Cv2.MinEnclosingCircle(inputcontours[i],out cp,out r);

                    colposition.Add(cp.X);
                }
              int Right=  colposition.IndexOf(colposition.Max());
              int Left= colposition.IndexOf(colposition.Min());              
                int Middle = 3 - Right - Left;
                switch (pos)
                {
                    case 0:
                        //左侧
                        resultpoints.Add( inputcontours[Left]);
                        break;
                    case 1:
                        resultpoints.Add(inputcontours[Middle]);
                        //中间
                        break;
                    case 2:
                        resultpoints.Add(inputcontours[Right]);
                        //右侧
                        break;
                    default:
                        break;

                }
                return resultpoints;
            }
            catch(Exception ex)
            {
                return resultpoints;
                throw (ex);
               
            }

        }

目标位置绘图,

相关代码:

 if(onecontours.Count==1)
                    {
                        Point2f cp;
                        float r;
                        Cv2.MinEnclosingCircle(onecontours[0], out cp, out r);
                        //
                        Mat backimg = img.Clone();
                        Cv2.Circle(backimg, new OpenCvSharp.Point(cp.X,cp.Y), (int)r, Scalar.Red);
                        Imgwindow.Showimg(backimg);
                        backimg.Dispose();
                    }

通过以上就完成了三角形的定位,当然,其他定位你可以发挥你的能力,把握对象特点,选定合适的处理方法,所谓条条大路通罗马,我们的目的就能达到。

如果需要源代码,请留言。谢谢。如果你有其他的图片项目,欢迎交流。本文只做学习之用。

 

posted on 2019-07-26 13:28  半路敲代码  阅读(1857)  评论(1编辑  收藏  举报

导航