• 2641阅读
  • 1回复

qt使用摄像头问题 [复制链接]

上一主题 下一主题
离线bbmmdjejsjcc
 

只看楼主 正序阅读 楼主  发表于: 2019-01-09
我有两个问题想请教一下:
     我的板子用的摄像头是ov5642,摄像头是好的,用c程序写的摄像头测试程序可以很好的运行并且在屏幕上显示图像;我板子屏幕上的界面是用qt来设计,所以需要在qt里面使用摄像头;

   1.我用qt自带的QCamera类点不亮板子上的摄像头,报的错误信息是:"ERROR:v4l2 capture: slave not found",请问您知道原因及怎么解决吗?
   2.之所以要解决问题1,而不自己写一个摄像头类,是因为,我已经尝试这么做过了,但是碰到了新的问题,目前我显示屏的主界面是用qtquick的qml来做的,qml会刷新全屏显示的内容,当我把c程序控制测试摄像头部分写成一个Camera c++类并且实例化一个对象当作属性导入qml用之后,摄像头会往fb里面写内容显示摄像图像,图像也的确可以显示,但是qml控制的界面也会往fb里面写入数据来刷新图像,而且qml是全屏刷新,即使是界面元素没有用到的背景部分也写入"黑色"来刷新,导致qml界面会一直刷新摄像头部分,从而造成不断闪烁,这个问题我暂时没有能够解决,所以才不得不把Qt自带的QCamera类用起来,但是用的时候就出现了问题1所述的问题,请问您那边有人遇到过并且解决了吗,有过这种处理经验的应该能明白我的疑惑及困境,希望能指点一下,感激不尽
    
离线liudianwu

