关于opencv更改摄像头参数(帧率,分辨率,曝光度……)的几个问题 您所在的位置:网站首页 相机增益范围 关于opencv更改摄像头参数(帧率,分辨率,曝光度……)的几个问题

关于opencv更改摄像头参数(帧率,分辨率,曝光度……)的几个问题

2023-09-20 10:46| 来源: 网络整理| 查看: 265

1,适用于VideoCapture打开的摄像头

VideoCapture capture(0); 设置摄像头参数 不要随意修改

capture.set(CV_CAP_PROP_FRAME_WIDTH, 1080);//宽度

capture.set(CV_CAP_PROP_FRAME_HEIGHT, 960);//高度

capture.set(CV_CAP_PROP_FPS, 30);//帧率 帧/秒

capture.set(CV_CAP_PROP_BRIGHTNESS, 1);//亮度 

capture.set(CV_CAP_PROP_CONTRAST,40);//对比度 40

capture.set(CV_CAP_PROP_SATURATION, 50);//饱和度 50

capture.set(CV_CAP_PROP_HUE, 50);//色调 50

capture.set(CV_CAP_PROP_EXPOSURE, 50);//曝光 50 获取摄像头参数

得到摄像头的参数

capture.get(CV_CAP_PROP_FRAME_WIDTH);

capture.get(CV_CAP_PROP_FRAME_HEIGHT);

capture.get(CV_CAP_PROP_FPS);

capture.get(CV_CAP_PROP_BRIGHTNESS);

capture.get(CV_CAP_PROP_CONTRAST);

capture.get(CV_CAP_PROP_SATURATION);

capture.get(CV_CAP_PROP_HUE);

capture.get(CV_CAP_PROP_EXPOSURE); 获取视频参数:

capture.get(CV_CAP_PROP_FRAME_COUNT);//视频帧数 

然后你会发现除了个别参数你能更改之外(如曝光度),大分布你是不能更改的,甚至都没办法得到,这种并不适用

2,不做开发,只是单纯的更改

那么推荐一个软件,amcap,百度网盘链接,https://pan.baidu.com/s/1pL8nq0V#list/path=%2F,很简单很容易上手。

补,现在突然想起来我的一个学长告诉我的,利用这个软件调节摄像头的曝光度,可以改变帧率,且摄像头会记住曝光度的设置(其他特性就没有这个特点)。-2019.3.12

3,修改opencv的文件,不过效果可能和第一个差不多

大概是在opencv的这个位置,找一下,modules/highgui/src/cap_v4l.cpp,里面有关于参数的设置,位置比较靠前,可以搜索,也可以直接找到

大致在200多行

4,v4l2

下面是我找到的一篇参考,可以突破帧率的限制,当然前提是摄像头支持

https://blog.csdn.net/c406495762/article/details/72732135

