Esempio n. 1
0
        public unsafe void stereoMatch(Byte[] left_bmp, Byte[] right_bmp,
                                        int width, int height, bool colourImages)
        {
            if (!initialised)
            {
                initialised = true;
            }

            int BytesPerPixel = 3;
            if (!colourImages) BytesPerPixel = 1;

            stereointerface.loadImage(left_bmp, width, height, true, BytesPerPixel);

            stereointerface.loadImage(right_bmp, width, height, false, BytesPerPixel);

            setMaxDisparity(max_disparity_percent);
            setRequiredFeatures(required_features);

            // do the stereo correspondence            
            stereointerface.stereoMatchRun(0, peaks_per_row, correspondence_algorithm_type);

            // retrieve features
            no_of_disparities = stereointerface.getSelectedPointFeatures(disparities);

            // track the features
            features = new stereoFeatures(no_of_disparities);

            if (correspondence_algorithm_type == 0)
            {
                for (int i = 0; i < no_of_disparities * 3; i++) features.features[i] = disparities[i];
                tracking.update(features, width, height);
                for (int i = 2; i < no_of_disparities; i += 3) disparities[i] = features.features[i];
            }
            //robot_head.features[0] = features;

            // update radar
            radar.update(width, height, features);

            // dynamically adjust the difference threshold to try to
            // maintain a constant number of stereo features
            if (no_of_disparities < required_features*9/10)
            {
                difference_threshold -= 1;
                if (difference_threshold < 10)
                {
                    difference_threshold = 10;
                }
                setDifferenceThreshold(difference_threshold);
                if (no_of_disparities < required_features * 8 / 10)
                    if (peaks_per_row < 10) peaks_per_row++;
            }
            else
            {
                if (no_of_disparities >= required_features*9/10)
                {
                    if (peaks_per_row > 5)
                        peaks_per_row--;
                    else
                    {
                        difference_threshold += 2;
                        if (difference_threshold > 10000) difference_threshold = 10000;
                        setDifferenceThreshold(difference_threshold);
                    }
                }
            }

            prev_features = features;

        }
Esempio n. 2
0
 /// <summary>
 /// load stereo features for all cameras
 /// </summary>
 /// <param name="camera_index">stereo camera index</param>
 /// <param name="feat">stereo camera features</param>
 public void setStereoFeatures(int camera_index, stereoFeatures feat)
 {
     features[camera_index] = feat;
 }
