/// <summary>
        /// calculate stereo correspondence
        /// </summary>
        /// <param name="state">stereo correspondence state</param>
        private static void Update(ThreadStereoCorrespondenceState state)
        {
			// set the number of features we need, later to be turned into rays
            state.correspondence.setRequiredFeatures(state.no_of_stereo_features);

            // set the calibration data for this camera
            state.correspondence.setCalibration(state.head.calibration[state.stereo_camera_index]);

			// run the correspondence algorithm
			state.correspondence.loadRawImages(
			    state.stereo_camera_index, 
			    state.fullres_left, 
			    state.fullres_right, 
			    state.head, 
			    state.no_of_stereo_features, 
			    state.bytes_per_pixel, 
			    state.correspondence_algorithm_type);
			
            // perform scan matching for forwards or rearwards looking cameras
            float pan_angle = state.head.pan + state.head.cameraPosition[state.stereo_camera_index].pan;
            if ((pan_angle == 0) || (pan_angle == (float)Math.PI))
            {
                // create a scan matching object if needed
                if (state.head.scanmatch[state.stereo_camera_index] == null)
                    state.head.scanmatch[state.stereo_camera_index] = new scanMatching();

                if (state.EnableScanMatching)
                {
                    // perform scan matching
                    state.head.scanmatch[state.stereo_camera_index].update(
					    state.correspondence.getRectifiedImage(true),
                        state.head.calibration[state.stereo_camera_index].leftcam.image_width,
                        state.head.calibration[state.stereo_camera_index].leftcam.image_height,
                        state.head.calibration[state.stereo_camera_index].leftcam.camera_FOV_degrees * (float)Math.PI / 180.0f,
                        state.head.cameraPosition[state.stereo_camera_index].roll,
                        state.ScanMatchingMaxPanAngleChange * (float)Math.PI / 180.0f);
                    if (state.head.scanmatch[state.stereo_camera_index].pan_angle_change != scanMatching.NOT_MATCHED)
                    {
                        state.scanMatchesFound = true;
                        if (state.ScanMatchingPanAngleEstimate == scanMatching.NOT_MATCHED)
                        {
                            // if this is the first time a match has been found 
                            // use the current pan estimate
                            state.ScanMatchingPanAngleEstimate = state.pan;
                        }
                        else
                        {
                            if (pan_angle == 0)
                                // forward facing camera
                                state.ScanMatchingPanAngleEstimate -= state.head.scanmatch[state.stereo_camera_index].pan_angle_change;
                            else
                                // rearward facing camera
                                state.ScanMatchingPanAngleEstimate += state.head.scanmatch[state.stereo_camera_index].pan_angle_change;
                        }
                    }
                }
            }                 
            else state.head.scanmatch[state.stereo_camera_index] = null;
			
        }
        /// <summary>
        /// ThreadStart delegate
        /// </summary>
        public void Execute()
        {
            ThreadStereoCorrespondenceState state = (ThreadStereoCorrespondenceState)_data;

            Update(state);
            state.active = false;
            _callback(_data);
        }
