一般来说,USB的UVC摄像头在Linux平台下通过V4L驱动来使用。OpenCV打开USB的UVC摄像头一般也通过V4L驱动来打开。打开方法网上都有,一般就是通过VideoCapture的open(int index)函数来打开,其中index设为202。如下:
VideoCapture cap;
Mat frame;
if(!cap.open(202))
cout<<"camera error!"<<endl;
while(1)
{
cap>>frame;
//do what you want here
//put your code here
}
注意这个打开的索引号,只有设置为202才能打开UVC摄像头,设置成其他的往往都无法开UVC摄像头,和windows平台不一样。那么,为什么UVC摄像头的索引需要设为202呢?我们可以看下Opencv的源码,就可以明白。
CV_IMPL CvCapture * cvCreateCameraCapture (int index)
{
// interpret preferred interface (0 = autodetect)
int pref = (index / 100) * 100;
// remove pref from index
index -= pref;
// local variable to memorize the captured device
CvCapture *capture = 0;
switch (pref)
{
default:
// user specified an API we do not know
// bail out to let the user know that it is not available
if (pref) break;
#ifdef HAVE_MSMF
case CV_CAP_MSMF:
if (!capture)
capture = cvCreateCameraCapture_MSMF(index);
if (pref) break;
#endif
#ifdef HAVE_TYZX
case CV_CAP_STEREO:
if (!capture)
capture = cvCreateCameraCapture_TYZX(index);
if (pref) break;
#endif
case CV_CAP_VFW:
#ifdef HAVE_VFW
if (!capture)
capture = cvCreateCameraCapture_VFW(index);
#endif
#if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO
if (!capture)
capture = cvCreateCameraCapture_V4L(index);
#endif
#ifdef HAVE_GSTREAMER
if (!capture)
capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2,
reinterpret_cast<char *>(index));
if (!capture)
capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L,
reinterpret_cast<char *>(index));
#endif
if (pref) break; // CV_CAP_VFW
case CV_CAP_FIREWIRE:
#ifdef HAVE_DC1394_2
if (!capture)
capture = cvCreateCameraCapture_DC1394_2(index);
#endif
#ifdef HAVE_DC1394
if (!capture)
capture = cvCreateCameraCapture_DC1394(index);
#endif
#ifdef HAVE_CMU1394
if (!capture)
capture = cvCreateCameraCapture_CMU(index);
#endif
#if defined(HAVE_GSTREAMER) && 0
// Re-enable again when gstreamer 1394 support will land in the backend code
if (!capture)
capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_1394, 0);
#endif
if (pref) break; // CV_CAP_FIREWIRE
#ifdef HAVE_MIL
case CV_CAP_MIL:
if (!capture)
capture = cvCreateCameraCapture_MIL(index);
if (pref) break;
#endif
#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
case CV_CAP_QT:
if (!capture)
capture = cvCreateCameraCapture_QT(index);
if (pref) break;
#endif
#ifdef HAVE_UNICAP
case CV_CAP_UNICAP:
if (!capture)
capture = cvCreateCameraCapture_Unicap(index);
if (pref) break;
#endif
#ifdef HAVE_PVAPI
case CV_CAP_PVAPI:
if (!capture)
capture = cvCreateCameraCapture_PvAPI(index);
if (pref) break;
#endif
#ifdef HAVE_OPENNI
case CV_CAP_OPENNI:
if (!capture)
capture = cvCreateCameraCapture_OpenNI(index);
if (pref) break;
#endif
#ifdef HAVE_OPENNI2
case CV_CAP_OPENNI2:
if (!capture)
capture = cvCreateCameraCapture_OpenNI2(index);
if (pref) break;
#endif
#ifdef HAVE_XIMEA
case CV_CAP_XIAPI:
if (!capture)
capture = cvCreateCameraCapture_XIMEA(index);
if (pref) break;
#endif
#ifdef HAVE_AVFOUNDATION
case CV_CAP_AVFOUNDATION:
if (!capture)
capture = cvCreateCameraCapture_AVFoundation(index);
if (pref) break;
#endif
#ifdef HAVE_GIGE_API
case CV_CAP_GIGANETIX:
if (!capture)
capture = cvCreateCameraCapture_Giganetix(index);
if (pref) break; // CV_CAP_GIGANETIX
#endif
}
return capture;
}
上面是OPENCV的打开摄像头的中间一层的源码。注意其中开头的代码
int pref = (index / 100) * 100;
// remove pref from index
index -= pref;
可见,pref是索引号中百的倍数,index变为了原index的个位数。而此函数根据pref来选择底层驱动打开摄像头索引号,个位数是最终的摄像头索引号。
然后我们再看
enum
{
CV_CAP_ANY =0, // autodetect
CV_CAP_MIL =100, // MIL proprietary drivers
CV_CAP_VFW =200, // platform native
CV_CAP_V4L =200,
CV_CAP_V4L2 =200,
CV_CAP_FIREWARE =300, // IEEE 1394 drivers
CV_CAP_FIREWIRE =300,
CV_CAP_IEEE1394 =300,
CV_CAP_DC1394 =300,
CV_CAP_CMU1394 =300,
CV_CAP_STEREO =400, // TYZX proprietary drivers
CV_CAP_TYZX =400,
CV_TYZX_LEFT =400,
CV_TYZX_RIGHT =401,
CV_TYZX_COLOR =402,
CV_TYZX_Z =403,
CV_CAP_QT =500, // QuickTime
CV_CAP_UNICAP =600, // Unicap drivers
CV_CAP_DSHOW =700, // DirectShow (via videoInput)
CV_CAP_MSMF =1400, // Microsoft Media Foundation (via videoInput)
CV_CAP_PVAPI =800, // PvAPI, Prosilica GigE SDK
CV_CAP_OPENNI =900, // OpenNI (for Kinect)
CV_CAP_OPENNI_ASUS =910, // OpenNI (for Asus Xtion)
CV_CAP_ANDROID =1000, // Android - not used
CV_CAP_ANDROID_BACK =CV_CAP_ANDROID+99, // Android back camera - not used
CV_CAP_ANDROID_FRONT =CV_CAP_ANDROID+98, // Android front camera - not used
CV_CAP_XIAPI =1100, // XIMEA Camera API
CV_CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API)
CV_CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK
CV_CAP_INTELPERC = 1500, // Intel Perceptual Computing
CV_CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect)
CV_CAP_GPHOTO2 = 1700,
CV_CAP_GSTREAMER = 1800, // GStreamer
CV_CAP_FFMPEG = 1900, // FFMPEG
CV_CAP_IMAGES = 2000 // OpenCV Image Sequence (e.g. img_%02d.jpg)
};
CV_CAP_VFW,CV_CAP_V4L,CV_CAP_V4L2都是200。所以,看到下面部分,只有当输入的索引号为200~299时,opencv才会用V4L相关的驱动去打开摄像头。
而在LINUX平台上,USB摄像头的节点一般为/dev/video2。因此索引号一般为2。因此,最终输入OPENCV的索引号应当为202,OpenCV才能正确的打开USB的UVC摄像头。