Ejemplo n.º 1
0
        /// <summary>
        /// sets the top left or bottom right point of the region of interest
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="topLeft"></param>
        public void setRegionOfInterestPoint(int x, int y)
        {
            if (ROI == null) ROI = new calibration_region_of_interest();

            if (y < image_height / 2)
            {
                if (x < image_width / 2)
                    ROI.setTopLeft(x, y);
                else
                    ROI.setTopRight(x, y);
            }
            else
            {
                if (x < image_width / 2)
                    ROI.setBottomLeft(x, y);
                else
                    ROI.setBottomRight(x, y);
            }
        }
Ejemplo n.º 2
0
        public void Update(Byte[] img, int width, int height, bool alignMode)
        {
            if (img != null)
            {
                image_width = width;
                image_height = height;

                // create lists to store edges
                edges_horizontal = new ArrayList();
                edges_vertical = new ArrayList();
                edges_image = new Byte[width * height * 3];
                centrealign_image = new Byte[width * height * 3];
                corners_image = new Byte[width * height * 3];
                lines_image = new Byte[width * height * 3];
                edges_binary = new bool[width, height];
                horizontal_magnitude = new int[8, width];
                vertical_magnitude = new int[5, height];
                if (binary_image == null) binary_image = new bool[no_of_images, width, height];
                for (int i = 0; i < img.Length; i++)
                {
                    lines_image[i] = img[i];
                    centrealign_image[i] = img[i];
                    edges_image[i] = img[i];
                    corners_image[i] = img[i];
                }
                
                // show region of interest
                if (ROI == null)
                {
                    // create a default region of interest
                    ROI = new calibration_region_of_interest();
                    ROI.tx = width / 10;
                    ROI.bx = width - ROI.tx;
                    ROI.ty = height / 10;
                    ROI.by = height - ROI.ty;
                }

                // show the region of interest
                ROI.Show(centrealign_image, width, height);

                // determine the separation factor used for non-maximal suppression
                // during edge detection
                //separation_factor = (int)(1.0f / GetSeparationFactor(width));
                separation_factor = GetSeparationFactor(width);

                // image used for aligning the centre of the calibration pattern
                showAlignmentLines(centrealign_image, width, height);

                // create a mono image
                calibration_image = image.monoImage(img, width, height);

                if (!alignMode)
                {
                    if (samples < min_samples) samples++;

                    int min_magnitude = 1;
                    clearBinaryImage(width, height);
                    detectHorizontalEdges(calibration_image, width, height, edges_horizontal, min_magnitude);
                    detectVerticalEdges(calibration_image, width, height, edges_vertical, min_magnitude);
                    updateEdgesImage(width, height);

                    // detect lines
                    detectHorizontalLines(width, height);
                    detectVerticalLines(width, height);

                    float rotn = detectRotation(width, height);
                    if (rotation == 0)
                        rotation = rotn;
                    else
                        rotation = (rotation * 0.9f) + (rotn * 0.1f);

                    // create a grid to store the edges
                    if ((vertical_lines.Count > 0) && (horizontal_lines.Count > 0))
                    {
                        // locate corners
                        detectCorners(width, height);

                        // hunt the centre spot
                        grid_centre_x = 0;
                        grid_centre_y = 0;
                        detectCentreSpot(calibration_image, width, height, ref grid_centre_x, ref grid_centre_y);
                        if (grid_centre_x > 0)
                        {
                            // detect the lens distortion
                            detectLensDistortion(width, height, grid_centre_x, grid_centre_y);

                            if (fitter != null)
                            {
                                // store the polynomial coefficients which will be used as
                                // a basis for a more detailed search
                                float[] C = new float[3];
                                C[1] = fitter.Coeff(1);
                                C[2] = fitter.Coeff(2);

                                // itterate a number of time trying different possible matches
                                // the number of itterations is adjusted depending upon the size of the error
                                int max_v = 1;
                                if (min_RMS_error > 5) max_v = 5;
                                //if (min_RMS_error > 10) max_v = 10;
                                for (int v = 0; v < max_v; v++)
                                {
                                    // add small amount of noise to the polynomial coefficients
                                    for (int c = 1; c <= 2; c++)
                                        fitter.SetCoeff(c, C[c] * (1.0f + ((((rnd.Next(2000000) / 1000000.0f) - 1.0f) * 0.01f))));

                                    // does this equation cause the image to be re-scaled?
                                    // if it does we can explicitly detect this and correct for it later
                                    detectScale(width, height);

                                    // the rectification is only considered valid if it is roughly concave
                                    if (isValidRectification)
                                    {
                                        // update the calibration lookup
                                        updateCalibrationMap(width, height, fitter, 1.0f, rotation);

                                        float RMS_error = GetRMSerror();
                                        if ((RMS_error < min_RMS_error) && (samples >= min_samples))
                                        {
                                            // update the graph
                                            curve_fit = new Byte[width * height * 3];
                                            fitter.Show(curve_fit, width, height);

                                            updateCalibrationMap(width, height, fitter, temp_scale, rotation);
                                            calibration_map = new int[width * height];
                                            for (int i = 0; i < temp_calibration_map.Length; i++)
                                                calibration_map[i] = temp_calibration_map[i];
                                            calibration_map_inverse = new int[width, height, 2];
                                            for (int x = 0; x < width; x++)
                                            {
                                                for (int y = 0; y < height; y++)
                                                {
                                                    calibration_map_inverse[x, y, 0] = temp_calibration_map_inverse[x, y, 0];
                                                    calibration_map_inverse[x, y, 1] = temp_calibration_map_inverse[x, y, 1];
                                                }
                                            }

                                            // update the rectified position of the centre of the pattern
                                            updatePatternCentreRectified();

                                            scale = temp_scale;
                                            best_curve = fitter;
                                            min_RMS_error = RMS_error;
                                        }
                                    }
                                }

                                // rectify
                                Rectify(img, width, height);

                                ShowRectifiedCorners(rectified_image, width, height);
                            }
                        }

                        corners_index++;
                        if (corners_index >= corners.Length) corners_index = 0;
                    }

                    av_centreline_x += closest_to_centreline_x;
                    av_centreline_x_hits++;
                    if (av_centreline_x_hits > 50)
                    {
                        av_centreline_x /= 2;
                        av_centreline_x_hits /= 2;
                    }

                    av_centreline_y += closest_to_centreline_y;
                    av_centreline_y_hits++;
                    if (av_centreline_y_hits > 50)
                    {
                        av_centreline_y /= 2;
                        av_centreline_y_hits /= 2;
                    }
                }
                else
                {
                    samples = 0;
                }

                binary_image_index++;
                if (binary_image_index >= no_of_images) binary_image_index = 0;

            }

        }