搜索
bottom↓
回复: 3

视频采集图片的问题,有图有代码

[复制链接]

出0入0汤圆

发表于 2014-4-10 19:15:55 | 显示全部楼层 |阅读模式
使用V4L2做图片采集,查询到摄像头制式是YUYV,设置,申请帧缓存,读取,存储,得到.raw的文件,拿到windows下用picasa打开出现如下图片,请问可能是什么方面的原因?贴代码如下
  1. /*
  2. *  V4L2 video capture example
  3. */

  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <assert.h>

  8. #include <getopt.h>                /* getopt_long() */

  9. #include <fcntl.h>                /* low-level i/o */
  10. #include <unistd.h>
  11. #include <errno.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. #include <asm/types.h>                /* for videodev2.h */

  18. #include <linux/videodev2.h>
  19. //#include "YUV2JPEG.h"

  20. #define CLEAR(x) memset (&(x), 0, sizeof (x))

  21. typedef enum
  22. {
  23.   IO_METHOD_READ,
  24.   IO_METHOD_MMAP,
  25.   IO_METHOD_USERPTR,
  26. } io_method;

  27. struct buffer
  28. {
  29.   void *start;
  30.   size_t length;
  31. };

  32. static char *dev_name = NULL;
  33. static io_method io = IO_METHOD_MMAP;
  34.         /* can be V4L2_PIX_FMT_YUV420 or V4L2_PIX_FMT_PWC2 */
  35. static int pixel_format = V4L2_PIX_FMT_YUYV;
  36. static int fd = -1;
  37. struct buffer *buffers = NULL;
  38. static unsigned int n_buffers = 0;
  39. static unsigned int width = 640;
  40. static unsigned int height = 480;
  41. static unsigned int count = 2;

  42. static void errno_exit(const char *s)
  43. {
  44.   fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
  45.   exit(EXIT_FAILURE);
  46. }

  47. static int xioctl(int fd, int request, void *arg)
  48. {
  49.   int r;

  50.   do
  51.     r = ioctl(fd, request, arg);
  52.   while (-1 == r && EINTR == errno);

  53.   return r;
  54. }

  55. static void process_image(const void *p, ssize_t size)
  56. {
  57.   static int no_image = 0;
  58.   char filename[1024];
  59.   int fd;
  60.   ssize_t written = 0;

  61.   snprintf(filename, sizeof(filename), "/mnt/webcam-%5.5d.%s",
  62.            no_image++, pixel_format == V4L2_PIX_FMT_YUYV ? "raw" : "raw");
  63. //  snprintf(filename,sizeof(filename),"/mnt/picture%d.jpg",no_image++);

  64.   fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
  65.   if (fd < 0)
  66.     {
  67.       fputc('*', stdout);
  68.       fflush(stdout);
  69.       return;
  70.     }
  71.   do
  72.     {
  73.       int ret;
  74.       ret = write(fd, p + written, size - written);
  75.       if (ret < 0)
  76.         {
  77.           fputc('+', stdout);
  78.           fflush(stdout);
  79.           return;
  80.         }
  81.       written += ret;
  82.     }
  83.   while (written < size);
  84.   close(fd);


  85. //  YUV2JPEG((unsigned char *)p,640,480,filename);
  86.   fputc('.', stdout);
  87.   fflush(stdout);
  88. }

  89. static int read_frame(void)
  90. {
  91.   struct v4l2_buffer buf;
  92.   unsigned int i;
  93.   ssize_t read_bytes;
  94.   unsigned int total_read_bytes;

  95.   switch (io)
  96.     {
  97.     case IO_METHOD_READ:
  98.       total_read_bytes = 0;
  99.       do
  100.        {
  101.          read_bytes = read(fd, buffers[0].start, buffers[0].length);
  102.          if (read_bytes < 0)
  103.           {
  104.             switch (errno)
  105.              {
  106.               case EIO:
  107.               case EAGAIN:
  108.                 continue;
  109.               default:
  110.                 errno_exit("read");
  111.              }
  112.           }
  113.          total_read_bytes += read_bytes;

  114.        } while (total_read_bytes < buffers[0].length);
  115.       process_image(buffers[0].start, buffers[0].length);

  116.       break;

  117.     case IO_METHOD_MMAP:
  118.       CLEAR(buf);

  119.       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  120.       buf.memory = V4L2_MEMORY_MMAP;

  121.       if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
  122.         {
  123.           switch (errno)
  124.             {
  125.             case EAGAIN:
  126.               return 0;

  127.             case EIO:
  128.               /* Could ignore EIO, see spec. */

  129.               /* fall through */

  130.             default:
  131.               errno_exit("VIDIOC_DQBUF");
  132.             }
  133.         }

  134.       assert(buf.index < n_buffers);

  135.       process_image(buffers[buf.index].start, buf.length);

  136.       if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
  137.         errno_exit("VIDIOC_QBUF");

  138.       break;

  139.     case IO_METHOD_USERPTR:
  140.       CLEAR(buf);

  141.       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  142.       buf.memory = V4L2_MEMORY_USERPTR;

  143.       if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
  144.         {
  145.           switch (errno)
  146.             {
  147.             case EAGAIN:
  148.               return 0;

  149.             case EIO:
  150.               /* Could ignore EIO, see spec. */

  151.               /* fall through */

  152.             default:
  153.               errno_exit("VIDIOC_DQBUF");
  154.             }
  155.         }

  156.       for (i = 0; i < n_buffers; ++i)
  157.         if (buf.m.userptr == (unsigned long) buffers[i].start
  158.             && buf.length == buffers[i].length)
  159.           break;

  160.       assert(i < n_buffers);

  161.       process_image((void *) buf.m.userptr, buf.length);

  162.       if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
  163.         errno_exit("VIDIOC_QBUF");

  164.       break;
  165.     }

  166.   return 1;
  167. }

  168. static void mainloop(void)
  169. {
  170.   while (count-- > 0)
  171.     {
  172.       for (;;)
  173.         {
  174.           fd_set fds;
  175.           struct timeval tv;
  176.           int r;

  177.           FD_ZERO(&fds);
  178.           FD_SET(fd, &fds);

  179.           /* Timeout. */
  180.           tv.tv_sec = 2;
  181.           tv.tv_usec = 0;

  182.           r = select(fd + 1, &fds, NULL, NULL, &tv);

  183.           if (-1 == r)
  184.             {
  185.               if (EINTR == errno)
  186.                 continue;

  187.               errno_exit("select");
  188.             }

  189.           if (0 == r)
  190.             {
  191.               fprintf(stderr, "select timeout\n");
  192.               exit(EXIT_FAILURE);
  193.             }

  194.           if (read_frame())
  195.             break;

  196.           /* EAGAIN - continue select loop. */
  197.         }
  198.     }
  199. }

  200. static void stop_capturing(void)
  201. {
  202.   enum v4l2_buf_type type;

  203.   switch (io)
  204.     {
  205.     case IO_METHOD_READ:
  206.       /* Nothing to do. */
  207.       break;

  208.     case IO_METHOD_MMAP:
  209.     case IO_METHOD_USERPTR:
  210.       type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  211.       if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
  212.         errno_exit("VIDIOC_STREAMOFF");

  213.       break;
  214.     }
  215. }

  216. static void start_capturing(void)
  217. {
  218.   unsigned int i;
  219.   enum v4l2_buf_type type;

  220.   switch (io)
  221.     {
  222.     case IO_METHOD_READ:
  223.       /* Nothing to do. */
  224.       break;

  225.     case IO_METHOD_MMAP:
  226.       for (i = 0; i < n_buffers; ++i)
  227.         {
  228.           struct v4l2_buffer buf;

  229.           CLEAR(buf);

  230.           buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  231.           buf.memory = V4L2_MEMORY_MMAP;
  232.           buf.index = i;

  233.           if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
  234.             errno_exit("VIDIOC_QBUF");
  235.         }

  236.       type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  237.       if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
  238.         errno_exit("VIDIOC_STREAMON");

  239.       break;

  240.     case IO_METHOD_USERPTR:
  241.       for (i = 0; i < n_buffers; ++i)
  242.         {
  243.           struct v4l2_buffer buf;

  244.           CLEAR(buf);

  245.           buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  246.           buf.memory = V4L2_MEMORY_USERPTR;
  247.           buf.m.userptr = (unsigned long) buffers[i].start;
  248.           buf.length = buffers[i].length;

  249.           if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
  250.             errno_exit("VIDIOC_QBUF");
  251.         }


  252.       type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  253.       if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
  254.         errno_exit("VIDIOC_STREAMON");

  255.       break;
  256.     }
  257. }

  258. static void uninit_device(void)
  259. {
  260.   unsigned int i;

  261.   switch (io)
  262.     {
  263.     case IO_METHOD_READ:
  264.       free(buffers[0].start);
  265.       break;

  266.     case IO_METHOD_MMAP:
  267.       for (i = 0; i < n_buffers; ++i)
  268.         if (-1 == munmap(buffers[i].start, buffers[i].length))
  269.           errno_exit("munmap");
  270.       break;

  271.     case IO_METHOD_USERPTR:
  272.       for (i = 0; i < n_buffers; ++i)
  273.         free(buffers[i].start);
  274.       break;
  275.     }

  276.   free(buffers);
  277. }

  278. static void init_read(unsigned int buffer_size)
  279. {
  280.   buffers = calloc(1, sizeof(*buffers));

  281.   if (!buffers)
  282.     {
  283.       fprintf(stderr, "Out of memory\n");
  284.       exit(EXIT_FAILURE);
  285.     }

  286.   buffers[0].length = buffer_size;
  287.   buffers[0].start = malloc(buffer_size);

  288.   if (!buffers[0].start)
  289.     {
  290.       fprintf(stderr, "Out of memory\n");
  291.       exit(EXIT_FAILURE);
  292.     }
  293. }

  294. static void init_mmap(void)
  295. {
  296.   struct v4l2_requestbuffers req;

  297.   CLEAR(req);

  298.   req.count = 4;
  299.   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  300.   req.memory = V4L2_MEMORY_MMAP;

  301.   if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
  302.     {
  303.       if (EINVAL == errno)
  304.         {
  305.           fprintf(stderr, "%s does not support "
  306.                   "memory mapping\n", dev_name);
  307.           exit(EXIT_FAILURE);
  308.         }
  309.       else
  310.         {
  311.           errno_exit("VIDIOC_REQBUFS");
  312.         }
  313.     }

  314.   if (req.count < 2)
  315.     {
  316.       fprintf(stderr, "Insufficient buffer memory on %s\n", dev_name);
  317.       exit(EXIT_FAILURE);
  318.     }

  319.   buffers = calloc(req.count, sizeof(*buffers));

  320.   if (!buffers)
  321.     {
  322.       fprintf(stderr, "Out of memory\n");
  323.       exit(EXIT_FAILURE);
  324.     }

  325.   for (n_buffers = 0; n_buffers < req.count; ++n_buffers)
  326.     {
  327.       struct v4l2_buffer buf;

  328.       CLEAR(buf);

  329.       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  330.       buf.memory = V4L2_MEMORY_MMAP;
  331.       buf.index = n_buffers;

  332.       if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
  333.         errno_exit("VIDIOC_QUERYBUF");

  334.       buffers[n_buffers].length = buf.length;
  335.       buffers[n_buffers].start = mmap(NULL /* start anywhere */ ,
  336.                                       buf.length,
  337.                                       PROT_READ | PROT_WRITE /* required */ ,
  338.                                       MAP_SHARED /* recommended */ ,
  339.                                       fd, buf.m.offset);

  340.       if (MAP_FAILED == buffers[n_buffers].start)
  341.         errno_exit("mmap");
  342.     }
  343. }

  344. static void init_userp(unsigned int buffer_size)
  345. {
  346.   struct v4l2_requestbuffers req;

  347.   CLEAR(req);

  348.   req.count = 4;
  349.   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  350.   req.memory = V4L2_MEMORY_USERPTR;

  351.   if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
  352.     {
  353.       if (EINVAL == errno)
  354.         {
  355.           fprintf(stderr, "%s does not support "
  356.                   "user pointer i/o\n", dev_name);
  357.           exit(EXIT_FAILURE);
  358.         }
  359.       else
  360.         {
  361.           errno_exit("VIDIOC_REQBUFS");
  362.         }
  363.     }

  364.   buffers = calloc(4, sizeof(*buffers));

  365.   if (!buffers)
  366.     {
  367.       fprintf(stderr, "Out of memory\n");
  368.       exit(EXIT_FAILURE);
  369.     }

  370.   for (n_buffers = 0; n_buffers < 4; ++n_buffers)
  371.     {
  372.       buffers[n_buffers].length = buffer_size;
  373.       buffers[n_buffers].start = malloc(buffer_size);

  374.       if (!buffers[n_buffers].start)
  375.         {
  376.           fprintf(stderr, "Out of memory\n");
  377.           exit(EXIT_FAILURE);
  378.         }
  379.     }
  380. }

  381. static void init_device(void)
  382. {
  383.   struct v4l2_capability cap;
  384.   struct v4l2_cropcap cropcap;
  385.   struct v4l2_crop crop;
  386.   struct v4l2_format fmt;
  387.   unsigned int min;

  388.   if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap))
  389.     {
  390.       if (EINVAL == errno)
  391.         {
  392.           fprintf(stderr, "%s is no V4L2 device\n", dev_name);
  393.           exit(EXIT_FAILURE);
  394.         }
  395.       else
  396.         {
  397.           errno_exit("VIDIOC_QUERYCAP");
  398.         }
  399.     }
  400.   printf("cam name:%s\n driver name:%s\n driver version:%d\n businfo:%s\n"
  401.                   ,cap.card,cap.driver,cap.version,cap.bus_info);

  402.   if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
  403.     {
  404.       fprintf(stderr, "%s is no video capture device\n",cap.card);
  405.       exit(EXIT_FAILURE);
  406.     }
  407.   else
  408.   {
  409.           printf("%s is video capture device\n",cap.card);
  410.   }
  411.   switch (io)
  412.     {
  413.     case IO_METHOD_READ:
  414.       if (!(cap.capabilities & V4L2_CAP_READWRITE))
  415.         {
  416.           fprintf(stderr, "%s does not support read i/o\n",cap.card);
  417.           exit(EXIT_FAILURE);
  418.         }
  419.           else
  420.           {
  421.                   printf("%s support read i/o\n",cap.card);
  422.           }

  423.       break;

  424.     case IO_METHOD_MMAP:
  425.     case IO_METHOD_USERPTR:
  426.     if (!(cap.capabilities & V4L2_CAP_STREAMING))
  427.         {
  428.                 fprintf(stderr, "%s does not support streaming i/o\n",cap.card);
  429.                 exit(EXIT_FAILURE);
  430.         }
  431.         else
  432.         {
  433.                 printf("%s support streaming i/o\n",cap.card);
  434.         }
  435.       break;
  436.         }

  437.   /* Select video input, video standard and tune here. */

  438.   cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  439.   if (-1 == xioctl(fd, VIDIOC_CROPCAP, &cropcap))
  440.     {
  441.       /* Errors ignored. */
  442.     }

  443.   crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  444.   crop.c = cropcap.defrect;        /* reset to default */

  445.   if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop))
  446.     {
  447.       switch (errno)
  448.         {
  449.         case EINVAL:
  450.           printf("Cropping not supported\n");
  451.           /* Cropping not supported. */
  452.           break;
  453.         default:
  454.           /* Errors ignored. */
  455.           break;
  456.         }
  457.     }

  458.   CLEAR(fmt);

  459.   fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  460.   fmt.fmt.pix.width = width;
  461.   fmt.fmt.pix.height = height;
  462.   fmt.fmt.pix.pixelformat = pixel_format;
  463.   fmt.fmt.pix.field = V4L2_FIELD_SEQ_BT;//V4L2_FIELD_INTERLACED;

  464.   if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
  465.     errno_exit("VIDIOC_S_FMT");

  466.   /* Note VIDIOC_S_FMT may change width and height. */
  467.   width = fmt.fmt.pix.width;
  468.   height = fmt.fmt.pix.height;

  469.   switch (io)
  470.     {
  471.     case IO_METHOD_READ:
  472.       init_read(fmt.fmt.pix.sizeimage);
  473.       break;

  474.     case IO_METHOD_MMAP:
  475.       init_mmap();
  476.       break;

  477.     case IO_METHOD_USERPTR:
  478.       init_userp(fmt.fmt.pix.sizeimage);
  479.       break;
  480.     }
  481. }

  482. static void close_device(void)
  483. {
  484.   if (-1 == close(fd))
  485.     errno_exit("close");

  486.   fd = -1;
  487. }

  488. static void open_device(void)
  489. {
  490.   struct stat st;

  491.   if (-1 == stat(dev_name, &st))
  492.     {
  493.       fprintf(stderr, "Cannot identify '%s': %d, %s\n",
  494.               dev_name, errno, strerror(errno));
  495.       exit(EXIT_FAILURE);
  496.     }

  497.   if (!S_ISCHR(st.st_mode))
  498.     {
  499.       fprintf(stderr, "%s is no device\n", dev_name);
  500.       exit(EXIT_FAILURE);
  501.     }

  502.   fd = open(dev_name, O_RDWR /* required */  | O_NONBLOCK, 0);

  503.   if (-1 == fd)
  504.     {
  505.       fprintf(stderr, "Cannot open '%s': %d, %s\n",
  506.               dev_name, errno, strerror(errno));
  507.       exit(EXIT_FAILURE);
  508.     }
  509. }

  510. static const char short_options[] = "c:d:f:hmrs:u";

  511. static const struct option long_options[] = {
  512.   {"count", required_argument, NULL, 'c'},
  513.   {"device", required_argument, NULL, 'd'},
  514.   {"format", required_argument, NULL, 'f'},
  515.   {"help", no_argument, NULL, 'h'},
  516.   {"mmap", no_argument, NULL, 'm'},
  517.   {"read", no_argument, NULL, 'r'},
  518.   {"size", required_argument, NULL, 's'},
  519.   {"userp", no_argument, NULL, 'u'},
  520.   {0, 0, 0, 0}
  521. };

  522. static int video_fmtdesc(int fd)
  523. {
  524.         /***********Format Enumeration************/
  525.         int ret = 0;
  526.         struct v4l2_fmtdesc fmtdes;
  527.         CLEAR(fmtdes);
  528.         fmtdes.index = 0;
  529.         fmtdes.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  530.         printf("\n****vidioc enumeration stream format informations:****\n");
  531.         while (1) {
  532.                 ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdes);
  533.                 if (ret < 0)
  534.                         break;
  535.                 printf("{ pixelformat = %c%c%c%c, description = %s }\n",
  536.                                 (fmtdes.pixelformat & 0xFF),
  537.                                 (fmtdes.pixelformat >> 8) & 0xFF,
  538.                                 (fmtdes.pixelformat >> 16) & 0xFF,
  539.                                 (fmtdes.pixelformat >> 24) & 0xFF,
  540.                                 fmtdes.description);
  541.                 if (fmtdes.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  542.                         printf("video capture type:\n");
  543.                 if (fmtdes.pixelformat == V4L2_PIX_FMT_YUYV)
  544.                         printf("V4L2_PIX_FMT_YUYV\n");
  545.                 fmtdes.index++;
  546.         }
  547.         return 0;
  548. }

  549. int main(int argc, char **argv)
  550. {
  551.   dev_name = "/dev/video0";

  552.   open_device();

  553.   init_device();

  554.   video_fmtdesc(fd);

  555.   start_capturing();

  556.   mainloop();

  557.   stop_capturing();

  558.   uninit_device();

  559.   close_device();

  560.   exit(EXIT_SUCCESS);

  561.   return 0;
  562. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2014-4-12 12:35:19 | 显示全部楼层
还在纠结中,有谁帮忙分析下?

出0入0汤圆

 楼主| 发表于 2014-4-24 20:55:36 | 显示全部楼层
现在把图片转换为RGB24模式,但是有不规则横纹出现,有遇到过类似问题的吗?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-5-4 21:35:09 | 显示全部楼层
是不是屏的问题  
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 14:59

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表