目前只适用于Linux系统,本人试验过,120帧的摄像头在只打开摄像头时可以达到100帧左右,设置的图片分辨率越小,能达到的帧率越高

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include #include #include #include using namespace std; using namespace cv; #define CLEAR(x) memset(&(x), 0, sizeof(x)) #define IMAGEWIDTH 3264 #define IMAGEHEIGHT 2448 #define WINDOW_NAME1 "【原始图】" //为窗口标题定义的宏 #define WINDOW_NAME2 "【图像轮廓】" //为窗口标题定义的宏 Mat g_srcImage; Mat g_grayImage; int g_nThresh = 90; int g_nMaxThresh = 255; RNG g_rng(12345); Mat g_cannyMat_output; vector g_vContours; vector g_vHierarchy; Point point1[100000]; Point point2[100000]; Point point3[100000]; int ii,iii; int flag2 = 0;//避障用 float number = 0; int fps=0; class V4L2Capture { public: V4L2Capture(char *devName, int width, int height); virtual ~V4L2Capture(); int openDevice(); int closeDevice(); int initDevice(); int startCapture(); int stopCapture(); int freeBuffers(); int getFrame(void **,size_t *); int backFrame(); static void test(); private: int initBuffers(); struct cam_buffer { void* start; unsigned int length; }; char *devName; int capW; int capH; int fd_cam; cam_buffer *buffers; unsigned int n_buffers; int frameIndex; }; V4L2Capture::V4L2Capture(char *devName, int width, int height) { // TODO Auto-generated constructor stub this->devName = devName; this->fd_cam = -1; this->buffers = NULL; this->n_buffers = 0; this->frameIndex = -1; this->capW=width; this->capH=height; } V4L2Capture::~V4L2Capture() { // TODO Auto-generated destructor stub } int V4L2Capture::openDevice() { /*设备的打开*/ printf("video dev : %s\n", devName); fd_cam = open(devName, O_RDWR); if (fd_cam < 0) { perror("Can't open video device"); } return 0; } int V4L2Capture::closeDevice() { if (fd_cam > 0) { int ret = 0; if ((ret = close(fd_cam)) < 0) { perror("Can't close video device"); } return 0; } else { return -1; } } int V4L2Capture::initDevice() { int ret; struct v4l2_capability cam_cap; //显示设备信息 struct v4l2_cropcap cam_cropcap; //设置摄像头的捕捉能力 struct v4l2_fmtdesc cam_fmtdesc; //查询所有支持的格式:VIDIOC_ENUM_FMT struct v4l2_crop cam_crop; //图像的缩放 struct v4l2_format cam_format; //设置摄像头的视频制式、帧格式等 /* 使用IOCTL命令VIDIOC_QUERYCAP,获取摄像头的基本信息*/ ret = ioctl(fd_cam, VIDIOC_QUERYCAP, &cam_cap); if (ret < 0) { perror("Can't get device information: VIDIOCGCAP"); } printf( "Driver Name:%s\nCard Name:%s\nBus info:%s\nDriver Version:%u.%u.%u\n", cam_cap.driver, cam_cap.card, cam_cap.bus_info, (cam_cap.version >> 16) & 0XFF, (cam_cap.version >> 8) & 0XFF, cam_cap.version & 0XFF); /* 使用IOCTL命令VIDIOC_ENUM_FMT,获取摄像头所有支持的格式*/ cam_fmtdesc.index = 0; cam_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; printf("Support format:\n"); while (ioctl(fd_cam, VIDIOC_ENUM_FMT, &cam_fmtdesc) != -1) { printf("\t%d.%s\n", cam_fmtdesc.index + 1, cam_fmtdesc.description); cam_fmtdesc.index++; } /* 使用IOCTL命令VIDIOC_CROPCAP,获取摄像头的捕捉能力*/ cam_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (0 == ioctl(fd_cam, VIDIOC_CROPCAP, &cam_cropcap)) { printf("Default rec:\n\tleft:%d\n\ttop:%d\n\twidth:%d\n\theight:%d\n", cam_cropcap.defrect.left, cam_cropcap.defrect.top, cam_cropcap.defrect.width, cam_cropcap.defrect.height); /* 使用IOCTL命令VIDIOC_S_CROP,获取摄像头的窗口取景参数*/ cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cam_crop.c = cam_cropcap.defrect; //默认取景窗口大小 if (-1 == ioctl(fd_cam, VIDIOC_S_CROP, &cam_crop)) { //printf("Can't set crop para\n"); } } else { printf("Can't set cropcap para\n"); } /* 使用IOCTL命令VIDIOC_S_FMT,设置摄像头帧信息*/ cam_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cam_format.fmt.pix.width = capW; cam_format.fmt.pix.height = capH; cam_format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; //要和摄像头支持的类型对应 cam_format.fmt.pix.field = V4L2_FIELD_INTERLACED; ret = ioctl(fd_cam, VIDIOC_S_FMT, &cam_format); if (ret < 0) { perror("Can't set frame information"); } /* 使用IOCTL命令VIDIOC_G_FMT,获取摄像头帧信息*/ cam_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd_cam, VIDIOC_G_FMT, &cam_format); if (ret < 0) { perror("Can't get frame information"); } printf("Current data format information:\n\twidth:%d\n\theight:%d\n", cam_format.fmt.pix.width, cam_format.fmt.pix.height); ret = initBuffers(); if (ret < 0) { perror("Buffers init error"); //exit(-1); } return 0; } int V4L2Capture::initBuffers() { int ret; /* 使用IOCTL命令VIDIOC_REQBUFS,申请帧缓冲*/ struct v4l2_requestbuffers req; CLEAR(req); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; ret = ioctl(fd_cam, VIDIOC_REQBUFS, &req); if (ret < 0) { perror("Request frame buffers failed"); } if (req.count < 2) { perror("Request frame buffers while insufficient buffer memory"); } buffers = (struct cam_buffer*) calloc(req.count, sizeof(*buffers)); if (!buffers) { perror("Out of memory"); } for (n_buffers = 0; n_buffers < req.count; n_buffers++) { struct v4l2_buffer buf; CLEAR(buf); // 查询序号为n_buffers 的缓冲区,得到其起始物理地址和大小 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; ret = ioctl(fd_cam, VIDIOC_QUERYBUF, &buf); if (ret < 0) { printf("VIDIOC_QUERYBUF %d failed\n", n_buffers); return -1; } buffers[n_buffers].length = buf.length; //printf("buf.length= %d\n",buf.length); // 映射内存 buffers[n_buffers].start = mmap( NULL, // start anywhere buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd_cam, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) { printf("mmap buffer%d failed\n", n_buffers); return -1; } } return 0; } int V4L2Capture::startCapture() { unsigned int i; for (i = 0; i < n_buffers; i++) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == ioctl(fd_cam, VIDIOC_QBUF, &buf)) { printf("VIDIOC_QBUF buffer%d failed\n", i); return -1; } } enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(fd_cam, VIDIOC_STREAMON, &type)) { printf("VIDIOC_STREAMON error"); return -1; } return 0; } int V4L2Capture::stopCapture() { enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(fd_cam, VIDIOC_STREAMOFF, &type)) { printf("VIDIOC_STREAMOFF error\n"); return -1; } return 0; }/*ok*/ int V4L2Capture::freeBuffers() { unsigned int i; for (i = 0; i < n_buffers; ++i) { if (-1 == munmap(buffers[i].start, buffers[i].length)) { printf("munmap buffer%d failed\n", i); return -1; } } free(buffers); return 0; } int V4L2Capture::getFrame(void **frame_buf, size_t* len) { struct v4l2_buffer queue_buf; CLEAR(queue_buf); queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; queue_buf.memory = V4L2_MEMORY_MMAP; if (-1 == ioctl(fd_cam, VIDIOC_DQBUF, &queue_buf)) { printf("VIDIOC_DQBUF error\n"); return -1; } *frame_buf = buffers[queue_buf.index].start; *len = buffers[queue_buf.index].length; frameIndex = queue_buf.index; return 0; } int V4L2Capture::backFrame() { if (frameIndex != -1) { struct v4l2_buffer queue_buf; CLEAR(queue_buf); queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; queue_buf.memory = V4L2_MEMORY_MMAP; queue_buf.index = frameIndex; if (-1 == ioctl(fd_cam, VIDIOC_QBUF, &queue_buf)) { printf("VIDIOC_QBUF error\n"); return -1; } return 0; } return -1; } void V4L2Capture::test() { unsigned char *yuv422frame = NULL; unsigned long yuvframeSize = 0; string videoDev="/dev/video0"; V4L2Capture *vcap = new V4L2Capture(const_cast(videoDev.c_str()), 1920, 1080); vcap->openDevice(); vcap->initDevice(); vcap->startCapture(); vcap->getFrame((void **) &yuv422frame, (size_t *)&yuvframeSize); vcap->backFrame(); vcap->freeBuffers(); vcap->closeDevice(); } void line2(Point point3[100000], int n) { float aa, bb, cc, dd, ee, ff, gg; int jj = 0; for (;jj


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有