在OpenCV方法中使用设备名称而不是ID VideoCapture.open()

时间:2013-11-28 12:52:44

标签: c++ opencv video camera video-capture

我的/dev文件夹中有很多视频设备(例如video1video2,...,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");那样做什么?

3 个答案:

答案 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"