Video4linux(v4l)摄像头采集jpeg图片

1、Video4linux下视频编程的流程
(1)打开视频设备:
(2) 读取设备信息
(3)更改设备当前设置(没必要的话可以不做)
(4)进行视频采集,两种方法:
        a.内存映射
        b.直接从设备读取
(5)对采集的视频进行处理
(6)关闭视频设备。

2、为程序定义的数据结构

  1. typedef struct v4l_struct   
  2. {  
  3.    int fd;  
  4.    struct video_capability capability;  
  5.    struct video_channel channel[4];   
  6.    struct video_picture picture;    
  7.    struct video_window window;   
  8.    struct video_capture capture;   
  9.    struct video_buffer buffer;   
  10.    struct video_mmap mmap;   
  11.    struct video_mbuf mbuf;      
  12.    unsigned char *map;  
  13.    int frame;  
  14.    int framestat[2];   
  15. }vd;  
typedef struct v4l_struct 
{
   int fd;
   struct video_capability capability;
   struct video_channel channel[4]; 
   struct video_picture picture;  
   struct video_window window; 
   struct video_capture capture; 
   struct video_buffer buffer; 
   struct video_mmap mmap; 
   struct video_mbuf mbuf;    
   unsigned char *map;
   int frame;
   int framestat[2]; 
}vd;

3、Video4linux支持的数据结构及其用途

  1. struct video_capability  
  2. {  
  3.  char name[32];  
  4.  int type;  
  5.  int channels; /* Num channels */  
  6.  int audios; /* Num audio devices */  
  7.  int maxwidth; /* Supported width */  
  8.  int maxheight; /* And height */  
  9.  int minwidth; /* Supported width */  
  10.  int minheight; /* And height */  
  11. };  
  12. struct video_channel  
  13. {  
  14.  int channel;  
  15.  char name[32];  
  16.  int tuners;  
  17.  __u32  flags;  
  18. #define VIDEO_VC_TUNER  1 /* Channel has a tuner */   
  19. #define VIDEO_VC_AUDIO  2 /* Channel has audio */   
  20.  __u16  type;  
  21. #define VIDEO_TYPE_TV  1   
  22. #define VIDEO_TYPE_CAMERA 2    
  23.  __u16 norm;   /* Norm set by channel */  
  24. };  
  25. struct video_picture  
  26. {  
  27.  __u16 brightness;  
  28.  __u16 hue;  
  29.  __u16 colour;  
  30.  __u16 contrast;  
  31.  __u16 whiteness; /* Black and white only */  
  32.  __u16 depth;  /* Capture depth */  
  33.  __u16   palette; /* Palette in use */  
  34. #define VIDEO_PALETTE_GREY 1 /* Linear greyscale */   
  35. #define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */   
  36. #define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */   
  37. #define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */   
  38. #define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */    
  39. #define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */   
  40. #define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */   
  41. #define VIDEO_PALETTE_YUYV 8   
  42. #define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */   
  43. #define VIDEO_PALETTE_YUV420 10   
  44. #define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */   
  45. #define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */   
  46. #define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */   
  47. #define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */   
  48. #define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */   
  49. #define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */   
  50. #define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */   
  51. #define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */   
  52. };  
  53. struct video_window  
  54. {  
  55.  __u32 x,y;   /* Position of window */  
  56.  __u32 width,height;  /* Its size */  
  57.  __u32 chromakey;  
  58.  __u32 flags;  
  59.  struct video_clip *clips; /* Set only */  
  60.  int clipcount;  
  61. #define VIDEO_WINDOW_INTERLACE 1   
  62. #define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */   
  63. #define VIDEO_CLIP_BITMAP -1   
  64. /* bitmap is 1024x625, a '1' bit represents a clipped pixel */  
  65. #define VIDEO_CLIPMAP_SIZE (128 * 625)   
  66. };  
  67. struct video_capture  
  68. {  
  69.  __u32  x,y;   /* Offsets into image */  
  70.  __u32 width, height;  /* Area to capture */  
  71.  __u16 decimation;  /* Decimation divider */  
  72.  __u16 flags;   /* Flags for capture */  
  73. #define VIDEO_CAPTURE_ODD  0 /* Temporal */   
  74. #define VIDEO_CAPTURE_EVEN  1   
  75. };  
  76. struct video_buffer  
  77. {  
  78.  void *base;  
  79.  int height,width;  
  80.  int depth;  
  81.  int bytesperline;  
  82. };  
  83. struct video_mmap  
  84. {  
  85.  unsigned int frame;  /* Frame (0 - n) for double buffer */  
  86.  int  height,width;  
  87.  unsigned int format;  /* should be VIDEO_PALETTE_* */  
  88. };  
  89. #define VIDEO_MAX_FRAME  32   
  90. struct video_mbuf  
  91. {  
  92.  int size;  /* Total memory to map */  
  93.  int frames;  /* Frames */  
  94.  int offsets[VIDEO_MAX_FRAME];  
  95. };  
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 */
};
struct video_channel
{
 int channel;
 char name[32];
 int tuners;
 __u32  flags;
#define VIDEO_VC_TUNER  1 /* Channel has a tuner */
#define VIDEO_VC_AUDIO  2 /* Channel has audio */
 __u16  type;
#define VIDEO_TYPE_TV  1
#define VIDEO_TYPE_CAMERA 2 
 __u16 norm;   /* Norm set by channel */
};
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 */
#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ 
#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
#define VIDEO_PALETTE_YUYV 8
#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
#define VIDEO_PALETTE_YUV420 10
#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
};
struct video_window
{
 __u32 x,y;   /* Position of window */
 __u32 width,height;  /* Its size */
 __u32 chromakey;
 __u32 flags;
 struct video_clip *clips; /* Set only */
 int clipcount;
#define VIDEO_WINDOW_INTERLACE 1
#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
#define VIDEO_CLIP_BITMAP -1
/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
#define VIDEO_CLIPMAP_SIZE (128 * 625)
};
struct video_capture
{
 __u32  x,y;   /* Offsets into image */
 __u32 width, height;  /* Area to capture */
 __u16 decimation;  /* Decimation divider */
 __u16 flags;   /* Flags for capture */
#define VIDEO_CAPTURE_ODD  0 /* Temporal */
#define VIDEO_CAPTURE_EVEN  1
};
struct video_buffer
{
 void *base;
 int height,width;
 int depth;
 int bytesperline;
};
struct video_mmap
{
 unsigned int frame;  /* Frame (0 - n) for double buffer */
 int  height,width;
 unsigned int format;  /* should be VIDEO_PALETTE_* */
};
#define VIDEO_MAX_FRAME  32
struct video_mbuf
{
 int size;  /* Total memory to map */
 int frames;  /* Frames */
 int offsets[VIDEO_MAX_FRAME];
};