Esempio n. 3
0
        /// <summary>
        /// load stereo features for all cameras
        /// </summary>
        /// <param name="binfile">file to load from</param>
        public void loadStereoFeatures(BinaryReader binfile)
        {            
            for (int i = 0; i < no_of_stereo_cameras; i++)
            {
                // create a new object
                stereoFeatures feat = new stereoFeatures(1);

                // load features for this camera
                feat.load(binfile);

                // update the head with these features
                setStereoFeatures(i, feat);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// assign stereo features to the given camera
        /// </summary>
        /// <param name="camera_index">stereo camera index</param>
        /// <param name="featurelist">stereo features</param>
        /// <param name="uncertainties">governs the standard deviation used when ray throwing</param>
        /// <param name="no_of_features">number of stereo features</param>
        public void setStereoFeatures(int camera_index, 
                                      float[] featurelist, 
                                      float[] uncertainties, 
                                      int no_of_features)
        {
            if (features[camera_index] == null)
                features[camera_index] = new stereoFeatures(no_of_features);

            if (featurelist != null)
            {
                features[camera_index].no_of_features = no_of_features;
                features[camera_index].features = (float[])featurelist.Clone();
                if (uncertainties != null)
                    features[camera_index].uncertainties = (float[])uncertainties.Clone();
            }
            else
            {
                features[camera_index].no_of_features = 0;
                features[camera_index].features = null;
            }
        }
Esempio n. 5
0
        /// <summary>
        /// load a pair of images
        /// </summary>
        private float loadImages(int stereo_cam_index, Byte[] fullres_left, Byte[] fullres_right, stereoHead head, int no_of_stereo_features, int bytes_per_pixel,
                                 int algorithm_type)
        {
            stereointerface.loadImage(fullres_left, head.calibration[stereo_cam_index].leftcam.image_width, head.calibration[stereo_cam_index].leftcam.image_height, true, bytes_per_pixel);

            stereointerface.loadImage(fullres_right, head.calibration[stereo_cam_index].leftcam.image_width, head.calibration[stereo_cam_index].leftcam.image_height, false, bytes_per_pixel);
            
            // calculate stereo disparity features
            int peaks_per_row = 5;
            stereointerface.stereoMatchRun(0, peaks_per_row, algorithm_type);

            // retrieve the features
            stereoFeatures feat = new stereoFeatures(no_of_stereo_features);
            int no_of_selected_features = 0;
            stereoFeatures features;

            no_of_selected_features = stereointerface.getSelectedPointFeatures(feat.features);
            if (no_of_selected_features > 0)
            {
                
                if (no_of_selected_features == no_of_stereo_features)
                {
                    features = feat;
                }
                else
                {
                 
                    features = new stereoFeatures(no_of_selected_features);
                    for (int f = 0; f < no_of_selected_features * 3; f++)
                        features.features[f] = feat.features[f];
                }

                // update the head with these features
                head.setStereoFeatures(stereo_cam_index, features);

                // update the colours for each feature
                head.updateFeatureColours(stereo_cam_index, fullres_left);
            }

            if (no_of_selected_features > 0) //no_of_stereo_features * 4 / 10)
                return (stereointerface.getAverageMatchingScore());
            else
                return (-1);
        }
Esempio n. 6
0
        public unsafe void stereoMatch(Byte[] left_bmp, Byte[] right_bmp,
                                       int width, int height, bool colourImages)
        {
            if (!initialised)
            {
                initialised = true;
            }

            int BytesPerPixel = 3;

            if (!colourImages)
            {
                BytesPerPixel = 1;
            }

            stereointerface.loadImage(left_bmp, width, height, true, BytesPerPixel);

            stereointerface.loadImage(right_bmp, width, height, false, BytesPerPixel);

            setMaxDisparity(max_disparity_percent);
            setRequiredFeatures(required_features);

            // do the stereo correspondence
            stereointerface.stereoMatchRun(0, peaks_per_row, correspondence_algorithm_type);

            // retrieve features
            no_of_disparities = stereointerface.getSelectedPointFeatures(disparities);

            // track the features
            features = new stereoFeatures(no_of_disparities);

            if (correspondence_algorithm_type == 0)
            {
                for (int i = 0; i < no_of_disparities * 3; i++)
                {
                    features.features[i] = disparities[i];
                }
                tracking.update(features, width, height);
                for (int i = 2; i < no_of_disparities; i += 3)
                {
                    disparities[i] = features.features[i];
                }
            }
            //robot_head.features[0] = features;

            // update radar
            radar.update(width, height, features);

            // dynamically adjust the difference threshold to try to
            // maintain a constant number of stereo features
            if (no_of_disparities < required_features * 9 / 10)
            {
                difference_threshold -= 1;
                if (difference_threshold < 10)
                {
                    difference_threshold = 10;
                }
                setDifferenceThreshold(difference_threshold);
                if (no_of_disparities < required_features * 8 / 10)
                {
                    if (peaks_per_row < 10)
                    {
                        peaks_per_row++;
                    }
                }
            }
            else
            {
                if (no_of_disparities >= required_features * 9 / 10)
                {
                    if (peaks_per_row > 5)
                    {
                        peaks_per_row--;
                    }
                    else
                    {
                        difference_threshold += 2;
                        if (difference_threshold > 10000)
                        {
                            difference_threshold = 10000;
                        }
                        setDifferenceThreshold(difference_threshold);
                    }
                }
            }

            prev_features = features;
        }
Esempio n. 7
0
        /// <summary>
        /// update the radar
        /// </summary>
        /// <param name="img_width"></param>
        /// <param name="img_height"></param>
        /// <param name="features"></param>
        public void update(int img_width, int img_height,
                           stereoFeatures features)
        {
            if (ranges_horizontal == null)
            {
                ranges_horizontal = new float[img_width];
                ranges_vertical = new float[img_height];
                rawranges_horizontal = new float[img_width];
                tempranges_horizontal = new float[img_width];
                rawranges_vertical = new float[img_height];
                variation_horizontal = new float[img_width];
                variation_vertical = new float[img_height];
                //av_variation_horizontal = new float[img_width];
                hits_horizontal = new int[img_width];
                hits_vertical = new int[img_height];
                img = new Byte[img_width * img_height * 3];
                for (int h = 0; h < img_height; h++)
                {
                    rawranges_vertical[h] = 0;
                    hits_vertical[h] = 0;
                }
                for (int w = 0; w < img_width; w++)
                {
                    rawranges_horizontal[w] = 0;
                    hits_horizontal[w] = 0;
                    //av_variation_horizontal[w] = 0;
                }
            }
            for (int h = 0; h < img_height; h++)
            {
                variation_vertical[h] = ranges_vertical[h];
                rawranges_vertical[h] = 0;
                hits_vertical[h] = 0;
            }
            for (int w = 0; w < img_width; w++)
            {
                variation_horizontal[w] = ranges_horizontal[w];
                rawranges_horizontal[w] = 0;
                hits_horizontal[w] = 0;
            }

            for (int i = 0; i < features.no_of_features; i++)
            {
                int x = (int)features.features[i * 3];
                int y = (int)features.features[(i * 3) + 1];
                float disp = features.features[(i * 3) + 2];
                if (disp > 0)
                {
                    float dist = 1 / disp;
                    rawranges_horizontal[x] += dist;
                    hits_horizontal[x]++;
                    rawranges_vertical[y] += dist;
                    hits_vertical[y]++;
                }
            }

            // clear the image
            for (int i = 0; i < img_width * img_height * 3; i++) img[i] = 0;

            for (int w = 0; w < img_width; w++)
            {
                if (hits_horizontal[w] > 0)
                {
                    rawranges_horizontal[w] = rawranges_horizontal[w] * scale / hits_horizontal[w];
                    variation_horizontal[w] -= rawranges_horizontal[w];
                    ranges_horizontal[w] = rawranges_horizontal[w];
                    tempranges_horizontal[w] = ranges_horizontal[w];
                }
            }

            // smooth out noise
            int prev_range_index = -1;
            int prev_range_index2 = -1;
            for (int smooth = 0; smooth < smoothing_steps; smooth++)
            {
                for (int w = 1; w < img_width-1; w++)
                    if (hits_horizontal[w] > 0)
                    {
                        if ((prev_range_index > -1) && (prev_range_index2 > -1))
                        {
                            ranges_horizontal[prev_range_index] = (tempranges_horizontal[w] + tempranges_horizontal[prev_range_index] + tempranges_horizontal[prev_range_index2]) / 3.0f;
                        }
                        prev_range_index2 = prev_range_index;
                        prev_range_index = w;
                    }
                for (int w = 1; w < img_width-1; w++)
                    if (hits_horizontal[w] > 0)
                        tempranges_horizontal[w] = ranges_horizontal[w];
            }


            prev_range_index = -1;
            prev_range_index2 = -1;
            for (int w = 0; w < img_width; w++)
                if (hits_horizontal[w] > 0)
                {
                    if (variation_horizontal[w] < 0) variation_horizontal[w] = -variation_horizontal[w];
                    
                    if (ranges_horizontal[w]>0.01f)
                        hits_horizontal[w] = 1;
                    else
                        hits_horizontal[w] = 0;
                    prev_range_index2 = prev_range_index;
                    prev_range_index = w;
                }

            prev_range_index = -1;
            prev_range_index2 = -1;
            for (int h = 0; h < img_height; h++)
                if (hits_vertical[h] > 0)
                {
                    rawranges_vertical[h] = rawranges_vertical[h] * scale / hits_vertical[h];
                    variation_vertical[h] -= rawranges_vertical[h];
                    ranges_vertical[h] = rawranges_vertical[h];
                    if ((h > 0) && (h < img_height - 1) &&
                        (prev_range_index > -1) && (prev_range_index2 > -1))
                    {
                        ranges_vertical[prev_range_index] = (rawranges_vertical[h] + rawranges_vertical[prev_range_index] + rawranges_vertical[prev_range_index2]) / 3.0f;
                    }

                    if (variation_vertical[h] < 0) variation_vertical[h] = -variation_vertical[h];

                    if (ranges_vertical[h] > 0.01f)
                        hits_vertical[h] = 1;
                    else
                        hits_vertical[h] = 0;
                    prev_range_index2 = prev_range_index;
                    prev_range_index = h;
                }



            int prev_x = 0;
            int prev_y = 0;
            //overhead
            for (int w = 0; w < img_width; w++)
            {
                if ((hits_horizontal[w] > 0) && (ranges_horizontal[w] > 0.01f))
                {
                    if ((variation_horizontal[w] < 50) && (variation_horizontal[prev_x] < 50))
                    {
                        if (prev_x > 0)
                        {
                            for (int xx = prev_x+1; xx < w; xx++)
                            {
                                ranges_horizontal[xx] = ranges_horizontal[prev_x] + ((xx - prev_x) * (ranges_horizontal[w] - ranges_horizontal[prev_x]) / (w - prev_x));
                                hits_horizontal[xx] = 1;
                            }
                            if (display_type == 0)
                            {
                                if (((int)ranges_horizontal[w] > 0) && ((int)ranges_horizontal[w] < img_height))
                                    drawing.drawLine(img, img_width, img_height, w, img_height - 1 - (int)ranges_horizontal[w], prev_x, prev_y, 0, 255, 0, 1, false);
                            }
                        }
                        prev_x = w;
                        prev_y = img_height - 1 - (int)ranges_horizontal[w];
                    }
                }
            }

            //side
            prev_x = 0;
            prev_y = 0;
            for (int h = 0; h < img_height; h++)
            {
                if ((hits_vertical[h] > 0) && (ranges_vertical[h] > 0.01f))
                {
                    if ((variation_vertical[h] < 50) && (variation_vertical[prev_y] < 50))
                    {
                        if (prev_y > 0)
                        {
                            for (int yy = prev_y + 1; yy < h; yy++)
                            {
                                ranges_vertical[yy] = ranges_vertical[prev_y] + ((yy - prev_y) * (ranges_vertical[h] - ranges_vertical[prev_y]) / (h - prev_y));
                                hits_vertical[yy] = 1;
                            }
                            if (display_type == 1)
                            {
                                if (((int)ranges_vertical[h] > 0) && ((int)ranges_vertical[h] < img_width))
                                    drawing.drawLine(img, img_width, img_height, (int)ranges_vertical[h], h, prev_x, prev_y, 0, 255, 0, 1, false);
                            }
                        }
                        prev_x = (int)ranges_vertical[h];
                        prev_y = h;
                    }
                }
            }

            //calculate average disparity
            int hits = 0;
            float av_disparity = 0;
            for (int w = img_width / 4; w < img_width - (img_width / 4); w++)
                if (hits_horizontal[w] > 0)
                {
                    av_disparity += (ranges_horizontal[w] / scale);
                    hits++;
                }
            if (hits > 0) av_disparity /= hits;
            if (av_disparity > 0) av_disparity = 1.0f / av_disparity;
            average_disparity = (average_disparity * 0.7f) + (av_disparity * 0.3f);

            if (display_type == 2)
            {
                for (int xx = 0; xx < img_width; xx++)
                {
                    if (hits_horizontal[xx] > 0)
                        for (int yy = 0; yy < img_height; yy++)
                        {
                            if (hits_vertical[yy] > 0)
                            {
                                int intensity = 255 - (int)((ranges_horizontal[xx] + ranges_vertical[yy]) * 255 / img_width);
                                if (intensity < 0) intensity = 0;
                                for (int col=0;col<3;col++)
                                    img[(((yy * img_width) + xx)*3) + col] = (Byte)intensity;
                            }
                        }
                }
            }

        }
Esempio n. 8
0
        /// <summary>
        /// update stereo feature tracking
        /// </summary>
        /// <param name="features">stereo features</param>
        /// <param name="img_width">image width</param>
        /// <param name="img_height">image height</param>
        public void update(stereoFeatures features, 
                           int img_width, int img_height)
        {
            stereoFeatures prev_features = null;

            if (matched_index_list.Count == 0)
            {
                IDs = new sentienceTrackingFeature[history_steps, 1000];
                for (int h = 0; h < history_steps; h++)
                {
                    matched_index_list.Add(new int[1000]);
                    for (int i = 0; i < 1000; i++)
                        IDs[h, i] = null;
                }
            }

            int prev_step = curr_step - 1;
            if (prev_step < 0) prev_step += history_steps;
            int[] matched_indexes = (int[])matched_index_list[curr_step];
            int[] prev_matched_indexes = (int[])matched_index_list[prev_step];

            if (prev_feature_list.Count > 1)
            {
                int prev_step2 = curr_step - 2;
                if (prev_step2 < 0) prev_step2 += history_steps;

                prev_features = (stereoFeatures)prev_feature_list[prev_step];
                stereoFeatures prev_features2 = (stereoFeatures)prev_feature_list[prev_step2];

                // predict the positions of features using the velocity values
                for (int i = 0; i < prev_features.no_of_features; i++)
                {
                    if (IDs[prev_step, i] != null)
                    {
                        if ((IDs[prev_step, i].vx != 0) || ((IDs[prev_step, i].vy != 0)))
                        {
                            prev_features.features[(i * 3)] = IDs[prev_step, i].predicted_x;
                            prev_features.features[(i * 3) + 1] = IDs[prev_step, i].predicted_y;
                        }
                    }
                }

                // match predicted feature positions with the currently observed ones                
                features.match(prev_features, matched_indexes,
                               img_width, img_height,
                               max_displacement_x, max_displacement_y, true);

                // fill in any gaps
                
                features.match(prev_features2, prev_matched_indexes,
                               img_width, img_height,
                               max_displacement_x, max_displacement_y, true);
                 

                for (int i = 0; i < features.no_of_features; i++)
                {
                    // if the feature has been matched with a previous one update its ID
                    if (matched_indexes[i] > -1)
                        IDs[curr_step, i] = IDs[prev_step, matched_indexes[i]];
                    else
                    {
                        if (prev_matched_indexes[i] > -1)
                            IDs[curr_step, i] = IDs[prev_step2, prev_matched_indexes[i]];
                        else
                            IDs[curr_step, i] = null;
                    }
                }
            }

            // update the persistence and average disparity for observed features
            for (int i = 0; i < features.no_of_features; i++)
            {
                int x = (int)features.features[i * 3];
                int y = (int)features.features[(i * 3) + 1];
                float disp = features.features[(i * 3) + 2];

                if (IDs[curr_step, i] != null)
                {
                    int dx = (int)(x - IDs[curr_step, i].predicted_x);
                    if (dx < 0) dx = -dx;
                    IDs[curr_step, i].updatePosition(x, y);

                    float av_disparity = 0;
                    if (dx < 50)
                    {
                        // if the feature has not moved very much
                        IDs[curr_step, i].persistence++;
                        IDs[curr_step, i].total_disparity += disp;
                        av_disparity = IDs[curr_step, i].total_disparity / IDs[curr_step, i].persistence;
                    }
                    else
                    {
                        av_disparity = (IDs[curr_step, i].average_disparity * 0.9f) +
                                                   (disp * 0.1f);                        
                    }

                    if (av_disparity > 0)
                    {
                        float disp_change = (av_disparity - disp) / av_disparity;
                        float disp_confidence = 1.0f / (1.0f + (disp_change * disp_change));
                        int idx = matched_indexes[i];
                        if (idx > -1)
                        {
                            features.uncertainties[i] = prev_features.uncertainties[idx] -
                                                        ((prev_features.uncertainties[idx] * disp_confidence * uncertainty_gain));
                            if (features.uncertainties[i] < 0.2f) features.uncertainties[i] = 0.2f;
                            features.uncertainties[i] *= 1.02f;
                            if (features.uncertainties[i] > 1) features.uncertainties[i] = 1;
                        }
                    }

                    IDs[curr_step, i].average_disparity = av_disparity;
                    features.features[(i * 3) + 2] = IDs[curr_step, i].average_disparity;
                }

                // create a new tracking feature
                if (IDs[curr_step, i] == null)
                {
                    IDs[curr_step, i] = new sentienceTrackingFeature(max_ID, x, y, disp);
                    max_ID++;
                    if (max_ID > 30000) max_ID = 1;
                }
            }

            curr_step++;
            if (curr_step >= history_steps) curr_step = 0;
            if (prev_feature_list.Count < history_steps)
                prev_feature_list.Add(features);
            else
                prev_feature_list[curr_step] = features;
            //prev_features = features;
        }