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.

来源: https://jayrambhia.com/blog/capture-v4l2
来自为知笔记(Wiz)

转载于:https://www.cnblogs.com/jins-note/p/9534577.html

Open images from USB camera on linux using V4L2 with OpenCV相关推荐

  1. Hi3518EV300芯片linux系统配置USB Camera功能

    Hi3518EV300芯片linux系统配置USB Camera功能 一,安装好虚拟机VMware® Workstation 15 Pro 和Ubuntu16.04 64位版本:并且安装应用软件,配置 ...

  2. Android USB Camera(1) : 调试记录

    1. 前言 前段时间调试了一个uvc摄像头,这里做下记录.硬件平台为mt6735,软件平台为android 5.0 2. 底层配置 UVC全称是usb video class,一种usb视频规范.所有 ...

  3. Android USB Camera

    Android 设备基于 linux kernel, 自带 V4L2 支持.针对USB camera, 可选择的实现方案有下面几种(当然了,目前最优解是No.3 ): 1. 基于 libuvc 开发 ...

  4. 海康Camera MVS Linux SDK二次开发封装ROS packge过程记录(c++)

    Livox Lidar  + HIKROBOT Camera系列 最近在开发相机和激光雷达融合的slam算法,主要用于三维重建,想实时的得到彩色点云地图,传感器选择了海康威视的工业相机和大疆的固态激光 ...

  5. Android 利用V4L2 预览MJPEG格式 USB camera

    介绍 上一篇文章Android 利用V4L2 调用camera介绍了使用V4L2 接口预览camera的基本方法.目前接触过的usb camera支持的图像格式基本上只包括3种: YUV MJPEG ...

  6. USB Camera在android车机上应用前景及初试小结

    USB Camera在android车机上应用前景及初试小结   USB Camera在我们的生活中已经有一些年头了,USB接口的普通摄像头由于使用方便,价格低廉,性能较好,应用在了工作生活的各个方面 ...

  7. Kali Linux 安全渗透教程第六更1.4.2 安装至USB驱动器Kali Linux

    1.4.2  安装至USB驱动器Kali Linux 安全渗透教程<第六更> Kali Linux USB驱动器提供了一种能力,它能永久的保存系统设置.永久更新.在USB设备上安装软件包, ...

  8. linux查看usb设备文件,linux – 确定USB设备文件路径

    So which device file is used for USB? How can i indentify it? 您在/ sys /后面看到的主要是有关设备的配置/信息. / dev / b ...

  9. android usb多个,android、windows上多个USB Camera同时使用实验小结

    android.windows上多个USB Camera同时使用实验小结 (2013-05-18 19:19:46) 标签: 小结 实验 使用 杂谈 android.windows上多个USB Cam ...

最新文章

  1. 你能活多少岁,就让人工智能来告诉你吧
  2. 7 MyBatis映射文件中的拼接符
  3. 3.《SQLSERVER2012之T-SQL教程》T-SQL单表查询(三)
  4. memcached全面剖析–2.理解 memcached的内存存储
  5. C++ Lambda表达式demo
  6. static用法报错解决:cannot declare member function to have static linkage [-fpermissive]
  7. 安装QTP10.0 报需要先安装 c++组件
  8. paip.文件搜索工具总结V2012.8.18
  9. 网页鼠标动态线条html5,网站动态背景线条跟随鼠标移动,吸附鼠标效果代码
  10. 毫米波雷达系统构成、测量原理(测距、测速、角速度)
  11. android开发倒计时新年快乐,JavaScript实现新年倒计时效果
  12. 数据库的备份与恢复技术
  13. 深圳vpay钱包系统技术开发分享
  14. nvidia卸载程序失败_卸载删除NVIDIA驱动程序的方法步骤教程 - 系统家园
  15. 挂靠其入职公司股东名下其他公司,是否有违反竞业协议?
  16. Shell 通过sed替换文件字符串
  17. 2021-2027全球与中国陶瓷基板市场现状及未来发展趋势
  18. 参考文献中英文人名_英文人名的缩写和参考文献写法
  19. Linux-vim编辑器
  20. 数独(DFS优化练习)

热门文章

  1. 理解Python中的类对象、实例对象、属性、方法
  2. Css3系列-新属性新布局
  3. 黑盒之嵌入式操作系统鲁棒性研究
  4. c 语言练习__去掉多余的空白字符_修正
  5. Linux用户管理与权限
  6. ORACLE 使用函数返回表数据
  7. Chrome MessageLoop类分析
  8. C++和Java中成员数据名和成员函数名的冲突问题
  9. Django:序列化的几种方法
  10. Python说文解字_杂谈06