我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 2550|回复: 0

全志A20 a10下ov7670测试程序,拍照一张bmp图片

[复制链接]

该用户从未签到

11

主题

117

回帖

344

积分

二级逆天

积分
344

社区居民忠实会员终身成就奖

QQ
发表于 2015-3-16 10:03:23 | 显示全部楼层 |阅读模式
  1. /*
  2. *for a10 one video device ov7670 bmp
  3. *by jiangdou 2014-0701
  4. *
  5. *
  6. *
  7. *
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <assert.h>
  13. #include <getopt.h>
  14. #include <fcntl.h>
  15. #include <unistd.h>
  16. #include <errno.h>
  17. #include <malloc.h>
  18. #include <sys/stat.h>
  19. #include <sys/types.h>
  20. #include <sys/time.h>
  21. #include <sys/mman.h>
  22. #include <sys/ioctl.h>
  23. #include <sys/types.h>
  24. #include <linux/videodev2.h>
  25. #include <time.h>
  26. #define CLEAR(x) memset (&(x), 0, sizeof (x))
  27. typedef unsigned long       DWORD;
  28. typedef int                 BOOL;
  29. typedef unsigned char       BYTE;
  30. typedef unsigned short      WORD;
  31. typedef float               FLOAT;
  32. typedef int                INT;
  33. typedef unsigned int    UINT;
  34. typedef unsigned int    *PUINT;
  35. struct buffer {
  36.     void    *start;   
  37.     size_t    length;
  38. };
  39. static char *dev_name  = "/dev/video0";//摄像头设备名
  40. static int fd  = -1;
  41. struct buffer *buffers         = NULL;
  42. static unsigned int n_buffers       = 0;
  43. FILE *file_fd;  
  44. FILE *hf;
  45. static unsigned long file_length;
  46. static unsigned char *file_name;     //全局变量和静态全局变量的区别:都是静态存储方式,但全局变量可为多个源文件共同使用,静态全局变量只在本文件中使用
  47. //////////////////////////////////////////////////////
  48. //获取一帧数据
  49. //////////////////////////////////////////////////////
  50. BYTE clip255(long v)
  51. {
  52.     if(v < 0) v=0;
  53.     else if( v > 255) v=255;
  54.     return (BYTE)v;
  55. }
  56. void yuv2bmp(BYTE *YUV2buff,BYTE *RGBbuff,DWORD dwSize)
  57. {
  58.     DWORD count;
  59.     for(  count = 0; count < dwSize; count += 4 )
  60.     {
  61.         //Y0 U0 Y1 V0
  62.         BYTE Y0 = *YUV2buff;
  63.         BYTE U  = *(++YUV2buff);
  64.         BYTE Y1 = *(++YUV2buff);
  65.         BYTE V  = *(++YUV2buff);
  66.         ++YUV2buff;
  67.         long Y,C,D,E;
  68.         BYTE R,G,B;
  69.         Y = Y0;
  70.         C = Y - 16;
  71.         D = U - 128;
  72.         E = V - 128;
  73.         R = clip255(( 298 * C + 409 * E + 128) >> 8);
  74.         G = clip255(( 298 * C - 100 * D - 208 * E + 128) >> 8);
  75.         B = clip255(( 298 * C + 516 * D + 128) >> 8);
  76.         *(RGBbuff)   = B;
  77.         *(++RGBbuff) = G;
  78.         *(++RGBbuff) = R;
  79.         Y = Y1;
  80.         C = Y-16;
  81.         D = U-128;
  82.         E = V-128;
  83.         R = clip255(( 298 * C + 409 * E + 128) >> 8);
  84.         G = clip255(( 298 * C - 100 * D - 208 * E + 128) >> 8);
  85.         B = clip255(( 298 * C + 516 * D + 128) >> 8);
  86.         *(++RGBbuff) = B;
  87.         *(++RGBbuff) = G;
  88.         *(++RGBbuff) = R;
  89.         ++RGBbuff;
  90.     }
  91. }
  92. //unsigned char a[153600];//240x320
  93. //unsigned char rgbout[230400]="";
  94. //unsigned char rgbout2[230400]="";
  95. unsigned char a[614400];
  96. unsigned char rgbout[921600]="";
  97. unsigned char rgbout2[921600]="";
  98. static int read_frame (void)         //函数声明为static,只能在本文件中调用
  99. {
  100.     struct v4l2_buffer buf;
  101.     unsigned int i;
  102.     CLEAR (buf);
  103.     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  104.     buf.memory = V4L2_MEMORY_MMAP;
  105.     ioctl (fd, VIDIOC_DQBUF, &buf); //出列采集的帧缓冲
  106.     assert (buf.index < n_buffers);
  107.     printf ("buf.index dq is %d,\n",buf.index);
  108.     fwrite(buffers[buf.index].start, buffers[buf.index].length, 1, file_fd); //将其写入文件中
  109.     ioctl (fd, VIDIOC_QBUF, &buf); //再将其入列
  110.     return 1;
  111. }
  112. int v4l2_get_fmt()
  113. {
  114.     struct v4l2_format my_fmt;
  115. }
  116. int main (int argc,char ** argv)
  117. {
  118.     struct v4l2_capability cap;
  119.     struct v4l2_format fmt,get_fmt;
  120.     unsigned int i;
  121.     enum v4l2_buf_type type;
  122.     unsigned int format;
  123.     file_fd = fopen("test-mmap.txt", "w");//图片文件名
  124.     fd = open (dev_name, O_RDWR | O_NONBLOCK, 0);
  125.     //ioctl (fd, VIDIOC_QUERYCAP, &cap);//获取摄像头参数
  126. //////////////////////////////////////////////////////////////////////////////
  127. ////////////////////////开启设置device,but I die this!///////////////////////
  128.     struct v4l2_input inp;
  129.     inp.index = 0;
  130.     if (inp.type == V4L2_INPUT_TYPE_CAMERA)
  131.         printf("enuminput type is V4L2_INPUT_TYPE_CAMERA!\n");
  132.    
  133.     if (-1 == ioctl (fd, VIDIOC_S_INPUT, &inp))    //设置输入index
  134.         printf("VIDIOC_S_INPUT error!\n");
  135.    
  136. /////////////////////////////////////////////////////////////////////////////
  137. /////////////////////////////////////////////////////////////////////////////
  138.    
  139.     CLEAR (fmt);
  140.     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  141.     fmt.fmt.pix.width = 640;//640
  142.     fmt.fmt.pix.height = 480;//480
  143.     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;//V4L2_PIX_FMT_RGB32;//YUYV
  144.     fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
  145.     int ff = ioctl (fd, VIDIOC_S_FMT, &fmt); //设置图像格式
  146.     if(ff<0){
  147.         printf("failture VIDIOC_S_FMT\n");
  148.         return 0;
  149.     }
  150.     printf("fmt.fmt.pix.width    %d \n ",fmt.fmt.pix.width);
  151.     printf("fmt.fmt.pix.bytesperline   %d \n",fmt.fmt.pix.bytesperline);
  152.     CLEAR(get_fmt);
  153.     get_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  154.     if(-1 == ioctl(fd,VIDIOC_G_FMT,&get_fmt))
  155.         printf("failture VIDIOC_S_FMT\n");
  156.     format = fmt.fmt.pix.pixelformat;
  157.     char code[5];
  158.     int j = 0;
  159.     for(j = 0; j < 4; j++)
  160.     code[j] = (format & (0xff << j*8)) >> j*8;
  161.     code[4] = 0;
  162.     printf("format(human readble):%s\n",code);
  163.     file_length = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; //计算图片大小
  164.     printf("file_length is %d  %ld",file_length,file_length);
  165.     struct v4l2_requestbuffers req;
  166.     CLEAR (req);
  167.     req.count   = 4;
  168.     req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  169.     req.memory  = V4L2_MEMORY_MMAP;
  170.     ioctl (fd, VIDIOC_REQBUFS, &req); //申请缓冲,count是申请的数量
  171.     if (req.count < 2)
  172.     printf("Insufficient buffer memory\n");
  173.     buffers = calloc (req.count, sizeof (*buffers));//内存中建立对应空间
  174.     for (n_buffers = 0; n_buffers < req.count; ++n_buffers)   //这个for循环内部的buf,只在此循环内有效,循环结束就没有了;
  175.     {                    
  176.         struct v4l2_buffer buf;   //驱动中的一帧-----------
  177.         CLEAR (buf);
  178.         buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  179.         buf.memory  = V4L2_MEMORY_MMAP;
  180.         buf.index   = n_buffers;
  181.         printf("buf.length is %d",buf.length);
  182.         if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buf)) //映射用户空间
  183.         printf ("VIDIOC_QUERYBUF error\n");
  184.         buffers[n_buffers].length = buf.length;
  185.         printf("buf.length  %d\n\n",buf.length);
  186.         printf("buf.length is displayed");
  187.         buffers[n_buffers].start = mmap (NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);//通过mmap建立映射关系
  188.         if (MAP_FAILED == buffers[n_buffers].start)
  189.             printf ("mmap failed\n");
  190.         printf("buf.length is %d;",buf.length);
  191.         if (-1 == ioctl (fd, VIDIOC_QBUF, &buf))//申请到的缓冲进入列队
  192.         printf ("VIDIOC_QBUF failed\n");
  193.         printf("buf.length is %d\n.",buf.length);
  194.     }
  195.    
  196.     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  197.     if (-1 == ioctl (fd, VIDIOC_STREAMON, &type)) //开始捕捉图像数据
  198.         printf ("VIDIOC_STREAMON failed\n");
  199.     else printf("VIDIOC_STREAMON succeed\n");
  200.    
  201.     for (;;) //这一段涉及到异步IO
  202.     {
  203.         fd_set fds;
  204.         struct timeval tv;
  205.             int r;
  206.         FD_ZERO (&fds);//将指定的文件描述符集清空
  207.         FD_SET (fd, &fds);//在文件描述符集合中增加一个新的文件描述符
  208.         tv.tv_sec = 2;
  209.         tv.tv_usec = 0;
  210.         r = select (fd + 1, &fds, NULL, NULL, &tv);//判断是否可读(即摄像头是否准备好),tv是定时
  211.         if (-1 == r) {
  212.             if (EINTR == errno)
  213.             continue;
  214.             printf ("select err\n");
  215.         }
  216.         if (0 == r) {
  217.             fprintf (stderr, "select timeout\n");
  218.             exit (EXIT_FAILURE);
  219.         }
  220.         if (read_frame ())//如果可读,执行read_frame ()函数,并跳出循环
  221.             break;
  222.     }
  223.     unmap:
  224.     for (i = 0; i < n_buffers; ++i)
  225.     if (-1 == munmap (buffers[i].start, buffers[i].length))
  226.     printf ("munmap error");
  227.     close (fd);
  228.     fclose (file_fd);
  229.     printf("end-begin");
  230.     FILE *p;
  231.     p=fopen("test-mmap.txt","r");
  232.     fread(a,1,614400,p);
  233.     fclose(p);
  234.     unsigned char *yuv=a;
  235.     printf("1\n");
  236.     unsigned char *q=rgbout;
  237.     yuv2bmp(yuv,rgbout,614400);//153600
  238.     printf("2\n");
  239.     int j0,k;
  240.    
  241.     for ( j0 =0 ; j0<480; j0++)
  242.     {
  243.         for ( k=0; k <640*3 ;k++)
  244.         {
  245.             rgbout2[k+640*j0*3] = rgbout[640*(480-j0-1)*3+k] ;
  246.         }
  247.     }
  248.     //  HANDLE hf = CreateFile(
  249.     //  "F://Frame.bmp", GENERIC_WRITE, FILE_SHARE_READ, NULL,
  250.     //   CREATE_ALWAYS, NULL, NULL );
  251.     hf=fopen("frame.bmp","w");
  252.     if( hf == -1 )
  253.         return 0;
  254.     //if( hf == INVALID_HANDLE_VALUE )return 0;
  255.     typedef struct tagBITMAPFILEHEADER {
  256.             WORD    bfType;
  257.             DWORD   bfSize;
  258.             WORD    bfReserved1;
  259.             WORD    bfReserved2;
  260.             DWORD   bfOffBits;
  261.     } BITMAPFILEHEADER;
  262.     typedef struct tagBITMAPINFOHEADER{
  263.             DWORD      biSize;
  264.             long       biWidth;
  265.             long       biHeight;
  266.             WORD       biPlanes;
  267.             WORD       biBitCount;
  268.             DWORD      biCompression;
  269.             DWORD      biSizeImage;
  270.             long       biXPelsPerMeter;
  271.             long       biYPelsPerMeter;
  272.             DWORD      biClrUsed;
  273.             DWORD      biClrImportant;
  274.     } BITMAPINFOHEADER;
  275.      // 写文件头
  276.     BITMAPFILEHEADER bfh;
  277.     // printf("bfh1=%d\n",sizeof(WORD)+sizeof(DWORD)+sizeof(WORD)+sizeof(WORD)+sizeof(DWORD));
  278.     memset( &bfh, 0,sizeof(BITMAPFILEHEADER) );
  279.     bfh.bfType = 'MB';
  280.     bfh.bfSize = 14 + 921600 + sizeof( BITMAPINFOHEADER );
  281.     bfh.bfOffBits = 14+ sizeof( BITMAPFILEHEADER );
  282.     // DWORD dwWritten = 0;
  283.     // WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );
  284.     printf("bfh=%d\n",sizeof(BITMAPFILEHEADER));
  285.     printf("word=%d\n",sizeof(WORD));
  286.     printf("Dword=%d\n",sizeof(DWORD));
  287.     fwrite(&bfh.bfType,sizeof(WORD),1,hf);
  288.     fwrite(&bfh.bfSize,sizeof(DWORD),1,hf);
  289.     fwrite(&bfh.bfReserved1,sizeof(WORD),1,hf);
  290.     fwrite(&bfh.bfReserved2,sizeof(WORD),1,hf);
  291.     fwrite(&bfh.bfOffBits,sizeof(DWORD),1,hf);
  292.       // 写位图格式
  293.     BITMAPINFOHEADER bih;
  294.     memset( &bih, 0, sizeof( bih ) );
  295.     bih.biSize = sizeof( bih );
  296.     bih.biWidth =640;
  297.     bih.biHeight = 480;
  298.     bih.biPlanes = 1;
  299.     bih.biBitCount = 24;
  300.     fwrite(&bih,sizeof(bih),1,hf);
  301.     // printf("bih=%d\n",sizeof(bih));
  302.     //WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );
  303.     // 写位图数据
  304.     //WriteFile( hf, rgbout2, 921600, &dwWritten, NULL );
  305.     // CloseHandle( hf );
  306.     fwrite(rgbout2,921600,1,hf);//230400
  307.     fclose(hf);
  308.       //exit (EXIT_SUCCESS);
  309.     return 0;
  310. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

论坛开启做任务可以
额外奖励金币快速赚
积分升级了


Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

平平安安
TOP
快速回复 返回顶部 返回列表