/// <summary> /// use canny algorithm to find edges /// </summary> /// <param name="bmp"></param> /// <param name="edge_detector"></param> /// <param name="dots"></param> /// <param name="edges_bmp"></param> private static void DetectEdges( Bitmap bmp, ref EdgeDetectorCanny edge_detector, ref hypergraph dots, ref Bitmap edges_bmp) { byte[] image_data = new byte[bmp.Width * bmp.Height * 3]; BitmapArrayConversions.updatebitmap(bmp, image_data); if (edge_detector == null) edge_detector = new EdgeDetectorCanny(); edge_detector.automatic_thresholds = true; edge_detector.connected_sets_only = true; byte[] edges_data = edge_detector.Update(image_data, bmp.Width, bmp.Height); bool connected_sets_ok = false; try { edges_data = edge_detector.GetConnectedSetsImage(image_data, 10, bmp.Width / SurveyorCalibration.dots_across * 3, true, ref dots); connected_sets_ok = true; } catch { } if (connected_sets_ok) { // locate the red centre dot int max_redness = 0; CalibrationDot centre_dot = null; for (int i = 0; i < dots.Nodes.Count; i++) { CalibrationDot dot = (CalibrationDot)dots.Nodes[i]; int n = (((int)dot.y * bmp.Width) + (int)dot.x) * 3; if ((n > 3) && (n < image_data.Length - 4)) { int r = image_data[n + 2] + image_data[n + 2 + 3] + image_data[n + 2 - 3]; int g = image_data[n + 1] + image_data[n + 1 + 3] + image_data[n + 1 - 3]; int b = image_data[n] + image_data[n + 3] + image_data[n - 3]; int redness = (r * 2) - g - b; if (redness > max_redness) { max_redness = redness; centre_dot = dot; } } } if (centre_dot != null) centre_dot.centre = true; if (edges_bmp == null) edges_bmp = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); BitmapArrayConversions.updatebitmap_unsafe(edges_data, edges_bmp); } }
protected Bitmap DetectEdges(Bitmap bmp, EdgeDetectorCanny edge_detector, ref hypergraph dots) { usage.Update("Detect edges, BaseVisionStereo, DetectEdges"); byte[] image_data = new byte[bmp.Width * bmp.Height * 3]; BitmapArrayConversions.updatebitmap(bmp, image_data); if (edge_detector == null) edge_detector = new EdgeDetectorCanny(); edge_detector.automatic_thresholds = true; edge_detector.connected_sets_only = true; byte[] edges_data = edge_detector.Update(image_data, bmp.Width, bmp.Height); edges_data = edge_detector.GetConnectedSetsImage(image_data, 10, bmp.Width / SurveyorCalibration.dots_across * 3, true, ref dots); Bitmap edges_bmp = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); BitmapArrayConversions.updatebitmap_unsafe(edges_data, edges_bmp); return(edges_bmp); }
public static hypergraph DetectDots( Bitmap bmp, ref EdgeDetectorCanny edge_detector, CalibrationSurvey survey, ref Bitmap detected_dots, ref Bitmap linked_dots, ref Bitmap grd, ref Bitmap grid_diff, ref Bitmap rectified) { const int minimum_links = (dots_across * (dots_across/2)) / 2; hypergraph dots = null; DetectEdges(bmp, ref edge_detector, ref dots, ref detected_dots); if (dots != null) { // find the dots around the red centre dot List<CalibrationDot> centre_dots = null; polygon2D centre_square = GetCentreSquare(dots, ref centre_dots); if (centre_square != null) { if (centre_square.x_points.Count == 4) { // find the orientation of the centre square float angle = geometry.threePointAngle( (float)centre_dots[1].x, 0, (float)centre_dots[1].x, (float)centre_dots[1].y, (float)centre_dots[2].x, (float)centre_dots[2].y); angle = angle / (float)Math.PI * 180; if (angle > 160) { angle = geometry.threePointAngle( (float)centre_dots[2].x, 0, (float)centre_dots[2].x, (float)centre_dots[2].y, (float)centre_dots[3].x, (float)centre_dots[3].y); angle = angle / (float)Math.PI * 180; if ((angle >= 70) && (angle < 120)) { // link dots together List<CalibrationDot> search_regions = new List<CalibrationDot>(); double horizontal_dx = centre_dots[1].x - centre_dots[0].x; double horizontal_dy = centre_dots[1].y - centre_dots[0].y; double vertical_dx = centre_dots[3].x - centre_dots[0].x; double vertical_dy = centre_dots[3].y - centre_dots[0].y; for (int i = 0; i < centre_dots.Count; i++) LinkDots(dots, centre_dots[i], horizontal_dx, horizontal_dy, vertical_dx, vertical_dy, 0, search_regions); if (dots.Links.Count > minimum_links) { int tollerance_degrees = 10; if (ValidGrid(dots, bmp.Width, bmp.Height, tollerance_degrees)) { ShowLinkedDots(bmp, dots, search_regions, ref linked_dots); // assign a grid coordinate to each dot ApplyGrid(dots, centre_dots); // put the dots into a 2D grid for convenient lookup CalibrationDot[,] grid = CreateGrid(dots); if (grid != null) { grid2D ideal_grid = GetIdealGrid(grid, bmp.Width, bmp.Height); ShowIdealGrid(bmp, ideal_grid, grid, ref grd); ShowIdealGridDiff(bmp, grid, ref grid_diff); survey.Update(bmp.Width, bmp.Height, grid); ShowRectifiedImage(bmp, survey.centre_of_distortion_x, survey.centre_of_distortion_y, survey.best_fit_curve, ref rectified); } } } } } } } } return(dots); }