Two cameras with different settings

Hello fellow programmer,
I’m having trouble trying to figure out how to film with two identical cameras with different settings at the same time.
So far the two cameras only film in the same settings but there is some weird things happening:
- The displayed fps is twice what I put in the configuration settings.
- When i look up the camera’s with Stemmer app, the fps is set to the same value I set in my application so it “should work”.

Here is some samples of my application:

Grab event:

    {
        // turn grab on or off
        if (m_cbGrab.Checked)
        {
            if (IsRecordingInitialized)
            {
                StartRecording();
            }
            else
            {
                InitializeRecording();
                m_cvImage.Grab = true;
                m_cvImage2.Grab = true;
                if (!m_bTimerStarted)
                {
                    m_cvDisplay.StatusUserText = string.Empty;
                    m_cvDisplay2.StatusUserText = string.Empty;
                    m_framecounter = 0;
                    m_FramesToNextMeasurement = 1;
                }
            }
        }
        else
        {
            if (IsRecordingInitialized)
                StopRecording();
            m_cvImage.Grab = false;
            m_cvImage2.Grab = false;
        }

        UpdateUI();
    }

start recording method:

    {

        System.IO.File.WriteAllText(startFile, DateTime.Now.ToString("o"));
        //m_Recorder.StartRecording();
        //m_Recorder2.StartRecording();

        if (!(m_Recorder.StartRecording() && m_Recorder2.StartRecording()))
        {
            MessageBox.Show("Error while Start Recording. Check if target video is open and writable");
            StopRecording();
            return;
        }
        if (timerRecord.Interval != 0)
            timerRecord.Start();
        if (m_Recorder.AcquisitionMode == Movie2Recorder.AcquisitionModeType.AddFrame)
            m_cvImage.Grab = true;
        else
            m_cvImage.Grab = false;

        if (m_Recorder2.AcquisitionMode == Movie2Recorder.AcquisitionModeType.AddFrame)
            m_cvImage2.Grab = true;
        else
            m_cvImage2.Grab = false;
        m_RecordButton.Text = "recording...(Click to stop)";
    }

loading driver method:

    {
        // if grab is currently running, stop it first
        if (m_cvImage.Grab)
        {
            m_cbGrab.Checked = false;
            this.m_cbGrab_CheckedChanged(sender, e);
        }
        // Open LoadImage Dialog
        String filename = "";
        if (m_cvImage2.LoadImageByDialog())
        {
            // store filename as it will be overwritten with axCVimage2.Image = ...
            filename = m_cvImage2.Filename;

            // check if opened driver supports the ICameraSelect2 interface
            if (Driver.ICameraSelect2.CanCameraSelect2(m_cvImage2.Image))
            {
                // change camera
                SharedImg imgNew = null;
                try
                {
                    int result = Driver.ICameraSelect2.CS2SetCamPort(m_cvImage2.Image, 1, 0, out imgNew);

                    if (result == 0 && imgNew.Handle != IntPtr.Zero)
                    {
                        m_cvImage2.Image = imgNew;
                        m_cvDisplay2.Image = (int)m_cvImage2.Image;
                        m_cvDisplay2.Refresh();
                    }
                }
                finally
                {
                    // ActiveX controls share the assigned image (shared ownership)
                    if (imgNew != null)
                        imgNew.Dispose();
                }
            }

            else
            {
                MessageBox.Show("Image does not support the ICameraSelect2 interface.");
                return;
            }
        }

        else
        {
            MessageBox.Show("Error while loading the driver");
            return;
        }

        if (m_cvImage.LoadImage(filename))
        {
            m_cvDisplay.Image = (int)m_cvImage.Image;
        }

       
        this.ReadGenICamInfos();
        this.ReadGenICamInfos2();
        // Register all Callbacks
        this.RegisterCallbacks();
    }

If you need more information, dont hesitate! I only put these sample because i think they are the most relevant.

Hello morin,

I had a quick look at your code, it looks ok so far.
I would like to see the “InitializeRecording” method, and the part where you create your recorder objects.
Maybe you can zip your project and upload so I can debug it.

