Evans
Evans

Reputation: 1599

Set capture device EmguCV

I´m using class Capture from EmguCV to take images from a WebCam.

According to the documentation of the class (http://www.emgu.com/wiki/files/2.0.0.0/html/18b6eba7-f18b-fa87-8bf2-2acff68988cb.htm), Capture has 3 constructors.

Using public Capture() its supposed to use the default camera and it works properly.

As I saw in one of the examples, seems that

public Capture(string fileName) //takes a video file as the source for the captures.

The last constructor is

public Capture(int camIndex) //which is supposed to "Create a capture using the specific camera" 

I tried to use this last constructor to allow the user to choose the device in case he has more than one camera (for example, the integrated camera in a laptop or a USB cam pluged in)

My problem is I don´t know how to get a list of available devices. Tried to create captures with index from 0 to 99 and try to grab a frame expecting an exception, but it just takes a black image with the 100 captures. Also, when I use the default camera, I don´t know how to get his index.

Any help?

Edit: With the info in the answer of Shiva I got it working with this (I post it for future references):

private void onLoad(object sender, RoutedEventArgs e)
{
    //Add the image processing to the dispatcher
    this.Dispatcher.Hooks.DispatcherInactive += new EventHandler(dispatcherTimer_Tick);

    //Get the information about the installed cameras and add the combobox items 
    DsDevice[] _SystemCamereas = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
    Video_Device[] WebCams = new Video_Device[_SystemCamereas.Length];
    for (int i = 0; i < _SystemCamereas.Length; i++)
    {
        WebCams[i] = new Video_Device(i, _SystemCamereas[i].Name, _SystemCamereas[i].ClassID); //fill web cam array
        ComboBoxDevices.Items.Add(WebCams[i].ToString());
    }
}

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    if (capture != null)
    {
        //Capture an image
        Image<Bgr, byte> img = capture.QueryFrame();
        //Show the image in the window
        ImageOriginal.Source = ImageProcessor.ToBitmapSource(img);
    }
}

private void ComboBoxDevices_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    //If there is already a capture, dispose it
    if (capture != null)
    {
        capture.Dispose();
    }
    //Get the selected camera
    int selectedDevice = ComboBoxDevices.SelectedIndex;
    try
    {
        //Create new capture with the selected camera
        capture = new Capture(selectedDevice);
    }
    catch (Exception excpt)
    {
        MessageBox.Show(excpt.Message);
    }
}

Upvotes: 4

Views: 26102

Answers (2)

Shiva
Shiva

Reputation: 6887

The capture object can be used to give static files as input using the following code

 Capture grabber = new Emgu.CV.Capture(@".\..\..\file.avi");//can be relative path or absolute path of the video file.

For finding the list of connected web cams will need to import something like Direct Show (DirectShow.Net.dll) into the project and use the following code to retrieve the list of connected web cams .

    DsDevice[] _SystemCamereas = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
    Video_Device[] WebCams = new Video_Device[_SystemCamereas.Length];
        for (int i = 0; i < _SystemCamereas.Length; i++)
        {
            WebCams[i] = new Video_Device(i, _SystemCamereas[i].Name, _SystemCamereas[i].ClassID); //fill web cam array
            Camera_Selection.Items.Add(WebCams[i].ToString());
        }

Check this link for the full code http://www.emgu.com/wiki/index.php?title=Camera_Capture

This list can be populated into a combo box and each connected device can be chosen to retrieve the video input from the specific device.

Example can be found here: http://fewtutorials.bravesites.com/entries/emgu-cv-c/level-2---use-multiple-cameras-in-one-application.

For your last question the Default Camera always has the index of 0. So for initializing the Capture Object with default camera you will have to use the following code

Capture grabber = new Emgu.CV.Capture(0);

Upvotes: 4

Billy Mailman
Billy Mailman

Reputation: 272

Examining the EMGU CV source seems to indicate that it's just passing the index off to the underlying OpenCV library, as part of the cvCreateCameraCapture (int index) function. That function is... A bit of a mess of #ifdefs, but from what I can see (and from what the comments indicate), the index is used to specify both the camera you want, and the API it should be using.

Try successively trying multiples of a hundred; each should use a different codec, attempting to use the first camera. It may be that you have one of the APIs listed compiled into your copy of OpenCV, but not working correctly on your system.

Edit: Drilling down further, it seems like it ends up at this function call, which uses the MFEnumDeviceSources function to get the list. The device you wanted is then returned out of that list (see the getDevice function a few lines higher up). So, it looks to me like the dialog you mentioned in your comment is part of Windows' MediaFoundation stuff, in which case you might want to google the wording of the message, see if some people with more experience with MF can point you in the right direction.

Upvotes: 2

Related Questions