只看该作者 1楼 发表于: 2019-02-27
这个需要自己用v4l2写一个类。
  1. //查询设备属性
  2.     struct v4l2_capability cap;
  3.     if(ioctl(camera_fd, VIDIOC_QUERYCAP, &cap) < 0) {
  4.         qDebug() << TIMEMS << "error in VIDIOC_QUERYCAP";
  5.         close(camera_fd);
  6.         return false;
  7.     }
  8.     if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
  9.         qDebug() << TIMEMS << "it is not a video capture device";
  10.         close(camera_fd);
  11.         return false;
  12.     }
  13.     if(!(cap.capabilities & V4L2_CAP_STREAMING)) {
  14.         qDebug() << TIMEMS << "it can not streaming";
  15.         close(camera_fd);
  16.         return false;
  17.     }
  18.     if(cap.capabilities == 0x4000001) {
  19.         qDebug() << TIMEMS << "capabilities:" << "V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING";
  20.     }
  21.     //设置视频输入源
  22.     int input = 0;
  23.     if(ioctl(camera_fd, VIDIOC_S_INPUT, &input) < 0) {
  24.         qDebug() << TIMEMS << "error in VIDIOC_S_INPUT";
  25.         close(camera_fd);
  26.         return false;
  27.     }
  28.     //设置图片格式和分辨率
  29.     struct v4l2_format fmt;
  30.     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  31.     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV ;//V4L2_PIX_FMT_YUV420  V4L2_PIX_FMT_YUYV
  32.     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
  33.     fmt.fmt.pix.width = cameraWidth;
  34.     fmt.fmt.pix.height = cameraHeight;
  35.     if(ioctl(camera_fd, VIDIOC_S_FMT, &fmt) < 0) {
  36.         close(camera_fd);
  37.         return false;
  38.     }
  39.     //查看图片格式和分辨率,判断是否设置成功
  40.     if(ioctl(camera_fd, VIDIOC_G_FMT, &fmt) < 0) {
  41.         qDebug() << TIMEMS << "error in VIDIOC_G_FMT";
  42.         close(camera_fd);
  43.         return false;
  44.     }
  45.     //重新打印下宽高看下是否真正设置成功
  46.     qDebug() << TIMEMS << "cameraWidth =" << cameraWidth << "cameraHeight =" << cameraHeight << "  width =" << fmt.fmt.pix.width << "height =" << fmt.fmt.pix.height;
  47.     qDebug() << TIMEMS << "pixelformat =" << QString("%1%2%3%4").arg(QChar(fmt.fmt.pix.pixelformat & 0xFF)).arg(QChar((fmt.fmt.pix.pixelformat >> 8) & 0xFF)).arg(QChar((fmt.fmt.pix.pixelformat >> 16) & 0xFF)).arg(QChar((fmt.fmt.pix.pixelformat >> 24) & 0xFF));
  48.     //重新设置宽高为真实的宽高
  49.     cameraWidth = fmt.fmt.pix.width;
  50.     cameraHeight = fmt.fmt.pix.height;
  51.     //设置帧格式
  52.     struct v4l2_streamparm parm;
  53.     parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  54.     parm.parm.capture.timeperframe.numerator = 1;
  55.     parm.parm.capture.timeperframe.denominator = 25;
  56.     parm.parm.capture.capturemode = 0;
  57.     if(ioctl(camera_fd, VIDIOC_S_PARM, &parm) < 0) {
  58.         qDebug() << TIMEMS << "error in VIDIOC_S_PARM";
  59.         close(camera_fd);
  60.         return false;
  61.     }
  62.     if(ioctl(camera_fd, VIDIOC_G_PARM, &parm) < 0) {
  63.         qDebug() << TIMEMS << "error in VIDIOC_G_PARM";
  64.         close(camera_fd);
  65.         return false;
  66.     }
  67.     //申请和管理缓冲区
  68.     struct v4l2_requestbuffers reqbuf;
  69.     reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  70.     reqbuf.memory = V4L2_MEMORY_MMAP;
  71.     reqbuf.count = 1;
  72.     if(ioctl(camera_fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
  73.         qDebug() << TIMEMS << "error in VIDIOC_REQBUFS";
  74.         close(camera_fd);
  75.         return false;
  76.     }
  77.     img_buffers = (ImgBuffer *)calloc(1, sizeof(ImgBuffer));
  78.     if(img_buffers == NULL) {
  79.         qDebug() << TIMEMS << "error in calloc";
  80.         close(camera_fd);
  81.         return false;
  82.     }
  83.     struct v4l2_buffer buffer;
  84.     for(int numBufs = 0; numBufs < 1; numBufs++) {
  85.         buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  86.         buffer.memory = V4L2_MEMORY_MMAP;
  87.         buffer.index = numBufs;
  88.         if(ioctl(camera_fd, VIDIOC_QUERYBUF, &buffer) < 0) {
  89.             qDebug() << TIMEMS << "error in VIDIOC_QUERYBUF";
  90.             free(img_buffers);
  91.             close(camera_fd);
  92.             return false;
  93.         }
  94.         img_buffers[numBufs].length = buffer.length;
  95.         img_buffers[numBufs].start = (quint8 *)mmap (NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, camera_fd, buffer.m.offset);
  96.         if(MAP_FAILED == img_buffers[numBufs].start) {
  97.             qDebug() << TIMEMS << "error in mmap";
  98.             free(img_buffers);
  99.             close(camera_fd);
  100.             return false;
  101.         }
  102.         //把缓冲帧放入队列
  103.         if(ioctl(camera_fd, VIDIOC_QBUF, &buffer) < 0) {
  104.             qDebug() << TIMEMS << "error in VIDIOC_QBUF";
  105.             for(int i = 0; i <= numBufs; i++) {
  106.                 munmap(img_buffers[i].start, img_buffers[i].length);
  107.             }
  108.             free(img_buffers);
  109.             close(camera_fd);
  110.             return false;
  111.         }
  112.     }
  113.     enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  114.     if(ioctl(camera_fd, VIDIOC_STREAMON, &type) < 0) {
  115.         qDebug() << TIMEMS << "error in VIDIOC_STREAMON";
  116.         for(int i = 0; i < 1; i++) {
  117.             munmap(img_buffers[i].start, img_buffers[i].length);
  118.         }
  119.         free(img_buffers);
  120.         close(camera_fd);
  121.         return false;
  122.     }
  123.     qDebug() << TIMEMS << "init camera ok";
  124.     return true;

欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
快速回复
限100 字节
 
上一个 下一个