当前位置:   article > 正文

qt学习:arm摄像头+c调用v412框架驱动+qt调用v412框架驱动 显示摄像头画面_嵌入式qt识别不到摄像头

嵌入式qt识别不到摄像头

目录

跟内核进行数据通信的函数

编程步骤

c代码

头文件

打开摄像头文件 /dev/videox

获取当前主机上(开发板)摄像头列表信息

设置当前摄像头的画面格式  比如说 设置 采集图像的宽度为640  高度 480

在内核空间中,申请一个缓冲区队列(队列中有4块缓冲区)

将申请好的缓冲区队列 映射到 用户空间中

开启摄像头 

采集数据 yuyv

将采集出来的yuyv格式的数据---转换成 rgb

将c代码移植到qt代码中,在qt的界面显示摄像头画面

MCamera摄像头类添加头文件,成员,函数接口

实现MCamera摄像头类函数接口

在主ui界面类加入头文件,成员,函数接口

在构造函数中初始化摄像头类和定时器类,并关联定时器的槽函数

开启摄像头按钮点击事件

关闭摄像头按钮点击事件

拍照按钮点击事件

定时器槽函数实现


qt由于在arm qt版本下,没有多媒体库,所以,arm qt程序要访问摄像头,那么必须要使用linux操作系统v412(video for linux 2)机制

简单来说就是要在arm上安装v412框架就可以使用摄像头

跟内核进行数据通信的函数

#include <stropts.h>

int ioctl(int fildes,int request,.../* arg */);

  • 第一个参数:fd文件描述符
  • 第二个参数:要发送的命令
    • VIDIOC_REQBUFS:分配内存
    • VIDIOC_QUERYBUF:把 VIDIOC_REQBUFS 中分配的数据缓存转换成物理地址
    • VIDIOC_QUERYCAP:查询驱动功能
    • VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式
    • VIDIOC_S_FMT:设置当前驱动的频捕获格式
    • VIDIOC_G_FMT:读取当前驱动的频捕获格式
    • VIDIOC_TRY_FMT:验证当前驱动的显示格式
    • VIDIOC_CROPCAP:查询驱动的修剪能力
    • VIDIOC_S_CROP:设置视频信号的边框
    • VIDIOC_G_CROP:读取视频信号的边框
    • VIDIOC _QBUF:把数据放回缓存队列
    • VIDIOC_DQBUF:把数据从缓存中读取出来
    • VIDIOC_$TREAMON:开始视频显示函数
    • VIDIOC_STREAMOFF:结束视频显示函数
    • VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如 PAL或NTSC。
  • ....:变参接口,根据第二个参数来决定

编程步骤

  • 打开摄像头文件 /dev/videox
  • 获取当前主机上的摄像头列表信息
    • #define VIDIOC_ENUM_FMT _IOWR('V',2,struct v412_fmtdesc)
      • struct v412_fmtdesc fmt;
      • ioctl(fd,VIDIOC_ENUM_FMT,&fmt);
  • 设置当前视频捕捉格式
    • 也就是设置摄像头采集画面的宽度、高度、格式
    • VIDIOC_S_FMT:设置当前驱动的视频捕捉格式
    • #define VIDIOC_S_FMT _IOWR('V',5,struct v412_format)
      • struct v412_format format;
      • format.宽度 = 640;
      • format.高度 = 400;
      • ioctl(fd,VIDIOC_S_FMT,&format);
  • 申请内核缓冲区队列VIDIOC_REQBUFS
    • 一般会将摄像头获取到的数据放到4块内存空间---一次性存储4帧画面数据
  • 将申请的内核缓冲区队列映射到用户空间VIDIOC_QUERYBUF
  • 开启摄像头VIDIOC_STREAMON  
    • 将开启摄像头的命令从应用层发送到内核层中,内核层就会驱动这个摄像头开始工作
  • while(1)
    • 采集数据  --yuyv格式
      • 注意;摄像头采集出来的图像数据格式组成是yuyv
    • 将采集出来的一帧画面yuyv格式的数据转为rgb格式
    • 将转换好rgb格式数据显示到ui控件上

