Capturing images in your applications with the VideoCapture
class of the EmguCV library
(an OpenCV wrapper for dotnet) requires supplying an index value to choose a specific camera.
However, finding this number can be challenging, and since it can change over time, it might cause your application to break.
In this article, I will demonstrate how to use the actual name of the camera instead of the index value with OpenCV’s VideoCapture
class.
Capture an image
To start, this is the code to capture an image with the VideoCapture
class.
The code saves the frame from input 1
to the frame.jpg
file.
How do I know that I need the value of 1
?
Just by trial and error.
A couple of weeks ago the value was 0
.
I am not sure why Windows decided to change the order of devices,
but it happened, and my application broke.
Enumerate video input devices
Getting the list of video devices with .NET is not as easy as it might sound. To enumerate devices, we will have to fall back to the world of COM interop and magic values.
This is done with the System Device Enumerator.
Creating the enumerator will return an object that implements the ICreateDevEnum
interface.
This interface needs to be declared first.
It is possible to get the correct C# type using the correct GUID value. With the type available, create an instance.
Now it is possible to enumerate all system devices. In this case we only want video input devices. Provide the value of the video input device class to filter the enumerator.
If there are no errors creating the enumerator, it is now possible to do some enumeration. Loop until there are no devices left.
Get the friendly name of the device
With the moniker, it is possible to get more information about the device. This information is stored in a property bag.
To access the property bag, first declare a IPropertyBag
interface.
The property bag can be bound to the moniker.
Use the Read
method to query for the FriendlyName
property.
Put it all together
I have put all the bits together and shared this code on GitHub. I also provided this solution as a NuGet package for convenience.
As a consumer, I can use the name of my device to get the index and create an instance of the VideoCapture
class.
If you have any improvements on the code, please open an issue and/or submit a pull request.