这里,在第一个例子的基础上,稍微做修改,达到最终定位三角形位置的目的。
先在网络上找一张包含有三角形的图片,我们这里使用一张有三个三角形和一些标记的图片来处理。
原图:
先贴结果图片:左侧,中间,右侧寻找的位置如下,用红色圆形来包围。
基本处理思路: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(); }
通过以上就完成了三角形的定位,当然,其他定位你可以发挥你的能力,把握对象特点,选定合适的处理方法,所谓条条大路通罗马,我们的目的就能达到。
如果需要源代码,请留言。谢谢。如果你有其他的图片项目,欢迎交流。本文只做学习之用。