Using device name instead of ID in OpenCV method VideoCapture.open()

瘦欲@ 提交于 2019-11-30 18:11:07

问题


I have a lot of video devices in my /dev folder (e.g. video1, video2, ..., video9) and one /dev/video which is always pointing to the valid device (which, of course, can change). I want to open the /dev/video device with OpenCV using cv::Videocapture and realized that there are only two ways to open it:

VideoCapture::VideoCapture(const string& filename)
VideoCapture::VideoCapture(int device)

The first one opens a file and the second one opens /dev/video[device].

Is there any way to do something like cap = cv::VideoCapture("/dev/video");?


回答1:


with current OpenCV 3.2.0 you can create a new capture like this:

cv::VideoCapture cap("/dev/video20", cv::CAP_V4L);

its one of the additional constructors:

VideoCapture (const String &filename, int apiPreference)
Open video file or a capturing device or a IP video stream for video capturing with API Preference.

this is also possible with the open function:

cap.open("/dev/video20", cv::CAP_V4L);

i have tested this successfully under Kubuntu 16.10 with self compiled openCV from current git master.




回答2:


By looking at the source code of OpenCV 2.4.11 (cap.cpp) you can see that the overload using const string& filename is calling 'cvCreateFileCapture' which uses other plugins as FFMPEG or GStreamer to load files so the answer is no.

bool VideoCapture::open(const string& filename)
{
   if (isOpened()) release();
   cap = cvCreateFileCapture(filename.c_str());
   return isOpened();
}



回答3:


The best thing is to parse the ID of the device.

#include <regex>
#include <boost/filesystem.hpp>

...

boost::filesystem::path path( "/dev/video3" );
auto target = boost::filesystem::canonical(path).string();
std::regex exp( ".*video(\\d+)" );
std::smatch match;
std::regex_search( target, match, exp );
auto id = strtod( match[1] );
auto cap = cv::VideoCapture( id );

Note the use of canonical() to make the path absolute and resolve any symbolic links. This way it works even if you give it v4l device paths from /dev/v4l/by-id or /dev/v4l/by-path like for example:

"/dev/v4l/by-id/usb-046d_0990_1188AD49-video-index0"
"/dev/v4l/by-path/pci-0000:00:13.2-usb-0:4.4.4:1.0-video-index0"


来源:https://stackoverflow.com/questions/20266743/using-device-name-instead-of-id-in-opencv-method-videocapture-open

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!