Example #1
0
        /// <summary>
        /// fits a curve to the given grid using the given centre of distortion
        /// </summary>
        /// <param name="grid">detected grid dots</param>
        /// <param name="overlay_grid">overlayed ideal rectified grid</param>
        /// <param name="centre_of_distortion">centre of lens distortion</param>
        /// <param name="curve">curve to be fitted</param>
        private static void FitCurve(CalibrationDot[,] grid,
                                     grid2D overlay_grid,
                                     CalibrationDot centre_of_distortion,
                                     polynomial curve,
                                     double noise, Random rnd,
                                     int grid_offset_x, int grid_offset_y)
        {
            double[] prev_col = new double[grid.GetLength(1) * 2];
            double[] col = new double[prev_col.Length];

            double half_noise = noise / 2;
            double rectified_x, rectified_y;

            for (int pass = 0; pass < 1; pass++)
            {
                // for every detected dot
                for (int grid_x = 0; grid_x < grid.GetLength(0); grid_x++)
                {
                    double prev_rectified_radial_dist = 0;
                    double prev_actual_radial_dist = 0;
                    int prev_grid_y = -1;
                    for (int grid_y = 0; grid_y < grid.GetLength(1); grid_y++)
                    {
                        if (grid[grid_x, grid_y] != null)
                        {
                            if ((grid_x + grid_offset_x < overlay_grid.line_intercepts.GetLength(0)) &&
                                (grid_y + grid_offset_y < overlay_grid.line_intercepts.GetLength(1)) &&
                                (grid_x + grid_offset_x >= 0) && (grid_y + grid_offset_y >= 0))
                            {
                                // find the rectified distance of the dot from the centre of distortion
                                rectified_x = overlay_grid.line_intercepts[grid_x + grid_offset_x, grid_y + grid_offset_y, 0];
                                rectified_y = overlay_grid.line_intercepts[grid_x + grid_offset_x, grid_y + grid_offset_y, 1];
                                if (pass > 0)
                                {
                                    rectified_x += (((rnd.NextDouble() * noise) - half_noise) * 0.1);
                                    rectified_y += (((rnd.NextDouble() * noise) - half_noise) * 0.1);
                                }

                                //double rectified_x = overlay_grid.line_intercepts[grid_x + grid_offset_x, grid_y + grid_offset_y, 0];
                                //double rectified_y = overlay_grid.line_intercepts[grid_x + grid_offset_x, grid_y + grid_offset_y, 1];
                                double rectified_dx = rectified_x - centre_of_distortion.x;
                                double rectified_dy = rectified_y - centre_of_distortion.y;
                                double rectified_radial_dist = Math.Sqrt(rectified_dx * rectified_dx + rectified_dy * rectified_dy);

                                // find the actual raw image distance of the dot from the centre of distortion
                                //double actual_x = grid[grid_x, grid_y].x + (((rnd.NextDouble() * noise) - half_noise) * 2);
                                //double actual_y = grid[grid_x, grid_y].y + (((rnd.NextDouble() * noise) - half_noise) * 2);
                                double actual_x = grid[grid_x, grid_y].x;
                                double actual_y = grid[grid_x, grid_y].y;
                                double actual_dx = actual_x - centre_of_distortion.x;
                                double actual_dy = actual_y - centre_of_distortion.y;
                                double actual_radial_dist = Math.Sqrt(actual_dx * actual_dx + actual_dy * actual_dy);

                                // plot
                                curve.AddPoint(rectified_radial_dist, actual_radial_dist);

                                col[(grid_y * 2)] = rectified_radial_dist;
                                col[(grid_y * 2) + 1] = actual_radial_dist;

                                prev_rectified_radial_dist = rectified_radial_dist;
                                prev_actual_radial_dist = actual_radial_dist;
                                prev_grid_y = grid_y;
                            }
                        }
                    }

                    for (int i = 0; i < col.Length; i++)
                        prev_col[i] = col[i];
                }
            }

            // find the best fit curve
            curve.Solve();
        }
Example #2
0
        /// <summary>
        /// fits a line to the greatest number of aligned spots
        /// </summary>
        /// <param name="spots">list of detected spot features</param>
        /// <param name="ignore_selected_spots">whether to ignore spots which have already been selected in previous line fits</param>
        /// <param name="spots_aligned">list of aligned spots</param>
        /// <param name="preferred_orientation">preferred direction of the line, in the range 0-2PI, or if set to -1 direction is ignored</param>
        /// <param name="orientation_tollerance">max deviation from the preferred tollerance</param>
        /// <param name="max_distance">the maximum perpendicular distance below which the spot is considered to touch the line, in the range, typically in the range 0.0-1.0 as a fraction of the spot radius</param>
        /// <param name="line_centre_x">x centre point of the line</param>
        /// <param name="line_centre_y">y centre point of the line</param>
        /// <returns>polynomial line fit</returns>
        private polynomial fitLineToSpots(ArrayList spots,
                                          bool ignore_selected_spots,
                                          ref ArrayList spots_aligned,
                                          float preferred_orientation,
                                          float orientation_tollerance,
                                          float max_distance,
                                          ref float line_centre_x,
                                          ref float line_centre_y)
        {
            polynomial best_fit_line = null;
            spots_aligned = null;
            line_centre_x = 0;
            line_centre_y = 0;

            // find the maximum number of aligned spots
            ArrayList max_spots_aligned =
                MaxAlignedSpots(ignore_selected_spots,
                                preferred_orientation,
                                orientation_tollerance,
                                max_distance);
            if (max_spots_aligned != null)
            {
                spots_aligned = max_spots_aligned;
                if (max_spots_aligned.Count > 0)
                {
                    // get the position of the centre of the line
                    for (int i = 0; i < max_spots_aligned.Count; i++)
                    {
                        blob spot = (blob)max_spots_aligned[i];
                        line_centre_x += spot.interpolated_x;
                        line_centre_y += spot.interpolated_y;
                    }
                    line_centre_x /= max_spots_aligned.Count;
                    line_centre_y /= max_spots_aligned.Count;

                    // fit a line to the points
                    best_fit_line = new polynomial();
                    best_fit_line.SetDegree(1);
                    for (int i = 0; i < max_spots_aligned.Count; i++)
                    {
                        blob spot = (blob)max_spots_aligned[i];
                        float dx = spot.interpolated_x - line_centre_x;
                        float dy = spot.interpolated_y - line_centre_y;
                        best_fit_line.AddPoint(dx, dy);
                        spot.selected = true;
                    }
                    // solve the line equation
                    best_fit_line.Solve();
                }
            }
            return (best_fit_line);
        }