/// <summary> /// detect corners within the grid pattern /// </summary> /// <param name="width"></param> /// <param name="height"></param> private void detectCorners(int width, int height) { if (corners == null) { corners = new ArrayList[5]; for (int i = 0; i < corners.Length; i++) corners[i] = new ArrayList(); } corners[corners_index].Clear(); // clear intersection points for (int i = 0; i < all_horizontal_lines.Count; i++) { calibration_line line = (calibration_line)all_horizontal_lines[i]; line.intersections.Clear(); } for (int i = 0; i < all_vertical_lines.Count; i++) { calibration_line line = (calibration_line)all_vertical_lines[i]; line.intersections.Clear(); } for (int i = 0; i < all_horizontal_lines.Count; i++) { calibration_line line1 = (calibration_line)all_horizontal_lines[i]; calibration_point prev_pt = null; for (int j = 0; j < line1.points.Count; j++) { calibration_point pt = (calibration_point)line1.points[j]; if (j > 0) { for (int i2 = 0; i2 < all_vertical_lines.Count; i2++) { calibration_line line2 = (calibration_line)all_vertical_lines[i2]; calibration_point prev_pt2 = null; for (int j2 = 0; j2 < line2.points.Count; j2++) { calibration_point pt2 = (calibration_point)line2.points[j2]; if (j2 > 0) { float ix = 0; float iy = 0; if (geometry.intersection((float)prev_pt.x, (float)prev_pt.y, (float)pt.x, (float)pt.y, (float)prev_pt2.x, (float)prev_pt2.y, (float)pt2.x, (float)pt2.y, ref ix, ref iy)) { //int av = averageIntensity(calibration_image, width, height, (int)ix - 10, (int)iy - 10, (int)ix + 10, (int)iy + 10); //if (av < 170) { calibration_edge intersection_point = new calibration_edge(ix, iy, 0); intersection_point.grid_x = line2.index; // i2; intersection_point.grid_y = line1.index; // i; corners[corners_index].Add(intersection_point); line1.intersections.Add(intersection_point); line2.intersections.Add(intersection_point); //util.drawCross(corners_image, width, height, (int)ix, (int)iy, 2, 255, 255, 255, 0); } } } prev_pt2 = pt2; } } } prev_pt = pt; } } int grid_tx=9999, grid_ty=9999, grid_bx=0, grid_by=0; coverage = new calibration_edge[width, height]; detected_corners = new ArrayList(); for (int i = 0; i < corners.Length; i++) { for (int j = 0; j < corners[i].Count; j++) { calibration_edge pt = (calibration_edge)corners[i][j]; int px = (int)(pt.x / pt.hits); int py = (int)(pt.y / pt.hits); if ((px < width) && (py < height)) { if (pt.grid_x < grid_tx) grid_tx = pt.grid_x; if (pt.grid_y < grid_ty) grid_ty = pt.grid_y; if (pt.grid_x > grid_bx) grid_bx = pt.grid_x; if (pt.grid_y > grid_by) grid_by = pt.grid_y; if (coverage[px, py] == null) { int radius = (int)(width * separation_factor / 1.5f); if (radius < 3) radius = 3; for (int xx = px - radius; xx <= px + radius; xx++) { if ((xx > -1) && (xx < width)) { for (int yy = py - radius; yy <= py + radius; yy++) { if ((yy > -1) && (yy < height)) { coverage[xx, yy] = pt; } } } } detected_corners.Add(pt); } else { coverage[px, py].x += px; coverage[px, py].y += py; coverage[px, py].hits++; if (coverage[px, py].hits > 1000) { coverage[px, py].x /= 2; coverage[px, py].y /= 2; coverage[px, py].hits /= 2; } if (pt.grid_x < coverage[px, py].grid_x) coverage[px, py].grid_x = pt.grid_x; if (pt.grid_y < coverage[px, py].grid_y) coverage[px, py].grid_y = pt.grid_y; detected_corners.Add(coverage[px, py]); } } } } grid = null; if ((grid_bx > grid_tx) && (grid_by > grid_ty)) { grid = new calibration_edge[grid_bx - grid_tx+1, grid_by - grid_ty+1]; } for (int i = 0; i < detected_corners.Count; i++) { calibration_edge pt = (calibration_edge)detected_corners[i]; //pt.x /= pt.hits; //pt.y /= pt.hits; //pt.hits = 1; int gx = pt.grid_x - grid_tx; int gy = pt.grid_y - grid_ty; if (grid != null) { grid[gx, gy] = new calibration_edge(pt.x/pt.hits,pt.y/pt.hits,1); } } // show the corner positions showCorners(width, height); }
private void detectHorizontalEdges(Byte[] calibration_image, int width, int height, ArrayList edges, int min_magnitude) { int search_radius = 2; ArrayList temp_edges = new ArrayList(); edges.Clear(); for (int y = 1; y < height - 1; y++) { float factor = y / (float)height * width * 0.8f; int inhibit_radius = (int)((width + factor) * separation_factor); temp_edges.Clear(); for (int x = search_radius; x < width - search_radius; x++) { int val1 = 0; int val2 = 0; int n = (y * width) + x - search_radius; for (int xx = x - search_radius; xx < x + search_radius; xx++) { if (xx < x) val1 += calibration_image[n]; else val2 += calibration_image[n]; n++; } val1 /= search_radius; val2 /= search_radius; int magnitude = Math.Abs(val1 - val2); if (magnitude > min_magnitude) { calibration_edge new_edge = new calibration_edge(x, y, magnitude); temp_edges.Add(new_edge); } } // perform non-maximal supression for (int i = 0; i < temp_edges.Count-1; i++) { calibration_edge e1 = (calibration_edge)temp_edges[i]; if (e1.enabled) { for (int j = i + 1; j < temp_edges.Count; j++) { if (i != j) { calibration_edge e2 = (calibration_edge)temp_edges[j]; if (e2.enabled) { int dx = (int)(e2.x - e1.x); if (dx < 0) dx = -dx; if (dx < inhibit_radius) { if (e1.magnitude > e2.magnitude) e2.enabled = false; else { e1.enabled = false; j = temp_edges.Count; } } } } } } } // the survivors linger on for (int i = 0; i < temp_edges.Count; i++) { calibration_edge e = (calibration_edge)temp_edges[i]; if (e.enabled) { edges.Add(e); for (int xx = (int)e.x - 1; xx < (int)e.x; xx++) for (int yy = (int)e.y - 1; yy < (int)e.y; yy++) binary_image[binary_image_index, xx, yy] = true; } } } }
private void detectVerticalEdges(Byte[] calibration_image, int width, int height, ArrayList edges, int min_magnitude) { //int inhibit_radius = height / separation_factor; int search_radius = 2; ArrayList temp_edges = new ArrayList(); edges.Clear(); for (int x = 1; x < width - 1; x++) { temp_edges.Clear(); for (int y = search_radius; y < height - search_radius; y++) { int val1 = 0; int val2 = 0; for (int yy = y - search_radius; yy < y + search_radius; yy++) { int n = (yy * width) + x; if (yy < y) val1 += calibration_image[n]; else val2 += calibration_image[n]; } val1 /= search_radius; val2 /= search_radius; int magnitude = Math.Abs(val1 - val2); if (magnitude > min_magnitude) { calibration_edge new_edge = new calibration_edge(x, y, magnitude); temp_edges.Add(new_edge); } } // perform non-maximal supression for (int i = 0; i < temp_edges.Count-1; i++) { calibration_edge e1 = (calibration_edge)temp_edges[i]; if (e1.enabled) { for (int j = i + 1; j < temp_edges.Count; j++) { if (i != j) { calibration_edge e2 = (calibration_edge)temp_edges[j]; if (e2.enabled) { //float factor = (e1.y - (height / 2)) * vertical_gradient; float factor = e1.y / (float)height * width * 0.8f; int inhibit_radius = (int)((height + factor) * separation_factor); int dy = (int)(e2.y - e1.y); if (dy < 0) dy = -dy; if (dy < inhibit_radius) { if (e1.magnitude > e2.magnitude) e2.enabled = false; else { e1.enabled = false; j = temp_edges.Count; } } } } } } } // the survivors linger on for (int i = 0; i < temp_edges.Count; i++) { calibration_edge e = (calibration_edge)temp_edges[i]; if (e.enabled) { edges.Add(e); for (int xx = (int)e.x - 1; xx < (int)e.x; xx++) for (int yy = (int)e.y - 1; yy < (int)e.y; yy++) binary_image[binary_image_index, xx, yy] = true; } } } }