我遇到了opencv c++无法通过cv::CAP_PROP_FPS修改帧率,即cap.get(CAP_PROP_FPS)虽然为60,但是我在运行while(1),每个循环读一张图时,每帧大概需要35-40ms。直接通过opencv修改fps后会出线以下报错
在使用您帖子中的方法后
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
#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流的大小,总线和内存带宽决定了是否有延迟