C # Winform second instance, to find the position of the triangle

Here, on the basis of the first example, making changes slightly, to achieve final positioning of the position of the triangle.

First find on the Web contains a picture of a triangle, here we use a card with three triangles and a few markers picture to deal with.

Original:

 

First posted image Results: left, center, right side position of the search as follows, with a red circle surrounded.

The basic idea of ​​processing: 1: first used binarizing a preprocess, where since the target black triangular form, the use of the reverse threshold.

The relevant code:

  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();
                    }

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

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

 

Guess you like

Origin www.cnblogs.com/banluqiaodaima/p/11249741.html