opencv无法通过cv::CAP_PROP_FPS修改帧率的问题

我遇到了opencv c++无法通过cv::CAP_PROP_FPS修改帧率,即cap.get(CAP_PROP_FPS)虽然为60,但是我在运行while(1),每个循环读一张图时,每帧大概需要35-40ms。直接通过opencv修改fps后会出线以下报错

img

在使用您帖子中的方法后
https://blog.csdn.net/u013171226/article/details/120712614?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1.pc_relevant_default&spm=1001.2101.3001.4242.2&utm_relevant_index=4
可以达到约20-25ms每帧,但是他并不稳定,相同的代码在运行时还可能会出现30-35ms每帧的情况,基本是每次开机前两次运行才可以达到20ms的效果。
请问您是否有获得最大帧率的方法呢?我遇到的帧率不稳定的情况原因又是什么呢?
感谢您的解答
以下是我的摄像头参数,我的设备为百度edgeboard fz3b,系统为ubuntu 180.4,opencv版本为3.4.3

img


以下是我的代码,我通过查看每帧串口接收的时间来判断帧率。

#include <fstream>
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include "opencv2/opencv.hpp"
#include <unistd.h>
 
 
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <sys/time.h>


#include <math.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include "core/uart_test.hpp"

 
 
 
#define logChw printf("function:%s, line:%d======\n", __FUNCTION__, __LINE__)
 
#define FILE_VIDEO      "/dev/video0"
#define TRUE            (1)
#define FALSE           (0)
 
using namespace cv;
using namespace std;
using namespace LibSerial;

std::shared_ptr<Driver> driver = nullptr;
 
 
int main(int argc, char ** argv)
{
 

    //预留串口的设备名为/dev/ttyPS1
    driver = std::make_shared<Driver>("/dev/ttyUSB0", BaudRate::BAUD_115200);
    if (driver == nullptr) {
    std::cout << "Create Driver Error ." << std::endl;
    return -1;
    }
    //串口初始化,打开串口设备及配置串口数据格式
    int ret = driver->open();
    if (ret != 0){
    std::cout << "Driver Open failed ." << std::endl;
    return -1;
    }


    unsigned long int frameCount = 0;//把帧数打印出来方便调试.
    
    int fd = 0;
    struct v4l2_capability cap;
    struct v4l2_fmtdesc fmtdesc;
    struct v4l2_format fmt;
    struct v4l2_streamparm stream_para;
    struct v4l2_control ctrl;
 
    if((fd = open(FILE_VIDEO, O_RDWR)) == -1)
    {
        printf("open video error;;;;;;;;\n");
    }
 
    
    //查询设备属性
    if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) 
    {
        printf("Error opening device %s: unable to query device.\n",FILE_VIDEO);
        return FALSE;
    }
    else
    {
        printf("driver:\t\t%s\n",cap.driver);
        printf("card:\t\t%s\n",cap.card);
        printf("bus_info:\t%s\n",cap.bus_info);
        printf("version:\t%d\n",cap.version);
        printf("capabilities:\t%x\n",cap.capabilities);
        
        if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE) 
        {
            printf("Device %s: supports capture.\n",FILE_VIDEO);
        }
 
        if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING) 
        {
            printf("Device %s: supports streaming.\n",FILE_VIDEO);
        }
    }
 
    //设置及查看帧速率,这里只能是30帧,就是1秒采集30张图
    memset(&stream_para, 0, sizeof(struct v4l2_streamparm));
    stream_para.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    stream_para.parm.capture.timeperframe.denominator = 120;
    stream_para.parm.capture.timeperframe.numerator = 1;
 
    if(ioctl(fd, VIDIOC_S_PARM, &stream_para) == -1)
    {
        printf("Unable to set frame rate\n");
        return FALSE;
    }
    else
    {
        printf("ser framerate success!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    }
 
    if(ioctl(fd, VIDIOC_G_PARM, &stream_para) == -1)
    {
        printf("Unable to get frame rate\n");
        return FALSE;       
    }
 
    {
        printf("numerator:%d\ndenominator:%d\n",stream_para.parm.capture.timeperframe.numerator,stream_para.parm.capture.timeperframe.denominator);
    }
    
    printf("stream_para.parm.capture.timeperframe.denominator::::::::::::::::::::::::::::%d\n", stream_para.parm.capture.timeperframe.denominator);
    close(fd);
    
 
    
    logChw;
    {
        logChw;
        clock_t start,end;
        double process_time = 0.0f;
        double total_time = 0.0f;
 
 
        cv::Mat frameTemp;
        cv::Mat frame;
        cv::VideoCapture cap;
        cap.open(0,cv::CAP_V4L);//注意这里不能用cap.open(0);

       
        int video_fps = cap.get(CAP_PROP_FPS); //获取帧率
        int width  = cap.get(CAP_PROP_FRAME_WIDTH);//获取图像宽 
        int height = cap.get(CAP_PROP_FRAME_HEIGHT); //获取图像高
        cout<<"video_fps:::  "<<video_fps<<endl;
        int n = 0x01;
 
        while(cap.isOpened())
        {  
            //cap >> frameTemp;
            printf("frameCount is =========%ld===========================================================================================================================\n", frameCount);
            
            //int video_fps = cap.get(CAP_PROP_FPS); //获取帧率
            //cout<<"video_fps:::  "<<video_fps<<endl;
    


            cap.read(frame);
            driver->senddata(n);
            n++;
            if(n == 0x0d)
            n = 0x01;
                
        }
 
    }
    
}


帧间图象的变化幅度决定了mpeg流的大小,总线和内存带宽决定了是否有延迟