private void detectVerticalLines(int width, int height) { vertical_lines = new ArrayList(); ArrayList[] horizontal_positions = new ArrayList[horizontal_magnitude.GetLength(0)]; ArrayList[] horizontal_positions_used = new ArrayList[horizontal_magnitude.GetLength(0)]; int max_y = height - (height / 4); if (ROI != null) max_y = ROI.by; int min_y = width / 4; if (ROI != null) min_y = ROI.ty; float bottom_spacing = 0; float top_spacing = 0; // detect the positions of horizontal disscontinuities for (int i = 0; i < horizontal_magnitude.GetLength(0); i++) { horizontal_positions[i] = new ArrayList(); horizontal_positions_used[i] = new ArrayList(); int n = 0; int prev_x = -1; for (int x = 0; x < width; x++) if (horizontal_magnitude[i, x] > 0) { horizontal_positions[i].Add(x); horizontal_positions_used[i].Add(false); int y = (height - 1) * i / horizontal_magnitude.GetLength(0) + (height / (horizontal_magnitude.GetLength(0) * 2)); if (ROI != null) y = ROI.ty + (i * (ROI.by - ROI.ty) / horizontal_magnitude.GetLength(0)) + ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2)); if (prev_x > -1) { if (i == 0) top_spacing += (x - prev_x); if (i == horizontal_magnitude.GetLength(0)-1) bottom_spacing += (x - prev_x); n++; } prev_x = x; } if ((i == 0) && (n > 0)) top_spacing /= n; if ((i == horizontal_magnitude.GetLength(0) - 1) && (n > 0)) bottom_spacing /= n; } // calculate the vertical gradient using the top and bottom horizontal spacings if ((top_spacing > 0) && (bottom_spacing > 0)) { if (bottom_spacing < top_spacing * 1.3f) bottom_spacing = top_spacing * 1.3f; if (ROI != null) vertical_gradient = (bottom_spacing - top_spacing) / (float)(ROI.by - ROI.ty); else vertical_gradient = (bottom_spacing - top_spacing) / (float)(height*3/4); } float vertical_additive = 0.5f; int max_horizontal_difference = (int)(width * separation_factor * 1.9f); for (int j = 0; j < horizontal_positions[0].Count; j++) { int x = (int)horizontal_positions[0][j]; int y = height / (horizontal_magnitude.GetLength(0) * 2); if (ROI != null) y = ROI.ty; bool drawn = false; calibration_line line = new calibration_line(); for (int i = 1; i < horizontal_magnitude.GetLength(0); i++) { int max_connectedness = min_connectedness; int best_x = -1; int best_y = -1; int idx = -1; for (int k = 0; k < horizontal_positions[i].Count; k++) { int x2 = (int)horizontal_positions[i][k]; int dx = x2 - x; if (Math.Abs(dx) < max_horizontal_difference) { int y2 = (height - 1) * i / horizontal_magnitude.GetLength(0) + (height / (horizontal_magnitude.GetLength(0) * 2)); if (ROI != null) y2 = ROI.ty + (i * (ROI.by - ROI.ty) / horizontal_magnitude.GetLength(0)) + ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2)); // are these two connected? if ((y < height) && (y2 < height)) { int grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * y2 / height)); if (ROI != null) grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * (y2 - ROI.ty) / (ROI.by - ROI.ty))); if (!(((x > width * 55 / 100) && (x>x2) && (x2 < x + grid_width)) || ((x < width * 45 / 100) && (x < x2) && (x2 > x - grid_width)))) { int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2); if (connectedness > max_connectedness) { best_x = x2; best_y = y2; max_connectedness = connectedness; idx = k; } } } } } if (best_x > -1) { horizontal_positions_used[i][idx] = true; calibration_line temp_line = traceLine(width, height, x, y, best_x, best_y); line.Add(temp_line); x = best_x; y = best_y; drawn = true; } } if (drawn) { calibration_line temp_line = traceLine(width, height, x, y, x, max_y); line.Add(temp_line); if (line.points.Count > 0) vertical_lines.Add(line); } } int index = horizontal_magnitude.GetLength(0) - 1; for (int j = 0; j < horizontal_positions[index].Count; j++) { if ((bool)horizontal_positions_used[index][j] == false) { int x = (int)horizontal_positions[index][j]; int y = height - (height / (horizontal_magnitude.GetLength(0) * 2)); if (ROI != null) y = ROI.by - ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2)); bool drawn = false; calibration_line line = new calibration_line(); for (int i = horizontal_magnitude.GetLength(0) - 2; i >= 0; i--) { int max_connectedness = min_connectedness; int best_x = -1; int best_y = -1; int idx = -1; for (int k = 0; k < horizontal_positions[i].Count; k++) { int x2 = (int)horizontal_positions[i][k]; int dx = x2 - x; if (Math.Abs(dx) < max_horizontal_difference) { int y2 = height - ((height - 1) * i / horizontal_magnitude.GetLength(0) + (height / (horizontal_magnitude.GetLength(0) * 2))); if (ROI != null) y2 = ROI.by - (i * (ROI.by - ROI.ty) / horizontal_magnitude.GetLength(0)) + ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2)); // are these two connected? if ((y < height) && (y2 < height)) { int grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * y2 / height)); if (ROI != null) grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * (y2 - ROI.ty) / (ROI.by - ROI.ty))); if (!(((x > width * 55 / 100) && (x > x2) && (x2 < x + grid_width)) || ((x < width * 45 / 100) && (x < x2) && (x2 > x - grid_width)))) { int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2); if (connectedness > max_connectedness) { best_x = x2; best_y = y2; max_connectedness = connectedness; idx = k; } } } } } if (best_x > -1) { calibration_line temp_line = traceLine(width, height, best_x, best_y, x, y); temp_line.Reverse(); line.Add(temp_line); x = best_x; y = best_y; drawn = true; } } if (drawn) { calibration_line temp_line = traceLine(width, height, x, min_y, x, y); temp_line.Reverse(); line.Add(temp_line); line.Reverse(); if (line.points.Count > 0) vertical_lines.Add(line); } } } // sort and prune detectLinesSort(width, height, false, vertical_lines); // remove first and last lines , because these are usually poorly detected if (vertical_lines.Count > 2) { vertical_lines.RemoveAt(vertical_lines.Count - 1); vertical_lines.RemoveAt(0); } updateAllLines(width, height, false, vertical_lines); // add index numbers to the lines indexLines(width, height, false, all_vertical_lines); // draw for (int i = 0; i < all_vertical_lines.Count; i++) { calibration_line line = (calibration_line)all_vertical_lines[i]; line.Draw(lines_image, width, height, 255, 0, 0); } }
private void detectHorizontalLines(int width, int height) { horizontal_lines = new ArrayList(); ArrayList[] vertical_positions = new ArrayList[vertical_magnitude.GetLength(0)]; ArrayList[] vertical_positions_used = new ArrayList[vertical_magnitude.GetLength(0)]; int max_x = width - (width / 4); if (ROI != null) max_x = ROI.bx; int min_x = width / 4; if (ROI != null) min_x = ROI.tx; // detect the positions of horizontal disscontinuities for (int i = 0; i < vertical_magnitude.GetLength(0); i++) { vertical_positions[i] = new ArrayList(); vertical_positions_used[i] = new ArrayList(); for (int y = 0; y < height; y++) if (vertical_magnitude[i, y] > 0) { vertical_positions[i].Add(y); vertical_positions_used[i].Add(false); int x = (width - 1) * i / vertical_magnitude.GetLength(0) + (width / (vertical_magnitude.GetLength(0)*2)); if (ROI != null) x = ROI.tx + (i * (ROI.bx - ROI.tx) / vertical_magnitude.GetLength(0)) + ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0)*2)); } } int max_vertical_difference = (int)((height * separation_factor) / 1.0f); for (int j = 0; j < vertical_positions[0].Count; j++) { int y = (int)vertical_positions[0][j]; int x = width / (vertical_magnitude.GetLength(0) * 2); if (ROI != null) x = ROI.tx; bool drawn = false; calibration_line line = new calibration_line(); for (int i = 1; i < vertical_magnitude.GetLength(0); i++) { int max_connectedness = min_connectedness; int best_x = -1; int best_y = -1; int idx = -1; for (int k = 0; k < vertical_positions[i].Count; k++) { int y2 = (int)vertical_positions[i][k]; int dy = y2 - y; if (Math.Abs(dy) < max_vertical_difference) { int x2 = (width - 1) * i / vertical_magnitude.GetLength(0) + (width / (vertical_magnitude.GetLength(0) * 2)); if (ROI != null) x2 = ROI.tx + (i * (ROI.bx - ROI.tx) / vertical_magnitude.GetLength(0)) + ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0) * 2)); // are these two connected? int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2); if (connectedness > max_connectedness) { best_x = x2; best_y = y2; max_connectedness = connectedness; idx = k; } } } if (best_x > -1) { vertical_positions_used[i][idx] = true; calibration_line temp_line = traceLine(width, height, x, y, best_x, best_y); line.Add(temp_line); x = best_x; y = best_y; drawn = true; } } if (drawn) { calibration_line temp_line = traceLine(width, height, x, y, max_x, y); line.Add(temp_line); if (line.points.Count > 0) horizontal_lines.Add(line); } } int index = vertical_magnitude.GetLength(0) - 1; for (int j = 0; j < vertical_positions[index].Count; j++) { if ((bool)vertical_positions_used[index][j] == false) { int y = (int)vertical_positions[index][j]; int x = width - (width / (vertical_magnitude.GetLength(0) * 2)); if (ROI != null) x = ROI.bx - ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0) * 2)); bool drawn = false; calibration_line line = new calibration_line(); for (int i = vertical_magnitude.GetLength(0) - 2; i >= 0; i--) { int max_connectedness = min_connectedness; int best_x = -1; int best_y = -1; int idx = -1; for (int k = 0; k < vertical_positions[i].Count; k++) { int y2 = (int)vertical_positions[i][k]; int dy = y2 - y; if (Math.Abs(dy) < max_vertical_difference) { int x2 = width - ((width - 1) * i / vertical_magnitude.GetLength(0) + (width / (vertical_magnitude.GetLength(0) * 2))); if (ROI != null) x2 = ROI.bx - (i * (ROI.bx - ROI.tx) / vertical_magnitude.GetLength(0)) + ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0) * 2)); // are these two connected? int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2); if (connectedness > max_connectedness) { best_x = x2; best_y = y2; max_connectedness = connectedness; idx = k; } } } if (best_x > -1) { calibration_line temp_line = traceLine(width, height, best_x, best_y, x, y); temp_line.Reverse(); line.Add(temp_line); x = best_x; y = best_y; drawn = true; } } if (drawn) { calibration_line temp_line = traceLine(width, height, min_x, y, x, y); temp_line.Reverse(); line.Add(temp_line); line.Reverse(); if (line.points.Count > 0) horizontal_lines.Add(line); } } } // sort and prune detectLinesSort(width, height, true, horizontal_lines); // remove first and last lines, since they're often poorly detected if (horizontal_lines.Count > 2) { horizontal_lines.RemoveAt(horizontal_lines.Count - 1); horizontal_lines.RemoveAt(0); } updateAllLines(width, height, true, horizontal_lines); // add index numbers to the lines indexLines(width, height, true, all_horizontal_lines); // draw for (int i = 0; i < all_horizontal_lines.Count; i++) { calibration_line line = (calibration_line)all_horizontal_lines[i]; line.Draw(lines_image, width, height, 255, 0, 0); } }