public Mat _01_DetectGrid4(Mat imgWhiteB, Mat imgBlackW, byte thValue, out Point2d[] Q4fnd, bool DispB) { //Acquiring convex hull //Coordinate list of contour Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(imgBlackW, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple); Size sz = imgWhiteB.Size(); int W = sz.Width, H = sz.Height, WW = (int)Math.Min(W * 0.4, H * 0.4); try{ Mat checkImg = imgWhiteB.CvtColor(ColorConversionCodes.GRAY2BGR); //###### Gray->Color foreach (var PP in contours.Where(p => p.Count() >= 4)) { double Xmin = PP.Min(p => p.X); double Xmax = PP.Max(p => p.X); double Ymin = PP.Min(p => p.Y); double Ymax = PP.Max(p => p.Y); if ((Xmax - Xmin) < WW || (Ymax - Ymin) < WW) { continue; } //convex hull (clockwise:true counterclockwise) var P = Cv2.ConvexHull(PP, clockwise: true).ToList(); double area = Cv2.ContourArea(P); //Area of convex hull //if(area<WW*WW) continue; List <Point2d> P2 = P.ConvertAll(q => new Point2d(q.X, q.Y)); Mat stdImg = CorrectDistortion(imgWhiteB, P2, out Point2d[] Q4, DispB: false); Q4fnd = Q4; if (stdImg == null) { return(null); } return(stdImg); } } catch (Exception e) { WriteLine(e.Message + "\r" + e.StackTrace); } Q4fnd = null; return(null); }