video4linux(v4l)使用摄像头的实例基础教程与体会(转)
- #ifndef _V4L_H_
- #define _V4L_H_
- #include <sys/types.h>
- #include <linux/videodev.h> //使用v4l必须包含的头文件
- struct _v4l_struct
- {
- int fd;//保存打开视频文件的设备描述符
- struct video_capability capability;//设备的基本信息(设备名称、支持的分辨率等)
- struct video_picture picture;//采集图像的各种属性
- struct video_mmap mmap;
- struct video_mbuf mbuf;//利用mmap映射的帧的信息
- unsigned char *map;//用于指向图像数据的指针
- int frame_current;
- int frame_using[VIDEO_MAXFRAME];//这两个变量用于双缓冲在后面介绍。
- };
- typedef struct _v4l_struct v4l_device;
- extern int v4l_open(char *, v4l_device *);
- extern int v4l_close(v4l_device *);
- extern int v4l_get_capability(v4l_device *);
- extern int v4l_get_picture(v4l_device *);
- extern int v4l_get_mbuf(v4l_device *);
- extern int v4l_set_picture(v4l_device *, int, int, int, int, int,);
- extern int v4l_grab_picture(v4l_device *, unsigned int);
- extern int v4l_mmap_init(v4l_device *);
- extern int v4l_grab_init(v4l_device *, int, int);
- extern int v4l_grab_frame(v4l_device *, int);
- extern int v4l_grab_sync(v4l_device *);
- #define DEFAULT_DEVICE “/dev/video0”
- int v4l_open(char *dev , v4l_device *vd)
- {
- if(!dev)dev= DEFAULT_DEVICE;
- if((vd->fd=open(dev,O_RDWR))<0){perror(“v4l_open:”);return -1;}
- if(v4l_get_capability(vd))return -1;
- if(v4l_get_picture(vd))return -1;//这两个函数就是即将要完成的获取设备信息的函数
- return 0
- }
- int v4l_close(v4l_device *vd)
- {close(vd->fd);return 0;}
- int v4l_get_capability(v4l_device *vd)
- {
- if (ioctl(vd->fd, VIDIOCGCAP, &(vd->capability)) < 0) {
- perror("v4l_get_capability:");
- return -1;
- }
- return 0;
- }
- int v4l_get_picture(v4l_device *vd)
- {
- if (ioctl(vd->fd, VIDIOCGPICT, &(vd->picture)) < 0) {
- perror("v4l_get_picture:");
- return -1;
- }
- return 0;
- }
- struct video_capability
- {
- char name[32];
- int type;
- int channels; /* Num channels */
- int audios; /* Num audio devices */
- int maxwidth; /* Supported width */
- int maxheight; /* And height */
- int minwidth; /* Supported width */
- int minheight; /* And height */
- };//capability结构它包括了视频设备的名称,频道数,音频设备数,支持的最大最小宽度和高度等信息。
- struct video_picture
- {
- __u16 brightness;
- __u16 hue;
- __u16 colour;
- __u16 contrast;
- __u16 whiteness; /* Black and white only */
- __u16 depth; /* Capture depth */
- __u16 palette; /* Palette in use */
- };//picture结构包括了亮度,对比度,色深,调色板等等信息。头文件里还列出了palette相关的值,这里并没有给出。
- int v4l_get_mbuf(v4l_device *vd)
- {
- if (ioctl(vd->fd, VIDIOCGMBUF ,&(vd->mbuf)) < 0) {
- perror("v4l_get_mbuf:");
- return -1;
- }
- return 0;
- }
对于结构体video_mbuf在v4l中的定义如下,video_mbuf结构体是为了服务使用mmap内存映射来获取图像的方法而设置的结构体,通过这个结构体可以获得摄像头设备存储图像的内存大小。具体的定义如下,各变量的使用也会在下文详细说明。
- struct video_mbuf
- {
- int size; 可映射的摄像头内存大小
- int frames; 摄像头可同时存储的帧数
- int offsets[VIDEO_MAX_FRAME];每一帧图像的偏移量
- };
- int v4l_set_picture(v4l_device *vd,int br,int hue,int col,int cont,int white)
- {
- if(br) vd->picture.brightnesss=br;
- if(hue) vd->picture.hue=hue;
- if(col) vd->picture.color=col;
- if(cont) vd->picture.contrast=cont;
- if(white) vd->picture.whiteness=white;
- if(ioctl(vd->fd,VIDIOCSPICT,&(vd->picture))<0)
- {perror("v4l_set_picture: ");return -1;}
- return 0;
- }
- extern int v4l_grab_picture(v4l_device *, unsigned int);//函数就是完成这个工作的,它的实现也很简单。
- int v4l_grab_picture(v4l_device *vd, unsighed int size)
- {
- if(read(vd->fd,&(vd->map),size)==0)return -1;
- return 0;
- }
- extern int v4l_mmap_init(v4l_device *);//该函数把摄像头图像数据映射到进程内存中,也就是只要使用vd->map指针就可以使用采集到的图像数据(下文详细说明)
- extern int v4l_grab_init(v4l_device *, int, int);//该函数完成图像采集前的初始化工作。
- extern int v4l_grab_frame(v4l_device *, int);//该函数是真正完成图像采集的一步,在本文使用了一个通常都会使用的一个小技巧,可以在处理一帧数据时同时采集下一帧的数据,因为通常我们使用的摄像头都可以至少存储两帧的数据。
- extern int v4l_grab_sync(v4l_device *);//该函数用来完成截取图像的同步工作,在截取一帧图像后调用,返回表明一帧截取结束。
- void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )
- int v4l_mmap_init(v4l_device *vd)
- {
- if (v4l_get_mbuf(vd) < 0)
- return -1;
- if ((vd->map = mmap(0, vd->mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, vd->fd, 0)) < 0) {
- perror("v4l_mmap_init:mmap");
- return -1;
- }
- return 0;
- }
- int v4l_grab_init(v4l_device *vd, int width, int height)
- {
- vd->mmap.width = width;
- vd->mmap.height = height;
- vd->mmap.format = vd->picture.palette;
- vd->frame_current = 0;
- vd->frame_using[0] = FALSE;
- vd->frame_using[1] = FALSE;
- return v4l_grab_frame(vd, 0);
- }
- <span style="color:#330033;">int v4l_grab_frame(v4l_device *vd, int frame)
- {
- if (vd->frame_using[frame]) {
- fprintf(stderr, "v4l_grab_frame: frame %d is already used.\n", frame);
- return -1;
- }
- vd->mmap.frame = frame;
- if (ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) < 0) {
- perror("v4l_grab_frame");
- return -1;
- }
- vd->frame_using[frame] = TRUE;
- vd->frame_current = frame;
- return 0;
- } </span>
- int v4l_grab_sync(v4l_device *vd)
- {
- if (ioctl(vd->fd, VIDIOCSYNC, &(vd->frame_current)) < 0) {
- perror("v4l_grab_sync");
- }
- vd->frame_using[vd->frame_current] = FALSE;
- return 0;
- }
- //test.c
- include “v4l.h”
- ...
- v4l_device vd;
- void main()
- {
- v4l_open(DEFAULT_DEVICE,&vd);
- v4l_mmap_init(&vd);
- v4l_grab_init(&vd,320,240);
- v4l_grab_sync(&vd);//此时就已经获得了一帧的图像,存在vd.map中
- while(1)
- {
- vd.frame_current ^= 1;
- v4l_grab_frame(&vd, vd.frame_current);
- v4l_grab_sync(&vd);
- 图像处理函数(vd.map+vd. vd.map+vd.mbuf.offsets[vd.frame_current]);
- //循环采集,调用你设计的图像处理函数来处理图像
- //其中vd.map+vd. vd.map+vd.mbuf.offsets[vd.frame_current]就是图像所在位置。
- }
- }
video4linux(v4l)使用摄像头的实例基础教程与体会(转)的更多相关文章
- React实例入门教程(1)基础API,JSX语法--hello world
前 言 毫无疑问,react是目前最最热门的框架(没有之一),了解并学习使用React,可以说是现在每个前端工程师都需要的. 在前端领域,一个框架为何会如此之火爆,无外乎两个原因:性能优秀,开发 ...
- 【原创】React实例入门教程(1)基础API,JSX语法--hello world
前 言 毫无疑问,react是目前最最热门的框架(没有之一),了解并学习使用React,可以说是现在每个前端工程师都需要的. 在前端领域,一个框架为何会如此之火爆,无外乎两个原因:性能优秀,开发效率 ...
- Python 基础教程 —— Pandas 库常用方法实例说明
目录 1. 常用方法 pandas.Series 2. pandas.DataFrame ([data],[index]) 根据行建立数据 3. pandas.DataFrame ({dic}) ...
- WCF基础教程之异常处理:你的Try..Catch语句真的能捕获到异常吗?
在上一篇WCF基础教程之开篇:创建.测试和调用WCF博客中,我们简单的介绍了如何创建一个WCF服务并调用这个服务.其实,上一篇博客主要是为了今天这篇博客做铺垫,考虑到网上大多数WCF教程都是从基础讲起 ...
- objective-c基础教程——学习小结
objective-c基础教程——学习小结 提纲: 简介 与C语言相比要注意的地方 objective-c高级特性 开发工具介绍(cocoa 工具包的功能,框架,源文件组织:XCode使用介绍) ...
- jQuery官方基础教程笔记(转载)
本文转载于阮一峰的博文,内容基础,结构清晰,是jquery入门不可多得的资料,非常好,赞一个. 阮一峰:jQuery官方基础教程笔记 jQuery是目前使用最广泛的javascript函数库. 据统计 ...
- Android程序开发0基础教程(一)
程序猿学英语就上视觉英语网 Android程序开发0基础教程(一) 平台简单介绍 令人激动的Google手机操作系统平台-Android在2007年11月13日正式公布了,这是一个开放源码的操 ...
- (转)Windows驱动编程基础教程
版权声明 本书是免费电子书. 作者保留一切权利.但在保证本书完整性(包括版权声明.前言.正文内容.后记.以及作者的信息),并不增删.改变其中任何文字内容的前提下,欢迎任何读者 以任何形式(包括 ...
- HTML入门基础教程相关知识
HTML入门基础教程 html是什么,什么是html通俗解答: html是hypertext markup language的缩写,即超文本标记语言.html是用于创建可从一个平台移植到另一平台的超文 ...
随机推荐
- Android面试三之Service
Service是什么 Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件.其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行.另 ...
- Hadoop出现 Wrong FS: hdfs://......错误的解决方法
今天在hadoop项目中出现以下报错:java.lang.IllegalArgumentException: Wrong FS: hdfs://......,expected: file:///... ...
- Day14 js高级部分
JS中文学习文档 http://jquery.cuishifeng.cn/ 一.函数变量的作用域: 变量的作用域是在声明时决定的而不是调用执行时决定 作用域链: 二.词法分析: 函数执行前,会进行预编 ...
- Django开发BUG "Model class WH_auth.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS."
当进行数据库迁移的时候发生问题,报错如下:RuntimeError: Model class WH_auth.models.User doesn't declare an explicit app_l ...
- progressbar进度条组件
Progressbar 进度条组件 通过$.fn.progressbar.fn.defaults重写默认的defaults进度条(progressbar)提供了一种显示长时间操作进度的反馈.进度可被更 ...
- cursor游标(mysql)
/* 游标 cursor 什么是游标?为什么需要游标 使用存储过程对sql进行编程的时候,我们查询的语句可能是数据是多个,它总是一口气全部执行,我们无法针对每一条进行判断.也就是说,我们无法控制程序的 ...
- Corosync+pacemaker实现集群的高可用
一.Corosync和pacemaker的了解: Corosync是集群管理套件的一部分,他在传递信息的时候可以通过一个简单的配置文件来定义信息传递的方式和协议等.也就是说,corosync是Mess ...
- IIS站点/虚拟目录中访问共享目录(UNC)以及建立后的应用程序的信任级别问题
UNC是 Universal Naming Convention 的简称,也叫通用命名规范.通用命名约定.网络(范指局域网)上资源的完整位置名称.格式为 \\servername\sharenam ...
- css 中相对定位和绝对定位
1. css中定位机制有三种: 标准文档流, 浮动, 绝对定位 2. 绝对定位就属于第三种定位, 用到position属性, 下面就是具体设置 相对定位: 相对于自身原有位置(就是普通流的时候)进行偏 ...
- emacs编辑器的使用
尽管有许多ide,但是,各种软件使用各种不同,设置等,受不了.觉得应该有一手好的编辑器就可以了.尤其是受不了ide什么lib,.h,exe,dll等路径设置,让人心烦.再加上黑盒子的感觉很不爽.一旦出 ...