查看完整版本: [-- qt使用摄像头问题 --]

QTCN开发网 -> Qt嵌入式开发 -> qt使用摄像头问题 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

bbmmdjejsjcc 2019-01-09 08:37

qt使用摄像头问题

我有两个问题想请教一下:
     我的板子用的摄像头是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 2019-02-27 12:15
这个需要自己用v4l2写一个类。
  1. //查询设备属性
        struct v4l2_capability cap;
        if(ioctl(camera_fd, VIDIOC_QUERYCAP, &cap) < 0) {
            qDebug() << TIMEMS << "error in VIDIOC_QUERYCAP";
            close(camera_fd);
            return false;
        }

        if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
            qDebug() << TIMEMS << "it is not a video capture device";
            close(camera_fd);
            return false;
        }

        if(!(cap.capabilities & V4L2_CAP_STREAMING)) {
            qDebug() << TIMEMS << "it can not streaming";
            close(camera_fd);
            return false;
        }

        if(cap.capabilities == 0x4000001) {
            qDebug() << TIMEMS << "capabilities:" << "V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING";
        }

        //设置视频输入源
        int input = 0;
        if(ioctl(camera_fd, VIDIOC_S_INPUT, &input) < 0) {
            qDebug() << TIMEMS << "error in VIDIOC_S_INPUT";
            close(camera_fd);
            return false;
        }

        //设置图片格式和分辨率
        struct v4l2_format fmt;
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV ;//V4L2_PIX_FMT_YUV420  V4L2_PIX_FMT_YUYV
        fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
        fmt.fmt.pix.width = cameraWidth;
        fmt.fmt.pix.height = cameraHeight;

        if(ioctl(camera_fd, VIDIOC_S_FMT, &fmt) < 0) {
            close(camera_fd);
            return false;
        }

        //查看图片格式和分辨率,判断是否设置成功
        if(ioctl(camera_fd, VIDIOC_G_FMT, &fmt) < 0) {
            qDebug() << TIMEMS << "error in VIDIOC_G_FMT";
            close(camera_fd);
            return false;
        }

        //重新打印下宽高看下是否真正设置成功
        qDebug() << TIMEMS << "cameraWidth =" << cameraWidth << "cameraHeight =" << cameraHeight << "  width =" << fmt.fmt.pix.width << "height =" << fmt.fmt.pix.height;
        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));

        //重新设置宽高为真实的宽高
        cameraWidth = fmt.fmt.pix.width;
        cameraHeight = fmt.fmt.pix.height;

        //设置帧格式
        struct v4l2_streamparm parm;
        parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        parm.parm.capture.timeperframe.numerator = 1;
        parm.parm.capture.timeperframe.denominator = 25;
        parm.parm.capture.capturemode = 0;

        if(ioctl(camera_fd, VIDIOC_S_PARM, &parm) < 0) {
            qDebug() << TIMEMS << "error in VIDIOC_S_PARM";
            close(camera_fd);
            return false;
        }

        if(ioctl(camera_fd, VIDIOC_G_PARM, &parm) < 0) {
            qDebug() << TIMEMS << "error in VIDIOC_G_PARM";
            close(camera_fd);
            return false;
        }

        //申请和管理缓冲区
        struct v4l2_requestbuffers reqbuf;
        reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        reqbuf.memory = V4L2_MEMORY_MMAP;
        reqbuf.count = 1;

        if(ioctl(camera_fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
            qDebug() << TIMEMS << "error in VIDIOC_REQBUFS";
            close(camera_fd);
            return false;
        }

        img_buffers = (ImgBuffer *)calloc(1, sizeof(ImgBuffer));
        if(img_buffers == NULL) {
            qDebug() << TIMEMS << "error in calloc";
            close(camera_fd);
            return false;
        }

        struct v4l2_buffer buffer;
        for(int numBufs = 0; numBufs < 1; numBufs++) {
            buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer.memory = V4L2_MEMORY_MMAP;
            buffer.index = numBufs;

            if(ioctl(camera_fd, VIDIOC_QUERYBUF, &buffer) < 0) {
                qDebug() << TIMEMS << "error in VIDIOC_QUERYBUF";
                free(img_buffers);
                close(camera_fd);
                return false;
            }

            img_buffers[numBufs].length = buffer.length;
            img_buffers[numBufs].start = (quint8 *)mmap (NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, camera_fd, buffer.m.offset);
            if(MAP_FAILED == img_buffers[numBufs].start) {
                qDebug() << TIMEMS << "error in mmap";
                free(img_buffers);
                close(camera_fd);
                return false;
            }

            //把缓冲帧放入队列
            if(ioctl(camera_fd, VIDIOC_QBUF, &buffer) < 0) {
                qDebug() << TIMEMS << "error in VIDIOC_QBUF";
                for(int i = 0; i <= numBufs; i++) {
                    munmap(img_buffers[i].start, img_buffers[i].length);
                }

                free(img_buffers);
                close(camera_fd);
                return false;
            }
        }

        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if(ioctl(camera_fd, VIDIOC_STREAMON, &type) < 0) {
            qDebug() << TIMEMS << "error in VIDIOC_STREAMON";
            for(int i = 0; i < 1; i++) {
                munmap(img_buffers[i].start, img_buffers[i].length);
            }

            free(img_buffers);
            close(camera_fd);
            return false;
        }

        qDebug() << TIMEMS << "init camera ok";
        return true;



查看完整版本: [-- qt使用摄像头问题 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled