V4L2通过摄像头采集图片 (转载)

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4.   
  5.   
  6. #include <assert.h>   
  7. #include <getopt.h>              
  8. #include <fcntl.h>               
  9. #include <unistd.h>   
  10. #include <errno.h>   
  11. #include <malloc.h>   
  12. #include <sys/stat.h>   
  13. #include <sys/types.h>   
  14. #include <sys/time.h>   
  15. #include <sys/mman.h>   
  16. #include <sys/ioctl.h>   
  17.   
  18.   
  19.   
  20.   
  21. #include <asm/types.h>           
  22. #include <linux/videodev2.h>   
  23.   
  24.   
  25. #define CAMERA_DEVICE "/dev/video0"   
  26.   
  27.   
  28. #define CAPTURE_FILE "frame_yuyv_new.jpg"   
  29. #define CAPTURE_RGB_FILE "frame_rgb_new.bmp"   
  30. #define CAPTURE_show_FILE "a.bmp"   
  31.   
  32.   
  33. #define VIDEO_WIDTH 640   
  34. #define VIDEO_HEIGHT 480   
  35. #define VIDEO_FORMAT V4L2_PIX_FMT_YUYV   
  36. #define BUFFER_COUNT 4   
  37.   
  38.   
  39. typedef struct VideoBuffer {  
  40.     void   *start; //视频缓冲区的起始地址  
  41.     size_t  length;//缓冲区的长度  
  42. } VideoBuffer;  
  43.   
  44.   
  45. /*  
  46. void *calloc(unsigned n,unsigned size) 功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。跟malloc的区别:calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据  
  47. */  
  48. //位图文件头数据结构含有位图文件的类型,大小和打印格式等信息  
  49. //进行数据字节的对齐  
  50. #pragma pack(1)   
  51. typedef struct BITMAPFILEHEADER  
  52. {  
  53.   unsigned short bfType;//位图文件的类型,  
  54.   unsigned long bfSize;//位图文件的大小,以字节为单位  
  55.   unsigned short bfReserved1;//位图文件保留字,必须为0  
  56.   unsigned short bfReserved2;//同上  
  57.   unsigned long bfOffBits;//位图阵列的起始位置,以相对于位图文件   或者说是头的偏移量表示,以字节为单位  
  58. } BITMAPFILEHEADER;  
  59. #pragma pack()   
  60.   
  61.   
  62. typedef struct BITMAPINFOHEADER//位图信息头类型的数据结构,用于说明位图的尺寸  
  63. {  
  64.   unsigned long biSize;//位图信息头的长度,以字节为单位  
  65.   unsigned long biWidth;//位图的宽度,以像素为单位  
  66.   unsigned long biHeight;//位图的高度,以像素为单位  
  67.   unsigned short biPlanes;//目标设备的级别,必须为1  
  68.   unsigned short biBitCount;//每个像素所需的位数,必须是1(单色),4(16色),8(256色)或24(2^24色)之一  
  69.   unsigned long biCompression;//位图的压缩类型,必须是0-不压缩,1-BI_RLE8压缩类型或2-BI_RLE4压缩类型之一  
  70.   unsigned long biSizeImage;//位图大小,以字节为单位  
  71.   unsigned long biXPelsPerMeter;//位图目标设备水平分辨率,以每米像素数为单位  
  72.   unsigned long biYPelsPerMeter;//位图目标设备垂直分辨率,以每米像素数为单位  
  73.   unsigned long biClrUsed;//位图实际使用的颜色表中的颜色变址数  
  74.   unsigned long biClrImportant;//位图显示过程中被认为重要颜色的变址数  
  75. } BITMAPINFOHEADER;  
  76.   
  77.   
  78.   
  79.   
  80. VideoBuffer framebuf[BUFFER_COUNT];   //修改了错误,2012-5.21  
  81. int fd;  
  82. struct v4l2_capability cap;  
  83. struct v4l2_fmtdesc fmtdesc;  
  84. struct v4l2_format fmt;  
  85. struct v4l2_requestbuffers reqbuf;  
  86. struct v4l2_buffer buf;  
  87. unsigned char *starter;  
  88. unsigned char *newBuf;  
  89. struct BITMAPFILEHEADER bfh;  
  90. struct BITMAPINFOHEADER bih;  
  91.   
  92.   
  93. void create_bmp_header()  
  94. {  
  95.   bfh.bfType = (unsigned short)0x4D42;  
  96.   bfh.bfSize = (unsigned long)(14 + 40 + VIDEO_WIDTH * VIDEO_HEIGHT*3);  
  97.   bfh.bfReserved1 = 0;  
  98.   bfh.bfReserved2 = 0;  
  99.   bfh.bfOffBits = (unsigned long)(14 + 40);  
  100.   
  101.   
  102.   bih.biBitCount = 24;  
  103.   bih.biWidth = VIDEO_WIDTH;  
  104.   bih.biHeight = VIDEO_HEIGHT;  
  105.   bih.biSizeImage = VIDEO_WIDTH * VIDEO_HEIGHT * 3;  
  106.   bih.biClrImportant = 0;  
  107.   bih.biClrUsed = 0;  
  108.   bih.biCompression = 0;  
  109.   bih.biPlanes = 1;  
  110.   bih.biSize = 40;//sizeof(bih);  
  111.   bih.biXPelsPerMeter = 0x00000ec4;  
  112.   bih.biYPelsPerMeter = 0x00000ec4;  
  113. }  
  114.   
  115.   
  116. int open_device()  
  117. {  
  118. /*  
  119. 在linux下设备都是以文件的形式进行管理的  
  120. ioctl是设备驱动程序中对设备的I/O通道进行管理的函数int ioctl(int fd,int cmd,...)?  
  121. 成功返回0,出错返回-1  
  122. 其中fd--就是用户程序打开设备使用open函数返回的文件标识符  
  123.     cmd--就是用户程序对设备的控制命令,至于后面都省略号,有或没有和cmd的意义相关  
  124. */  
  125.     int fd;  
  126.     fd = open(CAMERA_DEVICE, O_RDWR, 0);//  
  127.     if (fd < 0) {  
  128.         printf("Open %s failed\n", CAMERA_DEVICE);  
  129.         return -1;  
  130.     }  
  131.     return fd;  
  132. }  
  133.   
  134.   
  135. void get_capability()  
  136. {// 获取驱动信息  
  137. /*  
  138. 控制命令VIDIOC_QUERYCAP  
  139. 功能:查询设备驱动的功能;  
  140. 参数说明:参数类型为V4L2的能力描述类型struct v4l2_capability;  
  141. struct v4l2_capability {  
  142.         __u8    driver[16];     //i.e. "bttv"            //驱动名称,  
  143.         __u8    card[32];       // i.e. "Hauppauge WinTV"         //  
  144.         __u8    bus_info[32];   // "PCI:" + pci_name(pci_dev)     //PCI总线信息  
  145.         __u32   version;        // should use KERNEL_VERSION()   
  146.         __u32   capabilities;   // Device capabilities         //设备能力  
  147.         __u32   reserved[4];  
  148. };  
  149. 返回值说明: 执行成功时,函数返回值为 0;  
  150. 函数执行成功后,struct v4l2_capability 结构体变量中的返回当前视频设备所支持的功能  
  151. 例如支持视频捕获功能V4L2_CAP_VIDEO_CAPTURE或V4L2_CAP_STREAMING  
  152. */  
  153.     int ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);  
  154.     if (ret < 0) {  
  155.         printf("VIDIOC_QUERYCAP failed (%d)\n", ret);  
  156.         return;  
  157.     }  
  158.     // Print capability infomations  
  159.     printf("------------VIDIOC_QUERYCAP-----------\n");  
  160.     printf("Capability Informations:\n");  
  161.     printf(" driver: %s\n", cap.driver);  
  162.     printf(" card: %s\n", cap.card);  
  163.     printf(" bus_info: %s\n", cap.bus_info);  
  164.     printf(" version: %08X\n", cap.version);  
  165.     printf(" capabilities: %08X\n\n", cap.capabilities);  
  166.     return;  
  167. }  
  168.   
  169.   
  170. void get_format()  
  171. {  
  172. /*获取当前视频设备支持的视频格式  
  173. 控制命令 VIDIOC_ENUM_FMT  
  174. 功能: 获取当前视频设备支持的视频格式 。  
  175. 参数说明:参数类型为V4L2的视频格式描述符类型 struct v4l2_fmtdesc  
  176. struct v4l2_fmtdesc {  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值