我的/dev
文件夹中有很多视频设备(例如video1
,video2
,...,video9
)和一个/dev/video
总是指向有效的设备(当然,它可以改变)。
我想使用/dev/video
打开带有OpenCV的cv::Videocapture
设备,并意识到只有两种方法可以打开它:
VideoCapture::VideoCapture(const string& filename)
VideoCapture::VideoCapture(int device)
第一个打开文件,第二个打开/dev/video[device]
。
有没有办法像cap = cv::VideoCapture("/dev/video");
那样做什么?
答案 0 :(得分:2)
使用当前的OpenCV 3.2.0,您可以创建一个新的捕获:
cv::VideoCapture cap("/dev/video20", cv::CAP_V4L);
其中一个额外的构造函数:
VideoCapture (const String &filename, int apiPreference)
使用API首选项打开视频文件或捕获设备或IP视频流以进行视频捕获。
使用open函数也可以这样做:
cap.open("/dev/video20", cv::CAP_V4L);
我已经使用当前git master的自编译openCV在Kubuntu 16.10下成功测试了这个。
答案 1 :(得分:0)
通过查看OpenCV 2.4.11(cap.cpp)的源代码,您可以看到使用const字符串&的重载。 filename正在调用' cvCreateFileCapture'它使用其他插件作为FFMPEG或GStreamer来加载文件,所以答案是否定的。
bool VideoCapture::open(const string& filename)
{
if (isOpened()) release();
cap = cvCreateFileCapture(filename.c_str());
return isOpened();
}
答案 2 :(得分:0)
最好的办法是解析设备的ID。
#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 );
注意使用canonical()
使路径成为绝对路径并解析任何符号链接。这样,即使您从/dev/v4l/by-id
或/dev/v4l/by-path
提供v4l设备路径,它仍然有效,例如:
"/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"