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是用于创建可从一个平台移植到另一平台的超文 ...
随机推荐
- 对一致性Hash算法,Java代码实现的深入研究(转)
转载:http://www.cnblogs.com/xrq730/p/5186728.html 一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读 ...
- 【zznu-夏季队内积分赛3-I】逛超市
题目描述 “别人总说我瓜,其实我一点也不瓜,大多数时候我都机智的一批“我宝儿姐背包学的太差了,你们谁能帮我解决这道题,我就让他做我的男朋友!宝儿姐现在在逛超市,超市里的种类实在是太多了,每种都有很多很 ...
- nodejs编译sass模块包 node-compass,与gulp包gulp-sass使用方法
简介:node express或者就是node项目中,要自动编译sass方法很多,比如gulp 比如考拉,比如今天我想说的这个包node-compass. 编译sass的三种方法: 前提条件: 都需要 ...
- Linux crontab使用及注意事项
渗透测试中,经常会用到crontab来执行计划任务,从而实现后门程序的隐藏,但crontab有几个坑点还是需要记录一下,方便日后使用时及时查询 1.crontab配置格式 # Example of j ...
- Guid.NewGuid() 和 new Guid()的区别
Guid.NewGuid().ToString() + "||" + (new Guid()).ToString() b8efacbb-7d43-4da5-9f48-9a75d8c ...
- Composer介绍
Composer介绍 简单的说Composer就是一个PHP的组件包的依赖管理器.早年间PHP其实是有自己的包管理器的,叫PEAR.PEAR就介绍到这里,你只要知道这是一个狗屎一般的管理器就行了.在N ...
- jsp中把js变量赋给java变量,或者将java变量赋给js变量怎么做?
在jsp中经常会遇到把js变量赋给java变量,或者将java变量赋给js变量的情况,在此将通用的处理方法小结如下: java变量传给js好办,var a=”<%=javaParam%>“ ...
- 十图详解TensorFlow数据读取机制(附代码)
在学习TensorFlow的过程中,有很多小伙伴反映读取数据这一块很难理解.确实这一块官方的教程比较简略,网上也找不到什么合适的学习材料.今天这篇文章就以图片的形式,用最简单的语言,为大家详细解释一下 ...
- 一名十年Java程序员回忆阿里面试经历——揭开阿里面试的“遮羞布”
阿里面试经历 去阿里面试可以说非常非常的偶然和戏剧性,因为本人根本没投简历,以至于阿里hr给我电话的时候我一度认为是诈骗电话.因为深圳这家公司不错我还想在这里干个两年左右再考虑考虑. 这个时候的本人已 ...
- Compass入门
一.Compass是什么? 简单说,Compass是Sass的工具库(toolkit). Sass本身只是一个编译器,Compass在它的基础上,封装了一系列有用的模块和模板,补充Sass的功能. ...