在OpenCV中使用视频

目前Computer Vision领域最前沿的技术都集中在视频分析上。理所当然得,OpenCV也支持USB摄像头作为一个重要的输入类别。此前,OpenCV 1.1的API就提供了cvCaptureFromCAM函数从摄像头取得数据。OpenCV 2.0开始视频输入被包装成了VideoCapture这个类。而且,使用上也更加简便。虽然看上去在OpenCV中使用从摄像头作为输入并不困难,但是因为缺乏广泛的厂商支持,这件事情在Linux操作系统上却常常让人担心。这篇文章的主旨还是将我目前的配置记录下来,以便应付我那不怎么可靠的记忆力。

硬件

虽然Linux的世界Microsoft永远不会懂,但是Linux的开发者却一直在试图弄懂Microsoft的硬件,而且结果相当不错。Microsoft的硬件LifeCam几乎可以在Debian Jessie上面完美运行!这是我使用的LifeCam Cimema(官网盗图):

Microsoft LifeCam Cinema

v4l2驱动

V4L是Linux内核为各种视频输入设备提供的驱动框架。为了使用USB接口的视频设备,在系统中还需要其他内核模块支持这些硬件。以下是必要的内核模块列表:

$ lsmod | grep v4l
v4l2_common            12995  1 videobuf2_core
videodev              126451  4 uvcvideo,v4l2_common,videobuf2_core
i2c_core               46012  5 drm,i2c_i801,nvidia,v4l2_common,videodev

除此以外,用户空间还需要像gstreamer这样的视频处理框架来支持视频的编解码和显示。如果一一安装这些软件组件,那将会是一个非常痛苦的过程。所以,为了方便起见,直接安装处于这个软件栈的最顶端的应用程序将会达到事半功倍的效果。安装下面的程序:

$ sudo apt-get install v4l2ucp guvcview

安装结束后,分层确认安装结果。使用v4l2ctrl确认视频设备的配置。

$ v4l2ctrl -s /tmp/result

这个程序会探测系统中的/dev/video0并且将其配置保存到/tmp/result。在我的LifeCam上的确认结果如下:

9963776:                     Brightness:133
9963777:                       Contrast:5
9963778:                     Saturation:83
9963788:White Balance Temperature, Auto:1
9963800:           Power Line Frequency:2
9963802:      White Balance Temperature:4500
9963803:                      Sharpness:25
9963804:         Backlight Compensation:0
10094849:                 Exposure, Auto:3
10094850:            Exposure (Absolute):156
10094856:                 Pan (Absolute):0
10094857:                Tilt (Absolute):0
10094858:               Focus (absolute):4
10094860:                    Focus, Auto:1
10094861:                 Zoom, Absolute:0

然后,使用guvcview这个应用程序来测试视频录像。

guvcview_video_capture

使用OpenCV抓取视频

#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char** argv)
{
  VideoCapture cap(0); // open the default camera
  if (!cap.isOpened()) // check if we succeeded
    return -1;

  Mat edges;
  namedWindow("Edges", 1);

  for (;;) {
    Mat frame;
    cap >> frame; // get a new frame from camera
    cvtColor(frame, edges, CV_BGR2GRAY);
    GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
    Canny(edges, edges, 0, 30, 3);
    imshow("Edges", edges);
    if (waitKey(30) >= 0) break;
  }

  // the camera will be deinitialized automatically in VideoCapture
  // destructor
  return 0;
}

这段程序可以从摄像头抓取视频,并且对视频中的帧进行边缘探测。主循环使用了Canny边缘探测法。下面是运行时的截图。

OpenCv_VideoCapture_Example

发表评论