c代码

头文件

  1. #include<stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <sys/ioctl.h>
  6. #include <string.h>
  7. #include <linux/videodev2.h> //v4l2视频开发框架
  8. #include <sys/mman.h>

打开摄像头文件 /dev/videox

  1. //打开摄像头文件返回文件描述符
  2. int fd = open("/dev/video7",O_RDWR);
  3. if(fd == -1)
  4. {
  5. perror("open camera error");
  6. return -1;
  7. }

获取当前主机上(开发板)摄像头列表信息

  1. //2、获取当前主机上(开发板)摄像头列表信息
  2. //#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
  3. struct v4l2_fmtdesc v4fmt; //定义一个结构体
  4. v4fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //视频捕捉类型
  5. int i = 0;
  6. while(1)
  7. {
  8. v4fmt.index = i++;
  9. int ret = ioctl(fd,VIDIOC_ENUM_FMT,&v4fmt);
  10. if(ret < 0)
  11. {
  12. //perror("获取失败");
  13. break;
  14. }
  15. printf("index = %d\n",v4fmt.index);
  16. printf("flags = %d\n",v4fmt.flags);
  17. printf("description = %s\n",v4fmt.description);
  18. unsigned char*p = (unsigned char*)&v4fmt.pixelformat;
  19. printf("pixelformat = %c%c%c%c\n",p[0],p[1],p[2],p[3]);
  20. printf("reserved = %d\n",v4fmt.reserved[0]);
  21. }

设置当前摄像头的画面格式  比如说 设置 采集图像的宽度为640  高度 480

  1. //3、设置当前摄像头的画面格式 比如说 设置 采集图像的宽度为640 高度 480
  2. //#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
  3. //发送VIDIOC_S_FMT命令需要定义struct v4l2_format结构体,
  4. //该结构体存放摄像头的画面格式,将摄像头设置为视频捕捉模式需要用到struct v4l2_format结构体
  5. struct v4l2_format vfmt;
  6. //设置为视频捕捉模式
  7. vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  8. vfmt.fmt.pix.width = 640;// 设置宽(因为底层驱动已固定大小,不能任意改)
  9. vfmt.fmt.pix.height = 480;//设置高度
  10. vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; //设置视频采集格式
  11. //将设置好的格式发送到摄像头
  12. ioctl(fd,VIDIOC_S_FMT,&vfmt);
  13. //设置完通过VIDIOC_G_FMT这个命令来查看格式有没有设置成功
  14. //#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) //获取格式
  15. memset(&vfmt,0,sizeof(vfmt)); //清空结构体
  16. //设置为视频捕捉模式
  17. vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  18. //获取的格式信息存放在该结构体中
  19. int ret = ioctl(fd,VIDIOC_G_FMT,&vfmt);
  20. if(ret < 0)
  21. {
  22. perror("获取格式失败");
  23. return -1;
  24. }
  25. //获取成功判断它的宽和高和模式
  26. if(vfmt.fmt.pix.width == 640 && vfmt.fmt.pix.height == 480 && vfmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV )
  27. {
  28. printf("设置成功\n");
  29. }else{
  30. printf("设置失败\n");
  31. }

在内核空间中,申请一个缓冲区队列(队列中有4块缓冲区)

  1. //4、在内核空间中,申请一个缓冲区队列(队列中有4块缓冲区)
  2. //发送VIDIOC_REQBUFS命令需要struct v4l2_requestbuffers结构体
  3. struct v4l2_requestbuffers reqbuffers;
  4. reqbuffers.count = 4; //申请4个缓冲区
  5. reqbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;// 摄像头采集模式
  6. reqbuffers.memory = V4L2_MEMORY_MMAP; // mmap内存映射
  7. //向内核空间打一个报告,向你申请4个缓冲区队列,申请的方式为内存映射
  8. ret = ioctl(fd,VIDIOC_REQBUFS,&reqbuffers); //获取的信息存放在该结构体
  9. if(ret < 0)
  10. {
  11. perror("申请队列空间失败");
  12. return -1;
  13. }