这些struct都来自videodev.h

4、安装libjpeg
官方网站:http://www.ijg.org/
下载地址:http://www.ijg.org/files/

5、使用v4l的摄像头采集jpeg图像的代码:

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <sys/types.h>   
  4. #include <sys/stat.h>   
  5. #include <sys/ioctl.h>   
  6. #include <sys/mman.h>   
  7. #include <fcntl.h>   
  8. #include <errno.h>   
  9. #include <linux/videodev.h>   
  10. #include <jpeglib.h>   
  11. #define WIDTH  320   
  12. #define HEIGHT 240   
  13. #define V4L_DEVICE "/dev/video0"   
  14. int write_jpeg(char *filename,unsigned char *buf,int quality,int width, int height, int gray)  
  15. {  
  16.     struct jpeg_compress_struct cinfo;  
  17.     struct jpeg_error_mgr jerr;  
  18.     FILE *fp;  
  19.     int i;  
  20.     unsigned char *line;  
  21.     int line_length;  
  22.     if (NULL == (fp = fopen(filename,"w")))  
  23.     {  
  24.           fprintf(stderr,"grab: can't open %s: %s\n", filename, strerror(errno));  
  25.           return -1;  
  26.     }  
  27.     cinfo.err = jpeg_std_error(&jerr);  
  28.     jpeg_create_compress(&cinfo);  
  29.     jpeg_stdio_dest(&cinfo, fp);  
  30.     cinfo.image_width  = width;  
  31.     cinfo.image_height = height;  
  32.     cinfo.input_components = gray ? 1: 3;  
  33.     cinfo.in_color_space = gray ? JCS_GRAYSCALE: JCS_RGB;  
  34.     jpeg_set_defaults(&cinfo);  
  35.     jpeg_set_quality(&cinfo, quality, TRUE);  
  36.     jpeg_start_compress(&cinfo, TRUE);  
  37.     line_length = gray ? width : width * 3;  
  38.     for (i = 0, line = buf; i < height; i++, line += line_length)  
  39.         jpeg_write_scanlines(&cinfo, &line, 1);  
  40.     jpeg_finish_compress(&(cinfo));  
  41.     jpeg_destroy_compress(&(cinfo));  
  42.     fclose(fp);  
  43.     return 0;  
  44. }  
  45. int main()  
  46. {  
  47.    unsigned char* buf;  
  48.    int i,j;  
  49.    int fd;  
  50.    int re;  
  51.    struct video_capability vcap;  
  52.    struct video_channel   vc;  
  53.    struct video_mbuf     mbuf;  
  54.    struct video_mmap    map;  
  55.    fd = open(V4L_DEVICE, O_RDWR);  
  56.    if(fd<=0)  
  57.    {  
  58.        perror("open");  
  59.        exit(1);  
  60.    }  
  61.    if(ioctl(fd, VIDIOCGCAP, &vcap)<0)  
  62.    {  
  63.        perror("VIDIOCGCAP");  
  64.        exit(1);  
  65.    }  
  66.    printf("Video Capture Device Name : %s\n",vcap.name);  
  67.    for(i=0;i<vcap.channels;i++)  
  68.    {  
  69.        vc.channel = i;  
  70.        if(ioctl(fd, VIDIOCGCHAN, &vc)<0)  
  71.        {  
  72.            perror("VIDIOCGCHAN");  
  73.            exit(1);  
  74.        }  
  75.        printf("Video Source (%d) Name : %s\n",i, vc.name);  
  76.    }  
  77.    vc.channel=0;  
  78.    if(ioctl(fd, VIDIOCSCHAN, &vc) < 0)  
  79.    {  
  80.        perror("VIDIOCSCHAN");  
  81.        exit(1);  
  82.    }  
  83.    if(ioctl(fd, VIDIOCGMBUF, &mbuf) < 0)  
  84.    {  
  85.        perror("VIDIOCGMBUF");  
  86.        exit(1);  
  87.    }  
  88.    buf=(unsigned char *)mmap(0,mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);  
  89.    if((int)buf < 0)  
  90.    {  
  91.        perror("mmap");  
  92.        exit(1);  
  93.    }  
  94.      
  95.    map.frame  = 0;  
  96.    map.height = HEIGHT;  
  97.    map.width  = WIDTH;  
  98.    map.format = VIDEO_PALETTE_RGB24;  
  99.    if(ioctl(fd, VIDIOCMCAPTURE, &map)<0)  
  100.    {  
  101.        perror("VIDIOCMCAPTURE");  
  102.        exit(1);  
  103.    }  
  104.    if(ioctl(fd, VIDIOCSYNC, &map.frame)<0)  
  105.    {  
  106.        perror("VIDIOCSYNC");  
  107.        exit(1);  
  108.    }  
  109.    if(-1==(write_jpeg("./pic001.jpeg",buf,75,WIDTH,HEIGHT,0)))  
  110.    {  
  111.         printf("write_jpeg error\n");  
  112.         exit(1);  
  113.    }  
  114.    munmap(buf,mbuf.size);  
  115.    close(fd);  
  116.    return 0;  
  117. }  
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/videodev.h>
#include <jpeglib.h>
#define WIDTH  320
#define HEIGHT 240
#define V4L_DEVICE "/dev/video0"
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: can't open %s: %s\n", 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;
}
int main()
{
   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    map;
   fd = open(V4L_DEVICE, O_RDWR);
   if(fd<=0)
   {
       perror("open");
       exit(1);
   }
   if(ioctl(fd, VIDIOCGCAP, &vcap)<0)
   {
       perror("VIDIOCGCAP");
       exit(1);
   }
   printf("Video Capture Device Name : %s\n",vcap.name);
   for(i=0;i<vcap.channels;i++)
   {
       vc.channel = i;
       if(ioctl(fd, VIDIOCGCHAN, &vc)<0)
       {
           perror("VIDIOCGCHAN");
           exit(1);
       }
       printf("Video Source (%d) Name : %s\n",i, vc.name);
   }
   vc.channel=0;
   if(ioctl(fd, VIDIOCSCHAN, &vc) < 0)
   {
       perror("VIDIOCSCHAN");
       exit(1);
   }
   if(ioctl(fd, VIDIOCGMBUF, &mbuf) < 0)
   {
       perror("VIDIOCGMBUF");
       exit(1);
   }
   buf=(unsigned char *)mmap(0,mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
   if((int)buf < 0)
   {
       perror("mmap");
       exit(1);
   }
   
   map.frame  = 0;
   map.height = HEIGHT;
   map.width  = WIDTH;
   map.format = VIDEO_PALETTE_RGB24;
   if(ioctl(fd, VIDIOCMCAPTURE, &map)<0)
   {
       perror("VIDIOCMCAPTURE");
       exit(1);
   }
   if(ioctl(fd, VIDIOCSYNC, &map.frame)<0)
   {
       perror("VIDIOCSYNC");
       exit(1);
   }
   if(-1==(write_jpeg("./pic001.jpeg",buf,75,WIDTH,HEIGHT,0)))
   {
        printf("write_jpeg error\n");
        exit(1);
   }
   munmap(buf,mbuf.size);
   close(fd);
   return 0;
}

v4l编程的详细介绍:http://blog.csdn.net/luxiaoxun/archive/2011/05/27/6450783.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值