Create openCV VideoCapture from interface name instead of camera numbers

KenArrari picture KenArrari · Mar 6, 2016 · Viewed 13.1k times · Source

The normal way to create a videocapture is this:

cam = cv2.VideoCapture(n)

where n corresponds to the number of /dev/video0, dev/video1

But because I'm building a robot that uses multiple cameras for different things, I needed to make sure that it was being assigned to the correct camera, I created udev rules that created devices with symbolic links to the correct port whenever a specific camera was plugged in.

They appear to be working because when I look in the /dev directory I can see the link:

/dev/front_cam -> video1

However I'm not sure how to actually use this now.

I thought I could just open it from the filename, as if it was a video, but cam = cv2.VideoCapture('/dev/front_cam') doesn't work.

Neither does cv2.VideoCapture('/dev/video1')

It doesn't throw an error, it does return a VideoCapture object, just not one that's opened (cam.isOpened() returns False).

Answer

bontragersw picture bontragersw · Oct 31, 2019

Each of my video4linux devices creates 2 device nodes. For example, /dev/video0 and /dev/video1 are both related to my internal webcam. When I plug in a second USB webcam, /dev/video2 and /dev/video3 both appear. However, I can only use the lower-numbered device of each pair for video capture (i.e. /dev/video0 and /dev/video2).

I watched my device arrival with udevadm monitor, and then inspected each of the camera devices with udevadm info --path=$PATH_FROM_UDEVADM_MONITOR --attribute-walk. The devices which work for video capture have ATTR{index}=="0".

Maybe instead of trying to open /dev/video1, you just need to open /dev/video0:

cam = cv2.CaptureVideo("/dev/video0")