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");
?
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.
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();
}
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