OpenCV中VideoCapture 设置和获取摄像头参数和Qt设计UI控制界面详解代码示例

OpenCV VideoCapture 设置和获取摄像头参数

使用 OpenCV 的 cv::VideoCapture 类可以方便地获取和设置摄像头参数,如分辨率、帧率、曝光、增益、对比度等。


一、常用摄像头参数列表(ID)

参数 枚举常量 说明
宽度 cv::CAP_PROP_FRAME_WIDTH 图像帧宽
高度 cv::CAP_PROP_FRAME_HEIGHT 图像帧高
帧率 cv::CAP_PROP_FPS 每秒帧数
曝光 cv::CAP_PROP_EXPOSURE 曝光值(设备依赖,单位不统一)
亮度 cv::CAP_PROP_BRIGHTNESS 亮度值
对比度 cv::CAP_PROP_CONTRAST 图像对比度
饱和度 cv::CAP_PROP_SATURATION 色彩饱和度
色调 cv::CAP_PROP_HUE 色调
增益 cv::CAP_PROP_GAIN 图像增益(有些设备不支持)
自动曝光模式 cv::CAP_PROP_AUTO_EXPOSURE 自动曝光控制
自动对焦开关 cv::CAP_PROP_AUTOFOCUS 是否启用自动对焦
手动对焦位置 cv::CAP_PROP_FOCUS 手动设置焦距
帧编号(读取视频时使用) cv::CAP_PROP_POS_FRAMES 当前帧号

二、获取和设置参数示例代码

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::VideoCapture cap(0); // 打开默认摄像头(通常是设备的第一个)

    if (!cap.isOpened()) {
        std::cerr << "无法打开摄像头!" << std::endl;
        return -1;
    }

    // 设置摄像头参数
    cap.set(cv::CAP_PROP_FRAME_WIDTH, 1280);
    cap.set(cv::CAP_PROP_FRAME_HEIGHT, 720);
    cap.set(cv::CAP_PROP_FPS, 30);
    cap.set(cv::CAP_PROP_AUTO_EXPOSURE, 0.25);  // 关闭自动曝光(Linux下通常为0.25表示手动模式)
    cap.set(cv::CAP_PROP_EXPOSURE, -6);         // 设置曝光值(设备相关,单位可能是对数)
    cap.set(cv::CAP_PROP_GAIN, 0);              // 设置增益
    cap.set(cv::CAP_PROP_AUTOFOCUS, 0);         // 关闭自动对焦
    cap.set(cv::CAP_PROP_FOCUS, 0);             // 手动设置焦距(若支持)

    // 获取并打印设置结果
    std::cout << "Frame width: " << cap.get(cv::CAP_PROP_FRAME_WIDTH) << std::endl;
    std::cout << "Frame height: " << cap.get(cv::CAP_PROP_FRAME_HEIGHT) << std::endl;
    std::cout << "FPS: " << cap.get(cv::CAP_PROP_FPS) << std::endl;
    std::cout << "Exposure: " << cap.get(cv::CAP_PROP_EXPOSURE) << std::endl;
    std::cout << "Gain: " << cap.get(cv::CAP_PROP_GAIN) << std::endl;
    std::cout << "Auto Focus: " << cap.get(cv::CAP_PROP_AUTOFOCUS) << std::endl;
    std::cout << "Focus: " << cap.get(cv::CAP_PROP_FOCUS) << std::endl;

    // 显示摄像头图像
    cv::Mat frame;
    while (true) {
        cap >> frame;
        if (frame.empty()) break;

        cv::imshow("Camera", frame);
        if (cv::waitKey(1) == 27) break; // 按 ESC 退出
    }

    cap.release();
    cv::destroyAllWindows();
    return 0;
}

三、注意事项

1. 参数支持与否依赖于摄像头驱动

  • 有些摄像头(如 UVC 摄像头)支持所有常见参数;
  • 但有些摄像头参数设置会被忽略或无效;
  • 建议设置后再用 .get(...) 验证。

2. Linux 下曝光设置的特殊值(UVC)

设置 含义
AUTO_EXPOSURE 0.75 自动模式(默认)
AUTO_EXPOSURE 0.25 手动曝光模式
EXPOSURE -6 ~ 0 曝光时间(对数单位)

四、枚举值查询与工具支持

也可以通过如下方式列出所有参数支持情况(仅在某些系统有效,如LINUX):

bash 复制代码
v4l2-ctl --device=/dev/video0 --list-ctrls

小结

  • 使用 cv::VideoCapture::set()get() 可以设置和查询常用参数;
  • 参数支持程度取决于摄像头驱动和 OpenCV 后端(如 V4L2 / DirectShow);
  • 实际应用中建议先设置后查询,确认参数生效;
  • 对于工业相机,建议用原厂 SDK 控制参数,OpenCV 用于抓帧显示。

Qt设计UI界面综合示例

下面是一个 使用 Qt + OpenCV 构建的完整Demo框架,支持:

  • 实时摄像头图像预览;
  • GUI 控制条动态调节参数(曝光、增益、亮度、对比度、分辨率等);
  • 设置后立即生效并反映在画面中;
  • 支持 OpenCV 的所有通用 VideoCapture 参数;
  • 可构建为 Qt Widget 应用,适合工业相机控制/调试场景。

一、功能结构总览

