/// <summary> /// detect a grid within the given image using the given perimeter polygon /// </summary> /// <param name="img">image data</param> /// <param name="img_width">width of the image</param> /// <param name="img_height">height of the image</param> /// <param name="bytes_per_pixel">number of bytes per pixel</param> /// <param name="perimeter">bounding perimeter within which the grid exists</param> /// <param name="spot_centres">previously detected spot centres</param> /// <param name="minimum_dimension_horizontal">minimum number of cells across</param> /// <param name="maximum_dimension_horizontal">maximum number of cells across</param> /// <param name="minimum_dimension_vertical">minimum number of cells down</param> /// <param name="maximum_dimension_vertical">maximum number of cells down</param> /// <param name="known_grid_spacing">known grid spacing (cell diameter) value in pixels</param> /// <param name="known_even_dimension">set to true if it is known that the number of cells in horizontal and vertical axes is even</param> /// <param name="border_cells">extra cells to add as a buffer zone around the grid</param> /// <param name="horizontal_scale_spacings">description used on the spacings diagram</param> /// <param name="vertical_scale_spacings">description used on the spacings diagram</param> /// <param name="average_spacing_horizontal"></param> /// <param name="average_spacing_vertical"></param> /// <param name="output_img"></param> /// <param name="output_img_width"></param> /// <param name="output_img_height"></param> /// <param name="output_img_type"></param> /// <param name="ideal_grid_colour">colour used to draw the ideal grid</param> /// <param name="detected_grid_colour">colour used to draw the detected grid</param> /// <param name="simple_orientation"></param> /// <returns>2D grid</returns> public static grid2D DetectGrid(byte[] img, int img_width, int img_height, int bytes_per_pixel, polygon2D perimeter, ArrayList spot_centres, int minimum_dimension_horizontal, int maximum_dimension_horizontal, int minimum_dimension_vertical, int maximum_dimension_vertical, float known_grid_spacing, bool known_even_dimension, int border_cells, String horizontal_scale_spacings, String vertical_scale_spacings, ref float average_spacing_horizontal, ref float average_spacing_vertical, ref byte[] output_img, int output_img_width, int output_img_height, int output_img_type, byte[] ideal_grid_colour, byte[] detected_grid_colour, bool simple_orientation) { int tx = (int)perimeter.left(); int ty = (int)perimeter.top(); int bx = (int)perimeter.right(); int by = (int)perimeter.bottom(); // adjust spot centre positions so that they're relative to the perimeter // top left position if (spot_centres != null) { for (int i = 0; i < spot_centres.Count; i += 2) { spot_centres[i] = (float)spot_centres[i] - tx; spot_centres[i + 1] = (float)spot_centres[i + 1] - ty; } } int wdth = bx - tx; int hght = by - ty; // create an image of the grid area byte[] grid_img = image.createSubImage(img, img_width, img_height, bytes_per_pixel, tx, ty, bx, by); // get the orientation of the perimeter float dominant_orientation = perimeter.GetSquareOrientation(); // find the horizontal and vertical dimensions of the grid perimeter float grid_horizontal = perimeter.GetSquareHorizontal(); float grid_vertical = perimeter.GetSquareVertical(); // detect grid within the perimeter int cells_horizontal = 0, cells_vertical = 0; float horizontal_phase_offset = 0; float vertical_phase_offset = 0; if (spot_centres == null) DetectGrid(grid_img, wdth, hght, bytes_per_pixel, dominant_orientation, known_grid_spacing, grid_horizontal, grid_vertical, minimum_dimension_horizontal, maximum_dimension_horizontal, minimum_dimension_vertical, maximum_dimension_vertical, horizontal_scale_spacings, vertical_scale_spacings, ref average_spacing_horizontal, ref average_spacing_vertical, ref horizontal_phase_offset, ref vertical_phase_offset, ref cells_horizontal, ref cells_vertical, ref output_img, output_img_width, output_img_height, output_img_type, ideal_grid_colour, detected_grid_colour); else DetectGrid(spot_centres, grid_img, wdth, hght, bytes_per_pixel, dominant_orientation, known_grid_spacing, grid_horizontal, grid_vertical, minimum_dimension_horizontal, maximum_dimension_horizontal, minimum_dimension_vertical, maximum_dimension_vertical, horizontal_scale_spacings, vertical_scale_spacings, ref average_spacing_horizontal, ref average_spacing_vertical, ref horizontal_phase_offset, ref vertical_phase_offset, ref cells_horizontal, ref cells_vertical, ref output_img, output_img_width, output_img_height, output_img_type, ideal_grid_colour, detected_grid_colour); grid2D detectedGrid = null; // apply some range limits bool range_limited = false; if (cells_horizontal < 3) { cells_horizontal = 3; range_limited = true; } if (cells_vertical < 3) { cells_vertical = 3; range_limited = true; } if (cells_horizontal > maximum_dimension_horizontal) { cells_horizontal = maximum_dimension_horizontal; range_limited = true; } if (cells_vertical > maximum_dimension_vertical) { cells_vertical = maximum_dimension_vertical; range_limited = true; } if (range_limited) { Console.WriteLine("WARNING: When detecting the grid the matrix dimension had to be artificially restricted."); Console.WriteLine(" This probably means that there is a problem with the original image"); } // if we know the number of cells should be even correct any inaccuracies if (known_even_dimension) { cells_horizontal = (int)(cells_horizontal / 2) * 2; cells_vertical = (int)(cells_vertical / 2) * 2; } // get the centre of the region float cx = tx + ((bx - tx) / 2); float cy = ty + ((by - ty) / 2); detectedGrid = new grid2D(cells_horizontal, cells_vertical, cx, cy, dominant_orientation, average_spacing_horizontal, average_spacing_vertical, horizontal_phase_offset, vertical_phase_offset, border_cells, simple_orientation); return (detectedGrid); }