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(); }
通过以上就完成了三角形的定位,当然,其他定位你可以发挥你的能力,把握对象特点,选定合适的处理方法,所谓条条大路通罗马,我们的目的就能达到。
如果需要源代码,请留言。谢谢。如果你有其他的图片项目,欢迎交流。本文只做学习之用。