public override void FindCalibrationPoints() { Points = new List<CalibrationPoint>(); // 1) Binarize image BinarizeImage(); // 2) Find all black dots: // - find black pixel // - add to list all adjacent black points // - add this list to dot list _dots = new List<CalibrationDot>(); for(int y = 0; y < Image.RowCount; y++) { for(int x = 0; x < Image.ColumnCount; x++) { // Check if point is black if(Image[y, x] > 0) { if(CheckIfPointIsAlreadyInDot(y, x)) continue; // Point is not in any dot, so create new one and add all linked points ( with flood fill alg.) CalibrationDot newdot = new CalibrationDot(); FloodSearchForDotPoints(ref newdot, y, x); _dots.Add(newdot); // Move to right side of the dot x = (int)(newdot.BoundingBox.X + newdot.BoundingBox.Width); } } } // 3) For each dot compute gravity center -> it's calibration point! foreach(CalibrationDot dot in _dots) { dot.FindCenter(); Points.Add(new CalibrationPoint() { ImgX = (double)dot.Center.X, ImgY = (double)dot.Center.Y }); } }
// Search for all adjacent black points using algorithm similar to flood fill: // - after meeting black point it is added to dot points and its color is changed to white // - same is repeated for adjacent points private void FloodSearchForDotPoints(ref CalibrationDot dot, int y, int x) { if(y < 0 || y >= Image.RowCount || x < 0 || x >= Image.ColumnCount) return; if(Image[y, x] > 0.5f) { dot.AddPoint(new Point(x, y)); Image[y, x] = 0.0f; FloodSearchForDotPoints(ref dot, y - 1, x); FloodSearchForDotPoints(ref dot, y + 1, x); FloodSearchForDotPoints(ref dot, y, x - 1); FloodSearchForDotPoints(ref dot, y, x + 1); } }