protected void GrabWindows()
        {
            string filename = "capture";

            // append temporary files path if specified
            if ((temporary_files_path != null) &&
                (temporary_files_path != ""))
            {
                if (temporary_files_path.EndsWith("\\"))
                {
                    filename = temporary_files_path + filename;
                }
                else
                {
                    filename = temporary_files_path + "\\" + filename;
                }
            }

            // Extract numbers from the camera device names
            // This is ised to uniquely identify devices so that
            // potentially more than one stereo camera could be running
            // at the same time
            string identifier = "";

            for (int cam = 0; cam < 2; cam++)
            {
                char[] ch = camera_device[cam].ToCharArray();
                for (int i = 0; i < ch.Length; i++)
                {
                    if ((ch[i] >= '0') && (ch[i] <= '9'))
                    {
                        identifier += ch[i];
                    }
                }
            }
            filename += identifier;

            if (dsCameras == null)
            {
                dsCameras = new WebcamVisionDirectShow();
                dsCameras.camera_devices = camera_device[0] + "," + camera_device[1];
                if (image_width > 0)
                {
                    dsCameras.image_width  = image_width;
                    dsCameras.image_height = image_height;
                }
                dsCameras.Open();
            }

            // set the camera index
            dsCameras.stereo_camera_index = stereo_camera_index;

            // whether to use pause or stop on the media control
            dsCameras.use_pause = use_media_pause;

            // acquire new images
            dsCameras.Grab();

            // set exposure
            dsCameras.exposure = exposure;

            // define exposure range for the camera
            dsCameras.min_exposure = min_exposure;
            dsCameras.max_exposure = max_exposure;

            if ((dsCameras.left_image_bitmap != null) &&
                (dsCameras.right_image_bitmap != null))
            {
                // grab the data from the captured images
                Bitmap[] bmp = new Bitmap[2];

                for (int cam = 0; cam < 2; cam++)
                {
                    try
                    {
                        if (cam == 0)
                        {
                            bmp[cam] = dsCameras.left_image_bitmap;
                        }
                        else
                        {
                            bmp[cam] = dsCameras.right_image_bitmap;
                        }
                    }
                    catch
                    {
                        bmp[cam] = null;
                    }
                    if (bmp[cam] == null)
                    {
                        break;
                    }

                    try
                    {
                        image_width  = bmp[cam].Width;
                        image_height = bmp[cam].Height;
                    }
                    catch
                    {
                        bmp[cam] = null;
                    }

                    //byte[] raw_image_data = new byte[image_width * image_height * 3];
                    //BitmapArrayConversions.updatebitmap(bmp[cam], raw_image_data);
                }

                if ((bmp[0] != null) && (bmp[1] != null))
                {
                    if (calibration_pattern != null)
                    {
                        if (!show_left_image)
                        {
                            SurveyorCalibration.DetectDots(bmp[0], ref edge_detector, calibration_survey[0], ref edges, ref linked_dots, ref grid, ref grid_diff, ref rectified[0]);
                        }
                        else
                        {
                            SurveyorCalibration.DetectDots(bmp[1], ref edge_detector, calibration_survey[1], ref edges, ref linked_dots, ref grid, ref grid_diff, ref rectified[1]);
                        }
                    }

                    RectifyImages(bmp[0], bmp[1]);

                    Process(bmp[0], bmp[1]);

                    // save images to file
                    if (Record)
                    {
                        string path = "";
                        if ((recorded_images_path != null) &&
                            (recorded_images_path != ""))
                        {
                            if (recorded_images_path.EndsWith("\\"))
                            {
                                path = recorded_images_path;
                            }
                            else
                            {
                                path = recorded_images_path + "\\";
                            }
                        }

                        RecordFrameNumber++;
                        DateTime t = DateTime.Now;
                        LogEvent(t, "RAW_L " + stereo_camera_index.ToString() + " raw" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", image_log);
                        LogEvent(t, "RAW_R " + stereo_camera_index.ToString() + " raw" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", image_log);

                        bmp[0].Save(path + "raw" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                        bmp[1].Save(path + "raw" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                        if ((rectified[0] != null) && (rectified[0] != null))
                        {
                            LogEvent(t, "REC_L " + stereo_camera_index.ToString() + " rectified" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", image_log);
                            LogEvent(t, "REC_R " + stereo_camera_index.ToString() + " rectified" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", image_log);

                            rectified[0].Save(path + "rectified" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                            rectified[1].Save(path + "rectified" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 2; i++)
                    {
                        if (bmp[i] == null)
                        {
                            Console.WriteLine("Warning: Did not acquire image from " + camera_device[i]);
                        }
                    }
                }

                try
                {
                    if (bmp[0] != null)
                    {
                        bmp[0].Dispose();
                    }
                    if (bmp[1] != null)
                    {
                        bmp[1].Dispose();
                    }
                }
                catch
                {
                }
            }

            if (next_camera != null)
            {
                active_camera = false;
                Pause();
                next_camera.active_camera = true;
                next_camera.Resume();
            }
        }
        protected void GrabWindows()
        {
            string filename = "capture";
            
            // append temporary files path if specified
            if ((temporary_files_path != null) &&
                (temporary_files_path != ""))
            {
                if (temporary_files_path.EndsWith("\\"))
                    filename = temporary_files_path + filename;
                else
                    filename = temporary_files_path + "\\" + filename;
            }

            // Extract numbers from the camera device names
            // This is ised to uniquely identify devices so that
            // potentially more than one stereo camera could be running
            // at the same time
            string identifier = "";
            for (int cam = 0; cam < 2; cam++)
            {
                char[] ch = camera_device[cam].ToCharArray();
                for (int i = 0; i < ch.Length; i++)
                {
                    if ((ch[i] >= '0') && (ch[i] <= '9'))
                        identifier += ch[i];
                }
            }
            filename += identifier;
            			
            if (dsCameras == null)
            {
                dsCameras = new WebcamVisionDirectShow();
                dsCameras.camera_devices = camera_device[0] + "," + camera_device[1];
                if (image_width > 0)
                {
                    dsCameras.image_width = image_width;
                    dsCameras.image_height = image_height;
                }
                dsCameras.Open();
            }            
            
            // set the camera index
            dsCameras.stereo_camera_index = stereo_camera_index;

            // whether to use pause or stop on the media control
            dsCameras.use_pause = use_media_pause;
            
            // acquire new images
            dsCameras.Grab();
            
            // set exposure
            dsCameras.exposure = exposure;

            // define exposure range for the camera
            dsCameras.min_exposure = min_exposure;
            dsCameras.max_exposure = max_exposure;

            if ((dsCameras.left_image_bitmap != null) &&
                (dsCameras.right_image_bitmap != null))
            {
                // grab the data from the captured images
                Bitmap[] bmp = new Bitmap[2];

                for (int cam = 0; cam < 2; cam++)
                {
                    try
                    {
                        if (cam == 0)
                            bmp[cam] = dsCameras.left_image_bitmap;
                        else
                            bmp[cam] = dsCameras.right_image_bitmap;
                    }
                    catch
                    {
                        bmp[cam] = null;
                    }
                    if (bmp[cam] == null) break;

                    try
                    {
                        image_width = bmp[cam].Width;
                        image_height = bmp[cam].Height;
                    }
                    catch
                    {
                        bmp[cam] = null;
                    }

                    //byte[] raw_image_data = new byte[image_width * image_height * 3];
                    //BitmapArrayConversions.updatebitmap(bmp[cam], raw_image_data);
                }

                if ((bmp[0] != null) && (bmp[1] != null))
                {
                    if (calibration_pattern != null)
                    {
                        if (!show_left_image)
                            SurveyorCalibration.DetectDots(bmp[0], ref edge_detector, calibration_survey[0], ref edges, ref linked_dots, ref grid, ref grid_diff, ref rectified[0]);
                        else
                            SurveyorCalibration.DetectDots(bmp[1], ref edge_detector, calibration_survey[1], ref edges, ref linked_dots, ref grid, ref grid_diff, ref rectified[1]);
                    }

                    RectifyImages(bmp[0], bmp[1]);

                    Process(bmp[0], bmp[1]);

                    // save images to file
                    if (Record)
                    {
                        string path = "";
                        if ((recorded_images_path != null) &&
                            (recorded_images_path != ""))
                        {
                            if (recorded_images_path.EndsWith("\\"))
                                path = recorded_images_path;
                            else
                                path = recorded_images_path + "\\";
                        }

                        RecordFrameNumber++;
                        DateTime t = DateTime.Now;
                        LogEvent(t, "RAW_L " + stereo_camera_index.ToString() + " raw" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", image_log);
                        LogEvent(t, "RAW_R " + stereo_camera_index.ToString() + " raw" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", image_log);
                        
                        bmp[0].Save(path + "raw" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                        bmp[1].Save(path + "raw" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                        if ((rectified[0] != null) && (rectified[0] != null))
                        {
                            LogEvent(t, "REC_L " + stereo_camera_index.ToString() + " rectified" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", image_log);
                            LogEvent(t, "REC_R " + stereo_camera_index.ToString() + " rectified" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", image_log);
                            
                            rectified[0].Save(path + "rectified" + identifier + "_0_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                            rectified[1].Save(path + "rectified" + identifier + "_1_" + RecordFrameNumber.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 2; i++)
                        if (bmp[i] == null) Console.WriteLine("Warning: Did not acquire image from " + camera_device[i]);
                }

                try
                {
                    if (bmp[0] != null) bmp[0].Dispose();
                    if (bmp[1] != null) bmp[1].Dispose();
                }
                catch
                {
                }
            }

            if (next_camera != null)
            {
                active_camera = false;
                Pause();
                next_camera.active_camera = true;
                next_camera.Resume();
            }
        }