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是用于创建可从一个平台移植到另一平台的超文 ...
随机推荐
- Java多态性的理解2
多态的基础理解请参考:http://www.cnblogs.com/liujinhong/p/6003144.html Java的多态一直是我们理解的一个难点.在读过<深入理解Java虚拟机&g ...
- python - pandas或者sklearn中如何将字符形式的标签数字化
参考:http://www.php.cn/wenda/91257.html https://www.cnblogs.com/king-lps/p/7846414.html http://blog.cs ...
- HDU 4828 逆元+catalan数
Grids Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Subm ...
- pdflush进程介绍与优化【转】
转载地址: http://blog.ops88.com/2012/07/12/74 一. /proc/sys/vm/dirty_background_ratio 该参数是在尝试一个write ba ...
- EasyUI validType属性
/** * 包含easyui的扩展和常用的方法 * * @author * * @version 20120806 */ var wjc = $.extend({}, wjc);/* 定义全局对象,类 ...
- BZOJ 1010 [HNOI2008]玩具装箱 (斜率优化DP)
题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 思路 [斜率优化DP] 我们知道,有些DP方程可以转化成DP[i]=f[j]+x[i ...
- 上下行分流下行负载方式和能ping通但不能打开
1 下行线路负载方式选择 目的端口+协议 否则有可能出现微信443端口图片打不开的情况. 2.彭ping通但是打不开的情况下将上行线路mtu值改小 由1500改为1450
- ubuntu 14.04安装c++遇到的问题
这是我在安装c++编译器时遇到的一些问题和解决办法,总结一下希望以后的人能少走弯路 安装g++编译器:sudo apt-get install build-essential build-essent ...
- Node.js 全栈开发(一)——Web 开发技术演化
这些年一直不断接触学习 Node 技术栈,个人的技术开发学习兴趣也越来越倾向 node 流.也许是由于英语的关系,也许是因为墙增加了学习国外一手资料的难度,加上现在流行的 web 开发技术并不太容易上 ...
- Python基础学习----字典常用操作
字典的常见操作: # 字典: # 格式:{键值对,键值对} dict_demo={"name":"bai-boy","age":17} # ...