Beispiel #3
0
        /// <summary>
        /// load stereo images from a list
        /// </summary>
        /// <param name="images">list of images (byte arrays) in left/right order</param>
        private void loadImages(List<byte[]> images)
        {
            stopwatch correspondence_time = new stopwatch();
            correspondence_time.Start();
			
            bool scanMatchesFound = false;

            // create a set of threads
            Thread[] correspondence_thread = new Thread[no_of_stereo_cameras];			
			List<ThreadStereoCorrespondenceState> activeThreads = new List<ThreadStereoCorrespondenceState>();
			
            for (int stereo_camera_index = 0; stereo_camera_index < images.Count / 2; stereo_camera_index++)
            {
                byte[] left_image = images[stereo_camera_index * 2];
                byte[] right_image = images[(stereo_camera_index * 2) + 1];

				// create a state for the thread
				ThreadStereoCorrespondenceState state = new ThreadStereoCorrespondenceState();
				state.stereo_camera_index = stereo_camera_index;
				state.correspondence = correspondence[stereo_camera_index];
				state.correspondence_algorithm_type = correspondence_algorithm_type;
				state.fullres_left = left_image;
				state.fullres_right = right_image;
				state.bytes_per_pixel = 3;
				state.head = head;
				state.no_of_stereo_features = inverseSensorModel.no_of_stereo_features;
		        state.EnableScanMatching = EnableScanMatching;
		        state.ScanMatchingMaxPanAngleChange = ScanMatchingMaxPanAngleChange;
		        state.ScanMatchingPanAngleEstimate = ScanMatchingPanAngleEstimate;
		        state.pan = pan;
                state.active = true;
				
                // add this state to the threads to be processed
                ThreadStereoCorrespondence correspondence_update = new ThreadStereoCorrespondence(new WaitCallback(StereoCorrespondenceCallback), state);
                correspondence_thread[stereo_camera_index] = new Thread(new ThreadStart(correspondence_update.Execute));
                correspondence_thread[stereo_camera_index].Name = "stereo correspondence " + stereo_camera_index.ToString();
                correspondence_thread[stereo_camera_index].Priority = ThreadPriority.AboveNormal;
                activeThreads.Add(state);				
            }
			
            // start all stereo correspondence threads
			for (int th = 0; th < correspondence_thread.Length; th++)
                correspondence_thread[th].Start();

            // now sit back and wait for all threads to complete
            while (activeThreads.Count > 0)
            {
                for (int th = activeThreads.Count - 1; th >= 0; th--)
                {
                    // is this thread still active?
                    ThreadStereoCorrespondenceState state = (ThreadStereoCorrespondenceState)activeThreads[th];
                    if (!state.active)
                    {
						if (state.scanMatchesFound) scanMatchesFound = true;
						
                        // remove from the list of active threads
                        activeThreads.RemoveAt(th);
                    }
                }
            }			

            // if no scan matches were found set the robots pan angle estimate accordingly
            if (!scanMatchesFound) ScanMatchingPanAngleEstimate = scanMatching.NOT_MATCHED;

            correspondence_time.Stop();
            benchmark_stereo_correspondence = correspondence_time.time_elapsed_mS;
        }
        /// <summary>
        /// calculate stereo correspondence
        /// </summary>
        /// <param name="state">stereo correspondence state</param>
        private static void Update(ThreadStereoCorrespondenceState state)
        {
            // set the number of features we need, later to be turned into rays
            state.correspondence.setRequiredFeatures(state.no_of_stereo_features);

            // set the calibration data for this camera
            state.correspondence.setCalibration(state.head.calibration[state.stereo_camera_index]);

            // run the correspondence algorithm
            state.correspondence.loadRawImages(
                state.stereo_camera_index,
                state.fullres_left,
                state.fullres_right,
                state.head,
                state.no_of_stereo_features,
                state.bytes_per_pixel,
                state.correspondence_algorithm_type);

            // perform scan matching for forwards or rearwards looking cameras
            float pan_angle = state.head.pan + state.head.cameraPosition[state.stereo_camera_index].pan;

            if ((pan_angle == 0) || (pan_angle == (float)Math.PI))
            {
                // create a scan matching object if needed
                if (state.head.scanmatch[state.stereo_camera_index] == null)
                {
                    state.head.scanmatch[state.stereo_camera_index] = new scanMatching();
                }

                if (state.EnableScanMatching)
                {
                    // perform scan matching
                    state.head.scanmatch[state.stereo_camera_index].update(
                        state.correspondence.getRectifiedImage(true),
                        state.head.calibration[state.stereo_camera_index].leftcam.image_width,
                        state.head.calibration[state.stereo_camera_index].leftcam.image_height,
                        state.head.calibration[state.stereo_camera_index].leftcam.camera_FOV_degrees * (float)Math.PI / 180.0f,
                        state.head.cameraPosition[state.stereo_camera_index].roll,
                        state.ScanMatchingMaxPanAngleChange * (float)Math.PI / 180.0f);
                    if (state.head.scanmatch[state.stereo_camera_index].pan_angle_change != scanMatching.NOT_MATCHED)
                    {
                        state.scanMatchesFound = true;
                        if (state.ScanMatchingPanAngleEstimate == scanMatching.NOT_MATCHED)
                        {
                            // if this is the first time a match has been found
                            // use the current pan estimate
                            state.ScanMatchingPanAngleEstimate = state.pan;
                        }
                        else
                        {
                            if (pan_angle == 0)
                            {
                                // forward facing camera
                                state.ScanMatchingPanAngleEstimate -= state.head.scanmatch[state.stereo_camera_index].pan_angle_change;
                            }
                            else
                            {
                                // rearward facing camera
                                state.ScanMatchingPanAngleEstimate += state.head.scanmatch[state.stereo_camera_index].pan_angle_change;
                            }
                        }
                    }
                }
            }
            else
            {
                state.head.scanmatch[state.stereo_camera_index] = null;
            }
        }