一个比较详细的Linux摄像头图像采集讲解.doc_第1页
一个比较详细的Linux摄像头图像采集讲解.doc_第2页
一个比较详细的Linux摄像头图像采集讲解.doc_第3页
一个比较详细的Linux摄像头图像采集讲解.doc_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

这一部分将会介绍如何在linux中对电视卡编程。开始已经提到过,电视卡使用的是video for linux驱动,简称v4l,实际上,现在已经有了video for linux two驱动 ,即v4l2.它解决了v4l中存在的一些问题,并且提高了硬件性能。但是,目前来说,v4l2仍然没有集成到linux的内核中,要使用v4l2的话,只有去下载v4l2补丁了,以下如无特别说明,所涉及的内容只针对v4l设备而言。 我们都知道,在linux中,为了屏蔽用户对设备访问的复杂性,采用了设备文件,即可以通过像访问普通文件一样的方式来对设备进行访问读写。电视卡在linux中和打印机,鼠标一样,属于字符设备。其主设备号是81,在实际操作上,访问控制电视卡也和一般的设备文件没有什么不同。用open打开设备, int fd; fd = open(/dev/video0,O_RDWR);用一系列的ioctl发命令控制设备。v4l支持的ioctl命令大概有二十几个,为了尽快的编出一个简单的图象捕捉程序,让我们先来看看几个主要的命令:1. ioctl(fd,VIDIOCGCAP,&cap); 该命令主要是为了获取电视卡的功能信息。例如电视卡的名称,类型,channel等。参数cap是一个结构,当ioctl命令返回时,结构的各成员就被赋值了,结构体的定义为:struct video_capability char name32; 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 */;channel 指的是有几个信号输入源,例如television,composite,s-video等。2.ioctl(fd,VIDIOCGCHAN,&vc)3.ioctl(fd,VIDIOCSCHAN.&vc)这两个命令用来取得和设置电视卡的channel信息,例如使用那个输入源,制式等。vc 是一个video_channel结构,其定义为:struct video_capability char name32; 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 */;struct video_channel int channel; char name32; int tuners;/number of tuners for this input _u32 flags; _u16 type; _u16 norm; ;成员channel代表输入源,通常,0: television 1:composite1 2:s-videoname 表示该输入源的名称。norm 表示制式,通常,0:pal 1:ntsc 2:secam 3:auto4. ioctl(fd,VIDIOCGMBUF,*mbuf)获得电视卡缓存的信息,参数mbuf是video_mbuf结构。其定义如下:struct video_mbuf int size; /* Total memory to map */ int frames; /* Frames */ int offsetsVIDEO_MAX_FRAME;size是缓存的大小,frames表明该电视卡的缓存可以容纳的帧数,数组offsets则表明对应一帧的起始位置,0帧对应offsets0,1帧对应offsets1.执行完该命令后,就可以用mmap函数将缓存映射到内存中了。大致用法可以参考以下的代码struct video_mbuf mbuf;unsigned char *buf1,*buf2;if(ioctl(fd,VIDIOCGMBUF,&mbuf)0) perror(VIDIOCGMBUF); return -1;printf(the frame number is %dn,mbuf.frames);buf1 = (unsigned char*)mmap(0,mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd.0);buf1 = buf1 + mbuf.offset0;buf2 = buf1 + mbuf.offset1;/当然,如果mbuf.frames=1,就不需要下面的了。.5. ioctl(fd.VIDIOCMCAPTURE,&mm) 启动硬件去捕捉图象,mm 是video_mmap 结构,设置捕捉图象需要设置的信息。结构体如下定义:struct video_mmap unsigned int frame; /* Frame (0 - n) for double buffer */ int height,width; unsigned int format; /* should be VIDEO_PALETTE_* */;frame :设置当前是第几帧height,width:设置图象的高和宽。format :颜色模式要注意的是,该命令是非阻塞的,也就是说,它仅仅设置了硬件,而不负责是否捕捉到图象。要确定是否捕捉到图象,要用到下一个命令。6. ioctl(fd,VIDIOCSYNC,&frame)等待捕捉到这一帧图象。frame 是要等待的图象,它的值应和上一个命令中设置的frame相对应。好了,说了这么多,读者大概也对视频捕捉有了一个了解,是不是想亲自动手试一下,那就让我们开始实际程序的编写吧。下面我们会编一个程序,将捕捉到的图象存为jpeg文件。为此,还要向大家介绍一个函数,int write_jpeg(char *filename,unsigned char *buf,int quality,int width, int height, int gray) struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE *fp; int i; unsigned char *line; int line_length; if (NULL = (fp = fopen(filename,w) fprintf(stderr,grab: cant open %s: %sn,filename,strerror(errno); return -1; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, fp); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = gray ? 1: 3; cinfo.in_color_space = gray ? JCS_GRAYSCALE: JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); jpeg_start_compress(&cinfo, TRUE); line_length = gray ? width : width * 3; for (i = 0, line = buf; i height; i+, line += line_length) jpeg_write_scanlines(&cinfo, &line, 1); jpeg_finish_compress(&(cinfo); jpeg_destroy_compress(&(cinfo); fclose(fp); return 0;这个函数很通用,它的作用是把buf中的数据压缩成jpeg格式。/* 下面是一个完整的程序 test.c* gcc test.c -o test -ljpeg*/#include #include #include #include #include #include #include #include #include #include #define WIDTH 320#define HEIGHT 240#define V4L_DEVICE /dev/video0main() unsigned char* buf; int i,j; int fd; int re; struct video_capability vcap; struct video_channel vc; struct video_mbuf mbuf; struct video_mmap mm; fd = open(V4L_DEVICE, O_RDWR); if(fd=0) perror(open); exit(1); if(ioctl(fd, VIDIOCGCAP, &vcap)0) perror(VIDIOCGCAP); exit(1); fprintf(stderr,Video Capture Device Name : %sn,); for(i=0;ivcap.channels;i+) vc.channel = i; if(ioctl(fd, VIDIOCGCHAN, &vc)0) perror(VIDIOCGCHAN); exit(1); fprintf(stderr,Video Source (%d) Name : %sn,i, ); vc.channel =1; vc.norm=1; if(ioctl(fd, VIDIOCSCHAN, &vc) 0) perror(VIDIOCSCHAN); exit(1); if(ioctl(fd, VIDIOCGMBUF, &mbuf) 0) perror(VIDIOCGMBUF); exit(1); fprintf(stderr,the frames number is %dn,mbuf.frames); buf = (unsigned char*)mmap(0, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if(int)buf 0) perror(mmap); exit(1); mm.frame = 0; mm.height = HEIGHT; mm.width = WIDTH; mm.format = VIDEO_PALETTE_RGB24; if(ioctl(fd, VIDI

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论