将申请好的缓冲区队列 映射到 用户空间中

  1. //5、将申请好的缓冲区队列映射到用户空间中
  2. //#define VIDIOC_QUERYBUF _IOWR('v',9,struct v4l2_buffer)
  3. //这个数组有4个元素,每个元素存储的是地址,存储的地址就是映射成功之后的地址
  4. unsigned char* mptr[4];
  5. unsigned int size[4];
  6. //发送VIDIOC_QUERYBUF命令需要struct v4l2_buffer结构体
  7. struct v4l2_buffer mapbuffer;
  8. mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;// 摄像头采集模式
  9. for(int i=0;i<4;i++){
  10. mapbuffer.index = i; //申请的缓冲区编号
  11. //发送VIDIOC_QUERYBUF命令来查询内核空间队列
  12. ret = ioctl(fd,VIDIOC_QUERYBUF,&mapbuffer);
  13. if(ret < 0) {
  14. perror("查询内核空间队列失败\n");
  15. return -1;
  16. }
  17. //mmap真正来实现内存映射 ,该函数的返回值是一个内存的首地址
  18. mptr[i] = (unsigned char*)mmap(NULL,mapbuffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,mapbuffer.m.offset);
  19. size[i] = mapbuffer.length;
  20. //通知使用完毕,----放回内核
  21. //#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
  22. ret = ioctl(fd,VIDIOC_QBUF,&mapbuffer);
  23. if(ret < 0){
  24. perror("放回失败\n");
  25. return -1;
  26. }
  27. }

开启摄像头 

  1. //6、开启摄像头
  2. //#define VIDIOC_STREAMON _IOW('V', 18, int)
  3. int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;// 摄像头采集模式
  4. //发送VIDIOC_QUERYBUF命令来开启摄像头
  5. ioctl(fd,VIDIOC_STREAMON,&type);

采集数据 yuyv

  1. unsigned char buffer[640*480*3] = {0};//采集后的数据
  2. int size;
  3. //发送命令采集数据函数
  4. get_frame(buffer,&size);
  5. //获取图片
  6. void get_frame(unsigned char*buffer,int *size)
  7. {
  8. //1、先查询 当前帧数据 到底 在哪个 缓冲区中
  9. //采集数据 --VIDIOC_DQBUF:把数据从缓存中读取出来
  10. //#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer)
  11. //发送VIDIOC_DQBUF需要struct v4l2_buffer结构体
  12. struct v4l2_buffer readbuffer;
  13. readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//采集模式
  14. //发送VIDIOC_DQBUF采集数据放到结构体里
  15. int ret = ioctl(fd,VIDIOC_DQBUF,&readbuffer);
  16. if(ret < 0)
  17. {
  18. perror("提取数据失败");
  19. return -1 ;
  20. }
  21. //使用内存拷贝 -- void *memcpy(void *dest, const void *src, size_t n);
  22. memcpy(buffer,mptr[readbuffer.index],readbuffer.length);
  23. *size = readbuffer.length;
  24. //VIDIOC_QBUF:把数据放回缓存队列
  25. //通知内核已使用完毕
  26. //#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
  27. ret = ioctl(fd,VIDIOC_QBUF,&readbuffer);
  28. if(ret < 0)
  29. {
  30. perror("放回队列失败");
  31. return -1 ;
  32. }
  33. }

