public PointCluster ToPointCluster() { var cluster = new PointCluster(); foreach (var line in lines) { foreach (var span in line.scans) { for (var x = span.X; x <= span.Y; x++) { cluster.points.Add(new Point(x, line.y)); } } } return(cluster); }
/// <summary> /// вернуть координаты точки или null, если точка не распознана /// возвращает самую удаленную точку кластера, если его размер больше заданного, /// либо центр кластера /// </summary> public Point?GetSpotPosition(Bitmap img) { var clusters = PointCluster.FindClusters(img, spotDescriptor); if (clusters.Count == 0) { return(null); } if (clusters.Count == 1) {// м.б. имеем выраженную точку int minX = int.MaxValue, maxX = int.MinValue; int minY = int.MaxValue, maxY = int.MinValue; foreach (var pt in clusters[0].points) { if (pt.X < minX) { minX = pt.X; } else if (pt.X > maxX) { maxX = pt.X; } if (pt.Y < minY) { minY = pt.Y; } else if (pt.Y > maxY) { maxY = pt.Y; } } int wd = maxX - minX, ht = maxY - minY; var sz = wd > ht ? wd : ht; if (sz <= spotDescriptor.maxPointsToConsiderDot) {// точка int x = 0, y = 0; foreach (var pt in clusters[0].points) { x += pt.X; y += pt.Y; } return(new Point(x / clusters[0].points.Count, y / clusters[0].points.Count)); } } // имеем несколько кластеров либо один размазанный const int countClustersToGetCenter = 2; if (clusters.Count > 1) { clusters = clusters.OrderByDescending(c => c.points.Count).ToList(); } Point near, far = new Point(); double minDist, maxDist; Point? lastFarPoint = null; for (var i = 0; i < clusters.Count && i < countClustersToGetCenter; i++) { clusters[i].GetMinMaxDistance(ptCentre, out near, out far, out minDist, out maxDist); if (lastFarPoint != null) { var v = new Point(far.X - lastFarPoint.Value.X, far.Y - lastFarPoint.Value.Y); var scale = clusters[i].points.Count / (double)(clusters[i].points.Count + clusters[i - 1].points.Count); far = new Point(lastFarPoint.Value.X + (int)(v.X * scale), lastFarPoint.Value.Y + (int)(v.Y * scale)); } else { lastFarPoint = far; } } return(far); }