复制代码
CamControlGUI/
├── CMakeLists.txt
├── main.cpp
├── CameraControlWidget.h / .cpp
├── CameraControlWidget.ui
└── include / lib / build ...

二、关键模块代码

1. main.cpp

cpp 复制代码
#include <QApplication>
#include "CameraControlWidget.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    CameraControlWidget w;
    w.show();
    return a.exec();
}

2. CameraControlWidget.h

cpp 复制代码
#pragma once

#include <QWidget>
#include <QTimer>
#include <QImage>
#include <opencv2/opencv.hpp>

QT_BEGIN_NAMESPACE
namespace Ui { class CameraControlWidget; }
QT_END_NAMESPACE

class CameraControlWidget : public QWidget {
    Q_OBJECT

public:
    explicit CameraControlWidget(QWidget *parent = nullptr);
    ~CameraControlWidget();

private slots:
    void updateFrame();
    void onExposureChanged(int value);
    void onGainChanged(int value);
    void onBrightnessChanged(int value);
    void onContrastChanged(int value);

private:
    Ui::CameraControlWidget *ui;
    cv::VideoCapture cap;
    QTimer *timer;

    void setupCamera();
    void updateCameraParams();
    QImage matToQImage(const cv::Mat &mat);
};

3. CameraControlWidget.cpp

cpp 复制代码
#include "CameraControlWidget.h"
#include "ui_CameraControlWidget.h"

CameraControlWidget::CameraControlWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::CameraControlWidget), timer(new QTimer(this)) {
    ui->setupUi(this);

    setupCamera();

    connect(timer, &QTimer::timeout, this, &CameraControlWidget::updateFrame);
    connect(ui->sliderExposure, &QSlider::valueChanged, this, &CameraControlWidget::onExposureChanged);
    connect(ui->sliderGain, &QSlider::valueChanged, this, &CameraControlWidget::onGainChanged);
    connect(ui->sliderBrightness, &QSlider::valueChanged, this, &CameraControlWidget::onBrightnessChanged);
    connect(ui->sliderContrast, &QSlider::valueChanged, this, &CameraControlWidget::onContrastChanged);

    timer->start(30); // ~30 FPS
}

CameraControlWidget::~CameraControlWidget() {
    cap.release();
    delete ui;
}

void CameraControlWidget::setupCamera() {
    cap.open(0); // 默认摄像头
    cap.set(cv::CAP_PROP_FRAME_WIDTH, 1280);
    cap.set(cv::CAP_PROP_FRAME_HEIGHT, 720);
    cap.set(cv::CAP_PROP_AUTO_EXPOSURE, 0.25); // 手动曝光模式
    cap.set(cv::CAP_PROP_AUTOFOCUS, 0);        // 禁用自动对焦
}

void CameraControlWidget::updateFrame() {
    cv::Mat frame;
    cap >> frame;
    if (!frame.empty()) {
        QImage image = matToQImage(frame);
        ui->labelPreview->setPixmap(QPixmap::fromImage(image).scaled(
            ui->labelPreview->size(), Qt::KeepAspectRatio));
    }
}

QImage CameraControlWidget::matToQImage(const cv::Mat &mat) {
    if (mat.channels() == 3)
        return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_BGR888).copy();
    else
        return QImage();
}

void CameraControlWidget::onExposureChanged(int value) {
    double exposure = static_cast<double>(value) / 10.0; // 映射范围
    cap.set(cv::CAP_PROP_EXPOSURE, exposure);
    ui->labelExposureValue->setText(QString::number(exposure));
}

void CameraControlWidget::onGainChanged(int value) {
    cap.set(cv::CAP_PROP_GAIN, value);
    ui->labelGainValue->setText(QString::number(value));
}

void CameraControlWidget::onBrightnessChanged(int value) {
    cap.set(cv::CAP_PROP_BRIGHTNESS, value);
    ui->labelBrightnessValue->setText(QString::number(value));
}

void CameraControlWidget::onContrastChanged(int value) {
    cap.set(cv::CAP_PROP_CONTRAST, value);
    ui->labelContrastValue->setText(QString::number(value));
}

4. CameraControlWidget.ui(建议用 Qt Designer 拖拽方式在设计UI)

  • QLabel:显示摄像头画面 → labelPreview
  • QSlider + QLabel:用于曝光、增益、亮度、对比度调节 → 对应命名如 sliderExposure, labelExposureValue
  • 水平布局或网格布局组织即可

三、CMakeLists.txt 参考内容,大家可以根据自己环境配置

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(CamControlGUI)

set(CMAKE_CXX_STANDARD 17)

find_package(OpenCV REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Widgets)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(CamControlGUI
    main.cpp
    CameraControlWidget.cpp
    CameraControlWidget.h
    CameraControlWidget.ui
)

target_link_libraries(CamControlGUI
    ${OpenCV_LIBS}
    Qt5::Widgets
)

四、构建和运行

bash 复制代码
mkdir build && cd build
cmake ..
make -j
./CamControlGUI

五、可拓展功能建议

功能 实现方式
保存当前参数配置 使用 QSettings 读写配置文件
支持多个摄像头切换 提供下拉菜单选择不同 ID
显示当前参数值 在滑块旁增加 QLabel 实时显示
图像直方图 / ROI 块分析 使用 OpenCV 绘图工具或嵌入 Matplotlib plot
支持工业相机 SDK(如 Daheng, Hikvision) 封装原生 API 替换 VideoCapture