private bool PlusCondition(Mat tempROI) { bool flag = false; Cv2.Threshold(tempROI, tempROI, 200, 255, ThresholdTypes.BinaryInv); //反向二值化 var tempContours = new OpenCvSharp.Point[][] { }; var tempHierarchy = new OpenCvSharp.HierarchyIndex[] { }; Cv2.FindContours(tempROI, out tempContours, out tempHierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone); //对于每一个tempROI,对于箭头 或者 判断是否符合条件 if (tempContours.GetLength(0) == 4) { var pointListX = new List <double>();//4个轮廓中心点 var pointListY = new List <double>(); var euDisList = new List <double>(); double sumX = 0, sumY = 0; for (int i = 0; i < 4; i++) { var M = Cv2.Moments(tempContours[i]); if (M.M00 != 0) { var cx = (M.M10 / M.M00); var cy = (M.M01 / M.M00); pointListX.Add(cx); pointListY.Add(cy); sumX += cx; sumY += cy; } else { return(false); } } var centerPointX = sumX / 4; var centerPointY = sumY / 4; for (int i = 0; i < 4; i++) { euDisList.Add(Math.Pow(Math.Pow(Math.Abs(centerPointX - pointListX[i]), 2) + Math.Pow(Math.Abs(centerPointY - pointListY[i]), 2), 0.5)); } var stdDev = CalculateStdDev(euDisList); if (stdDev < 0.12) { flag = true; // Console.WriteLine(stdDev); } } return(flag); }
private List <Rect> ConditionNMS(Mat binaryImg, ref List <int> orientationList) { var rectList = new List <Rect>(); var indexer = binaryImg.GetGenericIndexer <Vec3b>(); var contours = new OpenCvSharp.Point[][] { }; var hierarchy = new OpenCvSharp.HierarchyIndex[] { }; var contourAreaList = new List <double>() { }; var contourCenterList = new List <System.Drawing.Point>() { }; Cv2.FindContours(binaryImg, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone); for (int i = 0; i < hierarchy.Length; i++) { var M = Cv2.Moments(contours[i]); if (M.M00 != 0) { var cx = (int)(M.M10 / M.M00); var cy = (int)(M.M01 / M.M00); if (indexer[cy, cx].Item0 == 255) { var rect = Cv2.BoundingRect(contours[i]); if (indexer[rect.Y, rect.X].Item0 == 0 && indexer[rect.Y + rect.Height, rect.X + rect.Width].Item0 == 0 && indexer[rect.Y + rect.Height, rect.X].Item0 == 0 && indexer[rect.Y, rect.X + rect.Width].Item0 == 0 && rect.Width / rect.Height > 4 && rect.Width > 40) { //Rect r = new Rect(new OpenCvSharp.Point(rect.X, rect.Y), new OpenCvSharp.Size(rect.Width, rect.Height)); //Cv2.Rectangle(binaryImg, r, Scalar.LimeGreen, 1); //Cv2.DrawContours(srcImg, contours, i, Scalar.Gray, 2, LineTypes.Link8, hierarchy, 4); var point1 = new OpenCvSharp.Point(cx, cy); Cv2.FloodFill(binaryImg, point1, new Scalar(155, 155, 155)); var tempROI = new Mat(); binaryImg[rect].CopyTo(tempROI);//截出连通域, 按中心点做漫水填充 int orientation = 0; /////////////// Vec3b color = new Vec3b(0, 0, 0); int sLeft = 0, sRight = 0; var ROIIndexer = tempROI.GetGenericIndexer <Vec3b>(); for (int k = 0; k < tempROI.Rows; k++) { for (int j = 0; j < tempROI.Cols; j++) { if (ROIIndexer[k, j].Item0 == 255) { ROIIndexer[k, j] = color; continue; } else if (ROIIndexer[k, j].Item0 == 155) { if (j < tempROI.Cols / 2) { sLeft++; } else { sRight++; } } } } Cv2.Threshold(tempROI, tempROI, 154, 255, ThresholdTypes.BinaryInv); if (sLeft < sRight) { orientation = 1; //正向箭头 } ////////////////// var tempContours = new OpenCvSharp.Point[][] { }; var tempHierarchy = new OpenCvSharp.HierarchyIndex[] { }; Cv2.FindContours(tempROI, out tempContours, out tempHierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone); if (tempContours.GetLength(0) == 4 && Math.Abs(sLeft - sRight) > 10) { rectList.Add(rect); orientationList.Add(orientation); } } } } } return(rectList); }