I have always been using OpenCV’s VideoCapture API to capture images from webcam or USB cameras. OpenCV supports V4L2 and I wanted to use something other than OpenCV’s VideoCapture API so I started digging up about v4l2 and got few links using and few examples using which I successfully wrote a small code to grab an image using V4L2 and convert it to OpenCV’s Mat structure and display the image.

What is V4L2?

V4L2 is the second version of Video For Linux which is a video capturing API for Linux. Hereyou can find amazing documentation about the API. So it gives you a very easy inteface to use it with C, C++ and Python. I haven’t tried Python bindings yet.

How To Use V4L2 API?

I started reading documentation but didn’t really understand much until I found this example. The code had some issues and wasn’t working properly. But I just copied it and tried understanding it. So this is my understanding of the code.

Step 1: Open the Capture Device.

In Linux, default capture devide is generally /dev/video0, but if you’re using USB webcams, the index will vary accordingly.

int fd;
fd = open("/dev/video0", O_RDWR);
if (fd == -1)
{
// couldn't find capture device
perror("Opening Video device");
return 1;
}

Step 2: Query the Capture

So, basically you check if the capture is available or not. V4L2 doesn’t support some cameras so it would throw an error here. We need to use v4l2_capability structure and VIDIOC_QUERYCAPto query the capture. Read More here.

struct v4l2_capability caps = {0};
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &caps))
{
perror("Querying Capabilites");
return 1;
}

Here xioctl is a wrapper function over ioctlioctl() is a function to manipulate device parameters of special files. Read more here.

#include <sys/ioctl.h>

static int xioctl(int fd, int request, void *arg)
{
int r;
do r = ioctl (fd, request, arg);
while (-1 == r && EINTR == errno);
return r;
}


Step 3: Image Format

V4L2 provides an easy interface to check the image formats and colorspace that your webcam supports and provide. v4l2_format sturcture is to be used to change image format.

struct v4l2_format fmt = {0};
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 320;
fmt.fmt.pix.height = 240;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
fmt.fmt.pix.field = V4L2_FIELD_NONE; if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
{
perror("Setting Pixel Format");
return 1;
}

I have set image width and height to be 320 and 240 respectively. You should check out the format that your camera supports. My Camera supports MJPEG and YUV and hence I have set image format to MJPEG.

Step 4: Request Buffers

A buffer contains data exchanged by application and driver using Streaming I/O methods. v4l2_requestbuffers is used to allocate device buffers. Read more here.

struct v4l2_requestbuffers req = {0};
req.count = 1;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
{
perror("Requesting Buffer");
return 1;
}

The ioctl is used to initialize memory mapped(mmap), user pointer based I/O.

Step 5: Query Buffer

After requesting buffer from the device, we need to query the buffer in order to get raw data. Read more here

struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = bufferindex;
if(-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
{
perror("Querying Buffer");
return 1;
} buffer = mmap (NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);

The mmap() function asks to map length bytes starting at offset in the memory of the device specified by fd into the application address space, preferably at address start. Read more here

Step 6: Capture Image

After querying the buffer, the only thing left is capturing the frame and saving it in the buffer.

if(-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type))
{
perror("Start Capture");
return 1;
} fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = {0};
tv.tv_sec = 2;
int r = select(fd+1, &fds, NULL, NULL, &tv);
if(-1 == r)
{
perror("Waiting for Frame");
return 1;
} if(-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
{
perror("Retrieving Frame");
return 1;
}

Step 7: Store data in OpenCV datatype

I wanted to stored the retrieved data in OpenCV image structure. It took me few hours to figure out the perfect way. So here’s how I did it.

CvMat cvmat = cvMat(480, 640, CV_8UC3, (void*)buffer);
IplImage * img;
img = cvDecodeImage(&cvmat, 1);

So this how I captured frames from my webcam and stored in OpenCV Image data structure.

You can find the complete code here on my GitHub

P.S. Coding period for gsoc has started and I have to start working.

Open images from USB camera on linux using V4L2 with OpenCV的更多相关文章

  1. Jetson TX1使用usb camera采集图像 (2)

    该方法只启动usb摄像头 import cv2 import numpy import matplotlib.pyplot as plot class Camera: cap = cv2.VideoC ...

  2. android4.0 USB Camera实例(三)UVC

    前面我写了两篇文章说明了zc301的实现 详细请看 http://blog.csdn.net/hclydao/article/details/21235919 以下顺便把通用的USB也写上 前面的ZC ...

  3. Android USB Camera(1) : 调试记录【转】

    转自:http://blog.csdn.net/eternity9255/article/details/53069037 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 前言 ...

  4. I.MX6 USB Camera

    /************************************************************************* * I.MX6 USB Camera * 说明: ...

  5. Android开发之《USB Camera》

    SimpleWebCam Source Code:https://bitbucket.org/neuralassembly/simplewebcam/src 1. USB摄像头UVC兼容(如今大部分兼 ...

  6. ROS_Kinetic_12 ROS程序基础Eclipse_C++(三)usb camera

    ROS_Kinetic_12 ROS程序基础Eclipse_C++(三)usb camera 软件包下载地址:https://github.com/bosch-ros-pkg/usb_cam 下载后, ...

  7. Power OFF and ON USB device in linux (ubuntu)

    Power OFF and ON USB device in linux (ubuntu) http://loginroot.com/power-off-and-on-usb-device-in-li ...

  8. Ffmpeg 获取USB Camera 视频流

    本文讲述的案例是如何通过Ffmpeg实现从USB Camera中获取视频流并将视频流保存到MP4文件. 本文亦适用于从USB Camera 获取视频流并将视频流转发到rtmp服务的案例,二者基本的原理 ...

  9. android4.0 USB Camera示例(四)CMOS

    上一页下一页说usb camera uvc标准 顺便说说CMOS一起做 操作基本一至, 前HAL在那里我已经提供了层CMOS相关接口 JNIEXPORT jint JNICALL Java_com_d ...

随机推荐

  1. Android Fragment原理及应用

    1.Fragment简介 Fragment(片段) 表示 Activity 中的行为或用户界面部分.您可以将多个片段组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中 ...

  2. HDU - 5306 剪枝的线段树

    题意:给定\(a[1...n]\),\(m\)次操作,0表示使\([L,R]\)中的值\(a[i]=min(a[i],x)\),其余的1是查最值2是查区间和 本题是吉利爷的2016论文题,1 2套路不 ...

  3. css提取数据2个常用方法

    提取标签里的内容 所谓数据就是HTML里标签的内容,如下面红色字体,就是标签内容 <title>我只是个实验 - SCRAPY</title> 提取标签里的数据,标签可以是ti ...

  4. [Java基础]-- Java GC 垃圾回收器的分类和优缺点

    https://blog.csdn.net/high2011/article/details/80177473?utm_source=blogxgwz2 参考:elasticsearch实战-使用G1 ...

  5. 【python】Scrapy爬虫框架入门

    说明: 本文主要学习Scrapy框架入门,介绍如何使用Scrapy框架爬取页面信息. 项目案例:爬取腾讯招聘页面 https://hr.tencent.com/position.php?&st ...

  6. unity动态加载FBX模型(Http下载到Rescources文件,场景Load直接调用):

    using UnityEngine; using System.Collections; using System.IO; using System.Net; using System; using ...

  7. DB2 锁问题的监控和解决

    常见的锁问题包括: 锁等待 锁超时 锁升级 死锁 而根据问题的特性通常分为两种: 实时事件:问题正在发生 历史事件:问题已经过去 如果实时事件,DBA 可以通过查看表信息.GET SNAPSHOT 或 ...

  8. Linux下ffmpeg添加Facebook/transform代码块实现将全景视频的球模型转换成立方体模型

    Facebook事实上已开始在平台中支持360度全景视频的流播,但公司对此并不满足.其工程师更是基于锥体几何学设计出了一套全新的视频编码,号称最高能将全景视频的文件大小减少80%.(VR最新突破:全景 ...

  9. Java ConcurrentModificationException异常原因和解决方法(转)

    摘自:http://www.cnblogs.com/dolphin0520/p/3933551.html#undefined 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同 ...

  10. 架构实战项目心得(十四):spring-boot结合Swagger2构建RESTful API测试体系

    一.添加依赖: <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-s ...