Software Trigger Stereo This source code snippet illustrates how to use the software trigger to synchronize two cameras and calculate a red green stereo image.
Language: | .NET C#/Visual Basic
Version: | 3.1
Author: | IC Imaging Control Support Department
Requirements: |
Software: | IC Imaging Control 3.1
Hardware: | Trigger camera with WDM Stream Class drivers.
Download C# sample | SoftTrigger-Stereo - C#

When creating a stereo application with two cameras, the cameras have to be synchronized. Usually this is done using an external trigger hardware. With IC Imaging Control 3.1 and the new firmware for the FireWire and USB cameras the trigger can be released by software. No external trigger pulse hardware is necessary. This sample shows how to:

- use two cameras
- setup up both cameras with the same property values
- query and use the software trigger property
- wait for both images being provided
- merge the images

The sample application's window looks as follows:

The Device buttons are used to select the video capture device for the left and right IC Imaging Control.

The Settings button is used to configure the left video capture device. After the left video capture device has been configured, the same property values will be sent to the right video capture device.

The Enable Trigger checkbox is use to enable the external trigger for both video capture devices.

The Trigger triggers one software trigger and merges the images.

The Continuous Trigger button starts a timer for continous triggering. In the timer event handler a software trigger trigerred and the images are merged.

Source code in detail

In the constructor both IC Imaging Control objects are set up. The names of the controls are icLeft and icRight.

    C#

    public Form1()
    {
        InitializeComponent();
        chkContinuousTrigger.Enabled = false;
        btnTrigger.Enabled = false;

        //Setup the left and right IC Imaging Control
        SetupIC(icLeft, "Left", out SoftTriggerLeft);
        SetupIC(icRight, "Right", out SoftTriggerRight);
    }

Since the code for setting up the controls is for both the same, it is usefull to create a function doing this:

    C#

    private void SetupIC(ICImagingControl CurrentIC, String Position,out VCDButtonProperty  SoftTrigger)
    {
        CurrentIC.LiveDisplayDefault = false;
        CurrentIC.LiveDisplaySize = CurrentIC.Size;
        CurrentIC.LiveCaptureContinuous = true;
        CurrentIC.MemoryCurrentGrabberColorformat = ICImagingControlColorformats.ICRGB24;

        SoftTrigger = null;
        try
        {
            // Try to load the previously used video capture device.
            CurrentIC.LoadDeviceStateFromFile(Position + ".xml", true);
        }
        catch { }

        if (CurrentIC.DeviceValid)
        {
            try
            {
                // Try to load the previously used settings.
                CurrentIC.LoadDeviceStateFromFile("Settings.xml", false);
            }
            catch { }
            CurrentIC.LiveStart();
            CurrentIC.ImageBuffers[0].Lock();

            // Get the software trigger property of the video capture device.
            SoftTrigger = (VCDButtonProperty)CurrentIC.VCDPropertyItems.FindInterface(VCDIDs.VCDID_TriggerMode +
                ":{FDB4003C-552C-4FAA-B87B-42E888D54147}:" +
                VCDIDs.VCDInterface_Button);
        }
    }

In the first few lines the control's video display size is set, so the original live videos are resized.

In the next step, it is tried to load the last used video capture device. The device states have been saved in the files Left.xml and Right.xml. The filename has been passed to the SetupIC function.

After a video capture was opened successfully, the device state for the properties, that are used for both video capture devices are loaded from the file settings.xml.

All the xml files for the device settings are created by this program, when the Device and Settings buttons have been clicked.

If the video capture device has been opened successfully, the live video stream is started.

The first image buffer is locked, to prevent it from being overwritten. This image buffer is used later to keep the merged image.

In the last step of this function the SoftTrigger property is querried. This property is of type VCDButtonProperty, so for triggering a software trigger its Push method is used.

Configuring both devices

Both video capture devices are to be configured in the same way, i.e. they must have the same video format, exposure settings etc. Only the video capture device in the icLeft control is configured. After doing so, its device state is saved into the file Settings.xml. This file is loaded by icRight in the next step. Please remark: the second parameter of LoadDeviceStateFromFile is false. This means a video capture has already been opened and only the properties are set to the values saved in the xml file.

    C#

    private void btnSettings_Click(object sender, EventArgs e)
    {
        if (icLeft.DeviceValid)
        {
            // Configure the left video capture device,
            icLeft.ShowPropertyDialog();
            // Save the properties to the "settings.xml" file
            icLeft.SaveDeviceStateToFile("Settings.xml");

            if (icRight.DeviceValid)
            {
                try
                {
                    // Now configure the right video capture device in the same way as the left
                    // by loading the setting from the previously saved "settings.xml".
                    icRight.LoadDeviceStateFromFile("Settings.xml", false);
                }
                catch { }
            }
        }
    }

Triggering both devices

For triggering both video capture devices at nearly the same time, the Push method of both software triggers must be called.

    C#

    private void GenerateTrigger()
    {
        if (SoftTriggerLeft != null && SoftTriggerRight != null )
        {
            NewImageLeft = false;
            NewImageRight = false;

            // Trigger the software triggers for both video capture devices,
            SoftTriggerLeft.Push();
            SoftTriggerRight.Push();

            int Tries = 5;
            // Use maximum of 5 tries for check of both images have arrived.
            while (Tries > 0 && (NewImageLeft == false || NewImageRight == false))
            {
                System.Threading.Thread.Sleep(100);
                Tries--;
            }

            if (NewImageLeft == false || NewImageRight == false)
            {
                MessageBox.Show("It was not possible to grab both images.\nPlease try again");
            }
            else
            {
                // Both images are available, now create the red green image.
                CreateRedGreenImage();
            }
        }
    }

In this GenerateTrigger function not only the software triggers are triggered, but it is also waited for both images to be provided. The program has to flags NewImageLeft and NewImageRight. Before the software triggers are triggered, these flags are set to false. This program uses the ImageAvailable events of icLeft and icRight to set the appropriate flag to true, when an image was provided.

After the software triggers have been triggered, the program waits in a simple while loop for NewImageLeft and NewImageRight becoming true. If both are true, the image can be merged by a call to CreateRedGreenImage. If one or both of them are not true, then there was a frame drop.

Creating the red green stereo image

The resulting red green image will be stored in the first image buffer of icLeft. The pixel format of the image buffer has been set to RGB24, which means the pixels are save as BGR (blue,green,red). The blue value of each pixel is alwas 0. The pixel data of the right video capture device will be copied into the green value, of the left video capture device in the red value. Since both cameras are monochrome cameras, only the first byte of each pixel is copied.

    C#

    private void CreateRedGreenImage()
    {
        ImageBuffer IB = icLeft.ImageBuffers[0];
        ImageBuffer Left = icLeft.ImageActiveBuffer;
        ImageBuffer Right = icRight.ImageActiveBuffer;
        int BufferSize = IB.Lines * IB.BytesPerLine;

        for (int i = 0; i < BufferSize; i += 3)
        {
            IB[i] = 0;             // Blue
            IB[i + 1] = Right[i];  // Green, the red glass on the right eye
            IB[i + 2] = Left[i];   // Red,  the green glass on the left eye
        }

        pictureBox1.Image = IB.Bitmap;
        pictureBox1.Update();
    }

The resulting image is displayed in a picture box.

Firmware versions for software trigger

- FireWire >= 3311
- USB CCD >= 1013
- USB CMOS n/a

For a firmware update please generate a support case.