Example #1
0
        /// <summary>
        /// returns an ideally spaced grid over the actual detected spots
        /// </summary>
        /// <param name="grid"></param>
        /// <returns></returns>
        private static grid2D OverlayIdealGrid(CalibrationDot[,] grid,
                                               List<CalibrationDot> corners,
                                               ref int grid_offset_x, ref int grid_offset_y,
                                               int random_seed)
        {
            grid2D overlay_grid = null;
            int grid_tx = -1;
            int grid_ty = -1;
            int grid_bx = -1;
            int grid_by = -1;

            int offset_x = 0;
            int offset_y = 0;

            bool found = false;
            int max_region_area = 0;

            // try searching horizontally and vertically
            // then pick the result with the greatest area
            for (int test_orientation = 0; test_orientation < 2; test_orientation++)
            {
                bool temp_found = false;

                int temp_grid_tx = -1;
                int temp_grid_ty = -1;
                int temp_grid_bx = -1;
                int temp_grid_by = -1;

                int temp_offset_x = 0;
                int temp_offset_y = 0;

                switch (test_orientation)
                {
                    case 0:
                        {
                            while ((temp_offset_y < 5) && (!temp_found))
                            {
                                temp_offset_x = 0;
                                while ((temp_offset_x < 3) && (!temp_found))
                                {
                                    temp_grid_tx = temp_offset_x;
                                    temp_grid_ty = temp_offset_y;
                                    temp_grid_bx = grid.GetLength(0) - 1 - temp_offset_x;
                                    temp_grid_by = grid.GetLength(1) - 1 - temp_offset_y;

                                    if ((temp_grid_bx < grid.GetLength(0)) &&
                                        (temp_grid_tx < grid.GetLength(0)) &&
                                        (temp_grid_by < grid.GetLength(1)) &&
                                        (temp_grid_ty < grid.GetLength(1)) &&
                                        (temp_grid_ty >= 0) &&
                                        (temp_grid_by >= 0) &&
                                        (temp_grid_tx >= 0) &&
                                        (temp_grid_bx >= 0))
                                    {
                                        if ((grid[temp_grid_tx, temp_grid_ty] != null) &&
                                            (grid[temp_grid_bx, temp_grid_ty] != null) &&
                                            (grid[temp_grid_bx, temp_grid_by] != null) &&
                                            (grid[temp_grid_tx, temp_grid_by] != null))
                                        {
                                            temp_found = true;
                                        }
                                    }

                                    temp_offset_x++;
                                }
                                temp_offset_y++;
                            }
                            break;
                        }
                    case 1:
                        {
                            while ((temp_offset_x < 3) && (!temp_found))
                            {
                                temp_offset_y = 0;
                                while ((temp_offset_y < 5) && (!temp_found))
                                {
                                    temp_grid_tx = temp_offset_x;
                                    temp_grid_ty = temp_offset_y;
                                    temp_grid_bx = grid.GetLength(0) - 1 - temp_offset_x;
                                    temp_grid_by = grid.GetLength(1) - 1 - temp_offset_y;

                                    if ((temp_grid_bx < grid.GetLength(0)) &&
                                        (temp_grid_tx < grid.GetLength(0)) &&
                                        (temp_grid_by < grid.GetLength(1)) &&
                                        (temp_grid_ty < grid.GetLength(1)) &&
                                        (temp_grid_ty >= 0) &&
                                        (temp_grid_by >= 0) &&
                                        (temp_grid_tx >= 0) &&
                                        (temp_grid_bx >= 0))
                                    {
                                        if ((grid[temp_grid_tx, temp_grid_ty] != null) &&
                                            (grid[temp_grid_bx, temp_grid_ty] != null) &&
                                            (grid[temp_grid_bx, temp_grid_by] != null) &&
                                            (grid[temp_grid_tx, temp_grid_by] != null))
                                        {
                                            temp_found = true;
                                        }
                                    }

                                    temp_offset_y++;
                                }
                                temp_offset_x++;
                            }
                            break;
                        }
                }

                temp_offset_y = temp_grid_ty - 1;
                while (temp_offset_y >= 0)
                {
                    if ((temp_offset_y < grid.GetLength(1)) &&
                        (temp_offset_y >= 0))
                    {
                        if ((grid[temp_grid_tx, temp_offset_y] != null) &&
                            (grid[temp_grid_bx, temp_offset_y] != null))
                        {
                            temp_grid_ty = temp_offset_y;
                            temp_offset_y--;
                        }
                        else break;
                    }
                    else break;
                }

                temp_offset_y = temp_grid_by + 1;
                while (temp_offset_y < grid.GetLength(1))
                {
                    if ((temp_offset_y < grid.GetLength(1)) &&
                        (temp_offset_y >= 0))
                    {
                        if ((grid[temp_grid_tx, temp_offset_y] != null) &&
                            (grid[temp_grid_bx, temp_offset_y] != null))
                        {
                            temp_grid_by = temp_offset_y;
                            temp_offset_y++;
                        }
                        else break;
                    }
                    else break;
                }

                if (temp_found)
                {
                    int region_area = (temp_grid_bx - temp_grid_tx) * (temp_grid_by - temp_grid_ty);
                    if (region_area > max_region_area)
                    {
                        max_region_area = region_area;
                        found = true;

                        grid_tx = temp_grid_tx;
                        grid_ty = temp_grid_ty;
                        grid_bx = temp_grid_bx;
                        grid_by = temp_grid_by;

                        offset_x = temp_offset_x;
                        offset_y = temp_offset_y;
                    }
                }
            }

            if (found)
            {
                // record the positions of the corners
                corners.Add(grid[grid_tx, grid_ty]);
                corners.Add(grid[grid_bx, grid_ty]);
                corners.Add(grid[grid_bx, grid_by]);
                corners.Add(grid[grid_tx, grid_by]);

                double dx, dy;

                double x0 = grid[grid_tx, grid_ty].x;
                double y0 = grid[grid_tx, grid_ty].y;
                double x1 = grid[grid_bx, grid_ty].x;
                double y1 = grid[grid_bx, grid_ty].y;
                double x2 = grid[grid_tx, grid_by].x;
                double y2 = grid[grid_tx, grid_by].y;
                double x3 = grid[grid_bx, grid_by].x;
                double y3 = grid[grid_bx, grid_by].y;

                polygon2D perimeter = new polygon2D();
                perimeter.Add((float)x0, (float)y0);
                perimeter.Add((float)x1, (float)y1);
                perimeter.Add((float)x3, (float)y3);
                perimeter.Add((float)x2, (float)y2);

                int grid_width = grid_bx - grid_tx;
                int grid_height = grid_by - grid_ty;

                int min_hits = 0;
                double min_dx = 0, min_dy = 0;

                // try various perimeter sizes
                double min_dist = double.MaxValue;
                int max_perim_size_tries = 100;
                polygon2D best_perimeter = perimeter;
                Random rnd = new Random(random_seed);
                for (int perim_size = 0; perim_size < max_perim_size_tries; perim_size++)
                {
                    // try a small range of translations
                    for (int nudge_x = -10; nudge_x <= 10; nudge_x++)
                    {
                        for (int nudge_y = -5; nudge_y <= 5; nudge_y++)
                        {
                            // create a perimeter at this scale and translation
                            polygon2D temp_perimeter = perimeter.Scale(1.0f + (perim_size * 0.1f / max_perim_size_tries));
                            temp_perimeter = temp_perimeter.ScaleSideLength(0, 0.95f + ((float)rnd.NextDouble() * 0.1f));
                            temp_perimeter = temp_perimeter.ScaleSideLength(2, 0.95f + ((float)rnd.NextDouble() * 0.1f));
                            for (int i = 0; i < temp_perimeter.x_points.Count; i++)
                            {
                                temp_perimeter.x_points[i] += nudge_x;
                                temp_perimeter.y_points[i] += nudge_y;
                            }

                            // create a grid based upon the perimeter
                            grid2D temp_overlay_grid = new grid2D(grid_width, grid_height, temp_perimeter, 0, false);

                            // how closely does the grid fit the actual observations ?
                            double temp_min_dist = min_dist;
                            BestFit(grid_tx, grid_ty, grid,
                                    temp_overlay_grid, ref min_dist,
                                    ref min_dx, ref min_dy, ref min_hits,
                                    ref grid_offset_x, ref grid_offset_y);

                            // record the closest fit
                            if (temp_min_dist < min_dist)
                            {
                                best_perimeter = temp_perimeter;
                                overlay_grid = temp_overlay_grid;
                            }
                        }
                    }
                }

                if (min_hits > 0)
                {
                    dx = min_dx;
                    dy = min_dy;

                    Console.WriteLine("dx: " + dx.ToString());
                    Console.WriteLine("dy: " + dy.ToString());

                    x0 += dx;
                    y0 += dy;
                    x1 += dx;
                    y1 += dy;
                    x2 += dx;
                    y2 += dy;
                    x3 += dx;
                    y3 += dy;

                    perimeter = new polygon2D();
                    perimeter.Add((float)x0, (float)y0);
                    perimeter.Add((float)x1, (float)y1);
                    perimeter.Add((float)x3, (float)y3);
                    perimeter.Add((float)x2, (float)y2);
                    overlay_grid = new grid2D(grid_width, grid_height, perimeter, 0, false);
                }
            }

            return (overlay_grid);
        }