将采集出来的yuyv格式的数据---转换成 rgb

  1. unsigned char rgb[640*480*3] = {0};//转换后的数据
  2. //8、将采集出来的yuyv格式的数据---转换成 rgb
  3. yuyv2rgb0(buffer, rgb, 640, 480);
  4. //将yuyv格式转为rgb格式
  5. int yuyv2rgb0(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
  6. {
  7. unsigned int in, out;
  8. int y0, u, y1, v;
  9. unsigned int pixel24;
  10. unsigned char *pixel = (unsigned char *)&pixel24;
  11. unsigned int size = width*height*2;
  12. for(in = 0, out = 0; in < size; in += 4, out += 6)
  13. {
  14. y0 = yuv[in+0];
  15. u = yuv[in+1];
  16. y1 = yuv[in+2];
  17. v = yuv[in+3];
  18. sign3 = 1;
  19. pixel24 = yuyv2rgb(y0, u, v);
  20. rgb[out+0] = pixel[0];
  21. rgb[out+1] = pixel[1];
  22. rgb[out+2] = pixel[2];
  23. pixel24 = yuyv2rgb(y1, u, v);
  24. rgb[out+3] = pixel[0];
  25. rgb[out+4] = pixel[1];
  26. rgb[out+5] = pixel[2];
  27. }
  28. return 0;
  29. }

将c代码移植到qt代码中,在qt的界面显示摄像头画面

新建一个ui界面,布局一个两个按钮用于开启,停止,一个QLabel显示画面

通过定时器来调整帧数

新建一个MCamera摄像头类,将c代码移植进去

MCamera摄像头类添加头文件,成员,函数接口

  1. extern "C"{
  2. #include<stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <sys/ioctl.h>
  7. #include <string.h>
  8. #include <linux/videodev2.h> //v4l2视频开发框架
  9. #include <sys/mman.h>
  10. #include <unistd.h>
  11. }
  12. class MCamera
  13. {
  14. public:
  15. MCamera(const char*deviceName = "/dev/video7");
  16. void start();//启动摄像头
  17. void stop();//关闭摄像头
  18. void get_frame(unsigned char*buffer,int *size);//获取图像数据
  19. int yuyv2rgb0(unsigned char *buffer, unsigned char *rgbdata, int w, int h);//yuyv转为rgb
  20. private:
  21. int fd;//摄像头文件描述符
  22. unsigned char* mptr[4];//这个数组有4个元素,每个元素存储的是地址,存储的地址就是映射成功之后的地址
  23. unsigned int size[4];//图像的大小
  24. bool captrueFlag;//拍照标志位
  25. };

实现MCamera摄像头类函数接口

  1. MCamera::MCamera(const char*deviceName )
  2. {
  3. //1、打开摄像头文件
  4. //打开摄像头文件返回文件描述符
  5. fd = open(deviceName,O_RDWR);
  6. if(fd == -1)
  7. {
  8. perror("open camera error");
  9. return ;
  10. }
  11. //2、获取当前主机上(开发板)摄像头列表信息
  12. //#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
  13. struct v4l2_fmtdesc v4fmt; //定义一个结构体
  14. v4fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //视频捕捉类型
  15. int i = 0;
  16. while(1)
  17. {
  18. v4fmt.index = i++;
  19. int ret = ioctl(fd,VIDIOC_ENUM_FMT,&v4fmt);
  20. if(ret < 0)
  21. {
  22. //perror("获取失败");
  23. break;
  24. }
  25. printf("index = %d\n",v4fmt.index);
  26. printf("flags = %d\n",v4fmt.flags);
  27. printf("description = %s\n",v4fmt.description);
  28. unsigned char*p = (unsigned char*)&v4fmt.pixelformat;
  29. printf("pixelformat = %c%c%c%c\n",p[0],p[1],p[2],p[3]);
  30. printf("reserved = %d\n",v4fmt.reserved[0]);
  31. }
  32. //3、设置当前摄像头的画面格式 比如说 设置 采集图像的宽度为640 高度 480
  33. //#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
  34. struct v4l2_format vfmt;
  35. vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  36. vfmt.fmt.pix.width = 640;// 设置宽(因为底层驱动已固定大小,不能任意改)
  37. vfmt.fmt.pix.height = 480;//设置高度
  38. vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; //设置视频采集格式
  39. ioctl(fd,VIDIOC_S_FMT,&vfmt);
  40. //#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) //获取格式
  41. memset(&vfmt,0,sizeof(vfmt)); //清 零结构体
  42. vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  43. int ret = ioctl(fd,VIDIOC_G_FMT,&vfmt); //获取的 信息存 放在该结构体
  44. if(ret < 0)
  45. {
  46. perror("获取格式失败");
  47. return ;
  48. }
  49. if(vfmt.fmt.pix.width == 640 && vfmt.fmt.pix.height == 480 && vfmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV )
  50. {
  51. printf("设置成功\n");
  52. }else{
  53. printf("设置失败\n");
  54. }
  55. //4、在内核空间中,申请一个缓冲区队列(队列中有4块缓冲区)
  56. struct v4l2_requestbuffers reqbuffers;
  57. reqbuffers.count = 4; //申请4个缓冲区
  58. reqbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;// 摄像头采集
  59. reqbuffers.memory = V4L2_MEMORY_MMAP; // mmap
  60. //向内核空间打一个报告,向你申请4个缓冲区队列,申请的方式为内存映射
  61. ret = ioctl(fd,VIDIOC_REQBUFS,&reqbuffers); //获取的 信息存 放在该结构体
  62. if(ret < 0)
  63. {
  64. perror("申请队列空间失败");
  65. return ;
  66. }
  67. //5、将申请好的缓冲区队列 映射到 用户空间中
  68. struct v4l2_buffer mapbuffer;
  69. mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  70. for(int i=0;i<4;i++){
  71. mapbuffer.index = i; //申请的缓冲区编号
  72. ret = ioctl(fd,VIDIOC_QUERYBUF,&mapbuffer);
  73. if(ret < 0) {
  74. perror("查询内核空间队列失败\n");
  75. return ;
  76. }
  77. //真正来实现内存映射 ,该函数的返回值是一个内存的首地址
  78. mptr[i] = (unsigned char*)mmap(NULL,mapbuffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,mapbuffer.m.offset);
  79. size[i] = mapbuffer.length;
  80. //通知使用完毕,----放回内核
  81. //#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
  82. ret = ioctl(fd,VIDIOC_QBUF,&mapbuffer);
  83. if(ret < 0){
  84. perror("放回失败\n");
  85. return ;
  86. }
  87. }
  88. }
  89. void MCamera::start()
  90. {
  91. //6、开启摄像头
  92. //#define VIDIOC_STREAMON _IOW('V', 18, int)
  93. int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  94. ioctl(fd,VIDIOC_STREAMON,&type);
  95. }
  96. void MCamera::stop()
  97. {
  98. //[8] 停止采集
  99. int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  100. int ret = ioctl(fd,VIDIOC_STREAMOFF,&type);
  101. //释放内存 int munmap(void *addr, size_t length);
  102. for(int i=0;i<4;i++)
  103. {
  104. munmap(mptr[i],size[i]);
  105. }
  106. //[9] 关闭设备
  107. ::close(fd);
  108. }
  109. void MCamera::get_frame(unsigned char *buffer, int *size)
  110. {
  111. //采集数据 --VIDIOC_DQBUF:把数据从缓存中读取出来
  112. //#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer)
  113. //1、先查询 当前帧数据 到底 在哪个 缓冲区中
  114. struct v4l2_buffer readbuffer;
  115. readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  116. int ret = ioctl(fd,VIDIOC_DQBUF,&readbuffer);
  117. if(ret < 0)
  118. {
  119. perror("提取数据失败");
  120. return ;
  121. }
  122. //使用内存拷贝 -- void *memcpy(void *dest, const void *src, size_t n);
  123. memcpy(buffer,mptr[readbuffer.index],readbuffer.length);
  124. *size = readbuffer.length;
  125. //VIDIOC_QBUF:把数据放回缓存队列
  126. //通知内核已使用完毕
  127. //#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
  128. ret = ioctl(fd,VIDIOC_QBUF,&readbuffer);
  129. if(ret < 0)
  130. {
  131. perror("放回队列失败");
  132. return ;
  133. }
  134. }
  135. int MCamera::yuyv2rgb0(unsigned char *buffer, unsigned char *rgbdata, int w, int h)
  136. {
  137. int r1, g1, b1;
  138. int r2, g2, b2;
  139. for(int i=0; i<w*h/2; i++)
  140. {
  141. char data[4];
  142. memcpy(data, buffer+i*4, 4);
  143. //Y0U0Y1V1 -->[Y0 U0 V1] [Y1 U0 V1]
  144. unsigned char Y0=data[0];
  145. unsigned char U0=data[1];
  146. unsigned char Y1=data[2];
  147. unsigned char V1=data[3];
  148. r1 = Y0+1.4075*(V1-128); if(r1>255)r1=255; if(r1<0)r1=0;
  149. g1 =Y0- 0.3455 * (U0-128) - 0.7169*(V1-128); if(g1>255)g1=255; if(g1<0)g1=0;
  150. b1 = Y0 + 1.779 * (U0-128); if(b1>255)b1=255; if(b1<0)b1=0;
  151. r2 = Y1+1.4075*(V1-128);if(r2>255)r2=255; if(r2<0)r2=0;
  152. g2 = Y1- 0.3455 * (U0-128) - 0.7169*(V1-128); if(g2>255)g2=255; if(g2<0)g2=0;
  153. b2 = Y1 + 1.779 * (U0-128); if(b2>255)b2=255; if(b2<0)b2=0;
  154. rgbdata[i*6+0]=r1;
  155. rgbdata[i*6+1]=g1;
  156. rgbdata[i*6+2]=b1;
  157. rgbdata[i*6+3]=r2;
  158. rgbdata[i*6+4]=g2;
  159. rgbdata[i*6+5]=b2;
  160. }
  161. }

在主ui界面类加入头文件,成员,函数接口

  1. #include <QTimer>
  2. #include "mcamera.h"
  3. private slots:
  4. void onUpdateCameraUi();
  5. private:
  6. MCamera *m_camera;//自定义摄像头类
  7. QTimer *m_timer;//定时器类

在构造函数中初始化摄像头类和定时器类,并关联定时器的槽函数

  1. m_camera = NULL;
  2. m_timer = new QTimer;
  3. connect(m_timer,&QTimer::timeout,this,&Widget::onUpdateCameraUi);

开启摄像头按钮点击事件

  1. if(m_camera == NULL)
  2. {
  3. m_camera = new MCamera;
  4. m_camera->start();
  5. //启动定时器,间隔时间采集图像数据
  6. m_timer->start(1); //1秒钟采集 一张画面(一帧画面)
  7. }

关闭摄像头按钮点击事件

  1. if(m_camera != NULL)
  2. {
  3. m_timer->stop();
  4. m_camera->stop();
  5. delete m_camera;
  6. m_camera = NULL;
  7. }

拍照按钮点击事件

captrueFlag=true;

定时器槽函数实现

  1. // 采集数据
  2. unsigned char buffer[640*480*3] = {0};
  3. unsigned char rgb[640*480*3] = {0};
  4. int size;
  5. m_camera->get_frame(buffer,&size);
  6. //yuyv转换rgb
  7. m_camera->yuyv2rgb0(buffer,rgb,640,480);
  8. //显示 源图像rgb --->pic对象
  9. QImage img = QImage(rgb,640,480,QImage::Format_RGB888);
  10. //保存为图片
  11. if(captrueFlag)
  12. {
  13. img.save("1.bmp");
  14. captrueFlag = false;
  15. }
  16. QPixmap pic = QPixmap::fromImage(img);
  17. ui->label->setPixmap(pic);

在linux中交叉编译放到开发板上运行

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/258221
推荐阅读
相关标签
  

闽ICP备14008679号