• 设为首页
  • 收藏本站
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    查看: 2553|回复: 0

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

    [复制链接]

    该用户从未签到

    11

    主题

    117

    回帖

    349

    积分

    二级逆天

    积分
    349

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

    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. }
    复制代码
    回复

    使用道具 举报

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

    本版积分规则

    公告:服务器刚移机,
    大家请不要下载东西。
    会下载失败


    QQ 手机版 小黑屋 监管台 遇到问题请联系QQ1308068381 逆天PCB论坛

    Powered by Discuz! X3.5 © 2001-2023

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