Regards,
Tim

I don’t have yet the authorization to share all the code but here are the bits of code you asked for:

Loading Method:

{
        // set LeftButtonMode of the Display to create AOIs with the mouse
        this.m_cvDisplay.LeftButtonMode = CVDISPLAYLib.LeftButtonMode.LB_FRAME;
        // show image size in the Display status line
        this.m_cvDisplay.StatusImageSize = true;
        // set DirectDraw property of the Display
        this.m_cvDisplay.DirectDrawEnabled = true;

        m_Recorder = new Movie2Recorder(Movie2Recorder.RecordingEngineType.DirectShow, m_cvImage.Image);

        // Register Recorder Image Snaped Event
        m_Recorder.ImageSnapped += m_Recorder_ImageSnaped;


        // set LeftButtonMode of the Display to create AOIs with the mouse
        this.m_cvDisplay2.LeftButtonMode = CVDISPLAYLib.LeftButtonMode.LB_FRAME;
        // show image size in the Display status line
        this.m_cvDisplay2.StatusImageSize = true;
        // set DirectDraw property of the Display
        this.m_cvDisplay2.DirectDrawEnabled = true;

        m_Recorder2 = new Movie2Recorder(Movie2Recorder.RecordingEngineType.DirectShow, m_cvImage2.Image);

        // Register Recorder Image Snaped Event
        m_Recorder2.ImageSnapped += m_Recorder2_ImageSnaped;


        // Register Recorder Image Snaped Event
        foreach (string codec in m_Recorder.AvailableCodecs)
        {
            m_CodecsList.Items.Add(codec);
        }
        m_CodecsList.SelectedIndex = 0;


        // Connect ProvideMetaData Event with Event function
        m_Recorder.ProvideMetaData += recorderReadyForNewMetaData;
        m_Recorder2.ProvideMetaData += recorderReadyForNewMetaData;

        // Set initial FileName
        string fileName = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Movie2Video.avi";
        m_FileNameTextBox.Text = fileName.Replace(@"\\", @"\");

        _radioButtonSynchronizeAfterCopy.Checked = true;
        _radioButtonAddFrame.Checked = true;
    }

InitializeRecording:

{
        Int64 result = (Int64)DateTime.UtcNow.Subtract(DateTime.MinValue).TotalSeconds;
        String path = @"D:\" + result.ToString();
        startFile = path + @"\start_recording.txt";
        endFile = path + @"\end_recording.txt";
        dirName = result.ToString();
        DirectoryInfo di = Directory.CreateDirectory(path);
        string fileName = path + @"\Movie2Video.avi";
        m_FileNameTextBox.Text = fileName.Replace(@"\\", @"\");

        IsRecordingInitialized = true;
        m_Recorder.TargetFileName = m_FileNameTextBox.Text;
        m_Recorder.FrameRate = m_LastPlaybackFPS;
        m_Recorder.CompressionCodecIndex = m_CodecsList.SelectedIndex;
        m_Recorder.UseMetaData = _saveMetadataToolStripMenuItem.Checked;

        String filename_cam2 = m_FileNameTextBox.Text;
        filename_cam2 = filename_cam2.Remove(filename_cam2.Length - 4);
        filename_cam2 += "_camera2.avi";
        m_Recorder2.TargetFileName = filename_cam2;
        m_Recorder2.FrameRate = m_LastPlaybackFPS;
        m_Recorder2.CompressionCodecIndex = m_CodecsList.SelectedIndex;
        m_Recorder2.UseMetaData = _saveMetadataToolStripMenuItem.Checked;

        if (m_Recorder2.Image == 0)
        {
            m_Recorder2.Image = m_cvImage2.Image;
        }

        if (!m_Recorder.PreStartRecording())
        {
            MessageBox.Show("Error while Initialize Recording. Check if target video is open and writable for camera 1");
            IsRecordingInitialized = false;
            return;
        }
        else if (!m_Recorder2.PreStartRecording())
        {
            MessageBox.Show("Error while Initialize Recording. Check if target video is open and writable for camera 2");
            IsRecordingInitialized = false;
            return;
        }

        try
        {
            maxFPSrequested = (double.Parse(timerText.Text) / 1000) * double.Parse(_FPSTextBox.Text);
        }
        catch
        {
            maxFPSrequested = 0;
        }

        m_RecordButton.Text = "Record";
    }

thanks again for helping!

Hello morin,

I only see frameCounter member.
Could it be, that you increment the framecounter in BOTH ImageSnapped events (of camera 1 and camera 2)?
This would explain why the display is twice the framerate you configured.

That might actually be it! let be change some bits and I’ll come back!

Clearly, that’s why it was displaying the double of the fps, i managed to correct it, but not to target the fps of the second camera though.

Calculate fps for 1st camera:
{
// Calculate FPS
m_framecounter++;

        if (m_framecounter == 0)
        {
            Utilities.TWStartStopWatch(m_Timer, 0);
        }
        else if (m_framecounter >= m_FramesToNextMeasurement)
        {
            // read the time since the last ImageSnaped event
            double dTimeMS;
            Utilities.TWReadStopWatch(m_Timer, 0, out dTimeMS);
            // Measure every second and use the last MeasuredFPS to
            // now how many frames have to be counted
            double measuredFPS = (m_framecounter * 1.0 / dTimeMS * 1000.0);


            if ((int)m_LastMeasuredFPS > 1)
                m_FramesToNextMeasurement = (int)measuredFPS;
            else
                m_FramesToNextMeasurement = 1;


            if (!m_FPSRecommended && measuredFPS > 0.1 && Math.Abs(measuredFPS - m_LastMeasuredFPS) < 0.2)
            {
                m_LastPlaybackFPS = measuredFPS;
                _FPSTextBox.Text = m_LastPlaybackFPS.ToString();
            }

            m_framecounter = 0;
            m_LastMeasuredFPS = measuredFPS;
            Utilities.TWStartStopWatch(m_Timer, 0);

        }

        return m_LastMeasuredFPS;
    }

calculate fps for second camera:

{
// Calculate FPS
m_framecounter_2++;

        if (m_framecounter_2 == 0)
        {
            Utilities.TWStartStopWatch(m_Timer_2, 0);
        }
        else if (m_framecounter_2 >= m_FramesToNextMeasurement_2)
        {
            // read the time since the last ImageSnaped event
            double dTimeMS;
            Utilities.TWReadStopWatch(m_Timer_2, 0, out dTimeMS);
            // Measure every second and use the last MeasuredFPS to
            // now how many frames have to be counted
            double measuredFPS_2 = (m_framecounter_2 * 1.0 / dTimeMS * 1000.0);


            
            if ((int)m_LastMeasuredFPS_2 > 1)
                m_FramesToNextMeasurement_2 = (int)measuredFPS_2;
            else
                m_FramesToNextMeasurement_2 = 1;


            if (!m_FPSRecommended && measuredFPS_2 > 0.1 && Math.Abs(measuredFPS_2 - m_LastMeasuredFPS_2) < 0.2)
            {
                m_LastPlaybackFPS = measuredFPS_2;
                _FPSTextBox.Text = m_LastPlaybackFPS.ToString();
            }

            m_framecounter_2 = 0;
            m_LastMeasuredFPS_2 = measuredFPS_2;
            Utilities.TWStartStopWatch(m_Timer_2, 0);

        }

        return m_LastMeasuredFPS_2;
    }

I am not quite sure if I understand your new problem correctly. The fps of the second camera is calculated incorrectly?

Yes, both methods calculate the FPS of the first camera, I want the second method to calculate the FPS of the second camera but I don’t know what to change to target the camera.

You have to use the ImageSnapped event of the second camera

Oh I found the problem, i didn’t link any imagesnapped method to my second camera, now i made another method for the second one and linked it and it works! thanks a lot for your help and your time!

Youre welcome, glad it works now.