這里,在第一個例子的基礎上,稍微做修改,達到最終定位三角形位置的目的。
先在網絡上找一張包含有三角形的圖片,我們這里使用一張有三個三角形和一些標記的圖片來處理。
原圖:
先貼結果圖片:左側,中間,右側尋找的位置如下,用紅色圓形來包圍。
基本處理思路: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(); }
通過以上就完成了三角形的定位,當然,其他定位你可以發揮你的能力,把握對象特點,選定合適的處理方法,所謂條條大路通羅馬,我們的目的就能達到。
如果需要源代碼,請留言。謝謝。如果你有其他的圖片項目,歡迎交流。本文只做學習之用。