Exemplo n.º 1
0
        /// <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);
        }