首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >V4L2框架滴剂

V4L2框架滴剂
EN

Stack Overflow用户
提问于 2017-09-14 21:18:34
回答 1查看 1.6K关注 0票数 0

上下文

你好!我一直在为一个机器人项目开发软件,该项目将视觉作为主要感官之一。我一直在围绕Raspberry Pi 3构建系统,运行带有4.9.35-v7+内核的。除了其他车载感应器外,我还计划训练一些来自摄像机的记录驾驶数据的ML模型。为了检索视频帧,我使用v4l2 api和Minoru 3D摄像头。我的项目的源代码可以在https://github.com/mrpossoms/AVC2017上找到。

问题

这是一个非常奇怪的问题。我上面描述的内容工作得很好,除了帧速率从目标15 from显著下降之外,只有当它看到一个超过1米远的对象时,才能这样做!我录制了一段这里视频,展示了这个问题。首先,我把我的手非常靠近相机,你可以看到在终端,帧速率开始在理想的15英尺。然而,随着我慢慢地移动我的手,帧速率下降到7 7fps左右!

这是我的相机代码:

代码语言:javascript
复制
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string.h>
#include <strings.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>

#include "structs.h"
#include "cam.h"

#define CAM_FPS 5

cam_t cam_open(const char* path, cam_settings_t* cfg)
{

    int fd = open(path, O_RDWR);
    int res;

    if(fd < 0)
    {
        fprintf(stderr, "Error opening video device '%s'\n", path);
        //exit(-1);

        cam_t empty = {};
        return empty;
    }

    struct v4l2_capability cap;
    res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if(res < 0)
    {
        fprintf(stderr, "Error: %d querying '%s' for capabilities (%d)\n", res, path, errno);
        exit(-2);
    }

    if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
    {
        fprintf(stderr, "Error: '%s' lacks V4L2_CAP_VIDEO_CAPTURE capability\n", path);
    }

    res = cam_config(fd, cfg);
    if(res < 0)
    {
        fprintf(stderr, "Error: %d configuring '%s' (%d)\n", res, path, errno);
        exit(-3);
    }

    // Inform v4l about the buffers we want to receive data through
    struct v4l2_requestbuffers bufrequest = {};
    bufrequest.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    bufrequest.memory = V4L2_MEMORY_MMAP;
    bufrequest.count = 2;

    if(ioctl(fd, VIDIOC_REQBUFS, &bufrequest) < 0)
    {
        fprintf(stderr, "VIDIOC_REQBUFS\n");
        exit(-4);
    }


    if(bufrequest.count < 2)
    {
        fprintf(stderr, "Not enough memory\n");
        exit(-5);
    }


    struct v4l2_buffer bufferinfo = {};
    void** fbs = calloc(sizeof(void*), bufrequest.count);
    for(int i = bufrequest.count; i--;)
    {
        bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        bufferinfo.memory = V4L2_MEMORY_MMAP;
        bufferinfo.index = i;

        if(ioctl(fd, VIDIOC_QUERYBUF, &bufferinfo) < 0)
        {
            fprintf(stderr, "VIDIOC_QUERYBUF\n");
            exit(-5);
        }

        fbs[i] = mmap(
            NULL,
            bufferinfo.length,
            PROT_READ | PROT_WRITE,
            MAP_SHARED,
            fd,
            bufferinfo.m.offset
        );

        if(fbs[i] == MAP_FAILED)
        {
            fprintf(stderr, "mmap failed\n");
            exit(-6);
        }

        bzero(fbs[i], bufferinfo.length);
        ioctl(fd, VIDIOC_QBUF, &bufferinfo);
    }


    cam_t cam = {
        .fd = fd,
        .frame_buffers = fbs,
        .buffer_info = bufferinfo,
    };

    cam_wait_frame(&cam);

    int type = bufferinfo.type;
    if(ioctl(fd, VIDIOC_STREAMON, &type) < 0)
    {
        fprintf(stderr, "Error starting streaming\n");
        exit(-7);
    }

    return cam;
}


int cam_request_frame(cam_t* cam)
{
    cam->buffer_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    cam->buffer_info.memory = V4L2_MEMORY_MMAP;

    return ioctl(cam->fd, VIDIOC_QBUF, &cam->buffer_info);
}


int cam_wait_frame(cam_t* cam)
{
    ioctl(cam->fd, VIDIOC_DQBUF, &cam->buffer_info);
}


int cam_config(int fd, cam_settings_t* cfg)
{
    int res = 0;
    struct v4l2_format format;

    if(!cfg)
    {
        fprintf(stderr, "Error: null configuration provided\n");
        return -1;
    }

/*
    res = ioctl(fd, VIDIOC_G_FMT, &format);
    if(res < 0)
    {
        fprintf(stderr, "Error: failed retrieving camera settings (%d)\n", errno);
        return -2;
    }
*/

    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    format.fmt.pix.width = cfg->width;
    format.fmt.pix.height = cfg->height;

    if(ioctl(fd, VIDIOC_S_FMT, &format) < 0)
    {
        fprintf(stderr, "Error: failed applying camera settings\n");
        return -3;
    }

    struct v4l2_streamparm parm = {};

    parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    parm.parm.capture.timeperframe.numerator = 1;
    parm.parm.capture.timeperframe.denominator = 15;

    res = ioctl(fd, VIDIOC_S_PARM, &parm);

    return 0;
}

我可以100%的时间重复这个问题,我真的不知道是什么导致了这种行为。任何建议或想法都会受到极大的赞赏。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-15 19:14:40

正如马克所建议的,问题在于暴露。司机必须已经决定,它需要更多的曝光时间,每帧在黑暗的情况下。仅仅是把摄像机带到外面,就立即将帧速率提高到目标的15 the。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46228379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档