调节UVC相机参数只需要六行代码

这里给出两种方案,第一种方案是调用了v4l2留给linux系统Terminal的接口,在qt中模拟对Terminal的操作。第二种方案是直接通过ioctl进行系统调用的方式对参数进行修改。

方案一:

uvc协议的设备在linux下支持v4l2,其预留了直接通过Terminal对camera参数进行调节的接口,其格式为:

v4l2-ctl -c + 需要调节的参数

我们也可以通过这个v4l2提供的接口查询该设备可调节的参数种类及其有效值范围

v4l2-ctl -d /dev/video0 --list-ctrls

因此,我们可以直接在Qt中模拟对Terminal的操作:在项目中包含Qt的QProcess类,通过以下函数可以直接向Terminal发送指令(该指令一般要求其参数不含中文或者空格)

int QProcess::execute(const QString &program, const QStringList &arguments)

使用方案一的实例:以调节对比度为例,该段代码为一个槽函数,通过拖拽滑块可以将uvc设备参数调节至当前值,并且将目前值显示到label
请添加图片描述

void  Dialog_camera_setting::slider_changed()
{
    contrast=ui->horizontalSlider->value();  //获取当前滑块值作为对比度数值
    ui->label->setText(QString::number(contrast));  //将该目前的对比度数值显示到label上
    std::string cmd="v4l2-ctl -c contrast="+std::to_string(contrast);   //构建一行Terminal指令
    const char*cmdc = cmd.c_str();
    QProcess::execute(cmdc);   //发送该指令至Terminal
    return;
}

方案二:

通过v4l2提供的ioctl进行系统调用,调节参数。
流程与linux中调用其他设备驱动完全相同,方法如下:

ioctl(fd, cmd, &set);

参数一:fd为该uvc设备描述符
参数二:调节设备参数的cmd为:VIDIOC_S_CTRL
参数三:set为一个v4l2_control类型的结构体,描述了要调节的参数类型及其目标值
该结构体定义如下:

struct v4l2_control {
__u32 id; //参数类型
__s32 value; //目标值
}

常见参数的__u32 id·分别为:

亮度( Brightness ):V4L2_CID_BRIGHTNESS
对比度(contrast):V4L2_CID_CONTRAST
饱和度( Saturation ):V4L2_CID_SATURATION
色调(Hue):V4L2_CID_HUE
清晰度(Sharpness):V4L2_CID_SHARPNESS
增益(Gain):V4L2_CID_GAIN
伽玛(Gamma):V4L2_CID_GAMMA
白平衡( White Balance):V4L2_CID_WHITE_BALANCE_TEMPERATURE
手动对焦(Focusing):V4L2_CID_FOCUS_ABSOLUTE

曝光值的设定较为不同,需要先设定为手动曝光,再设定曝光值

曝光(Exposure)//手动曝光
id = V4L2_CID_EXPOSURE_AUTO;
value = V4L2_EXPOSURE_MANUAL;
//设置曝光值
id = V4L2_CID_EXPOSURE_ABSOLUTE;

使用方案二的实例:以调节曝光为例,该段代码为一个槽函数,通过拖拽滑块可以将uvc设备参数调节至当前值,并且将目前值显示到label

void  Dialog_camera_setting::slider_3_changed()
{
    v4l2_control control1; //v4l2_control 结构体
    v4l2_control control2;
    exposure=ui->horizontalSlider->value(); //获取当前滑块值作为对比度数值
    ui->label->setText(QString::number(exposure)); //将该目前的对比度数值显示到label上
    control1.id=V4L2_CID_EXPOSURE_AUTO; //设定为手动曝光模式
    control1.value=V4L2_EXPOSURE_MANUAL;
    ioctl(fd, VIDIOC_S_CTRL, &control1);  //系统调用
    control2.id=V4L2_CID_EXPOSURE_ABSOLUTE; //设定具体曝光值
    control2.value=exposure;
    ioctl(fd, VIDIOC_S_CTRL, &control2); //系统调用
    return;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用libusb库打开UVC相机时,需要进行以下骤: 1. 初始化libusb库: ```cpp #include <libusb-1.0/libusb.h> int main() { libusb_context *ctx NULL; int r = libusb_init(&ctx); if (r < 0) { // 初始化失败 return r; } // 其他操作 libusb_exit(ctx); return 0; } ``` 2. 找到并打开UVC相机: ```cpp libusb_device **devs; libusb_device_handle *dev_handle; ssize_t cnt = libusb_get_device_list(ctx, &devs); if (cnt < 0) { // 获取设备列表失败 return cnt; } for (size_t i = 0; i < cnt; i++) { libusb_device *dev = devs[i]; struct libusb_device_descriptor desc; int r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { // 获取设备描述符失败 continue; } // 判断是否为UVC相机设备 if (desc.idVendor == UVC_VENDOR_ID && desc.idProduct == UVC_PRODUCT_ID) { // 打开设备 r = libusb_open(dev, &dev_handle); if (r < 0) { // 打开设备失败 continue; } // 其他操作 break; } } libusb_free_device_list(devs, 1); ``` 3. 设置UVC相机参数: ```cpp // 设置配置 int r = libusb_set_configuration(dev_handle, UVC_CONFIGURATION); if (r < 0) { // 设置配置失败 return r; } // 分配并设置接口 r = libusb_claim_interface(dev_handle, UVC_INTERFACE); if (r < 0) { // 设置接口失败 return r; } // 设置端点 libusb_endpoint_descriptor *ep_desc; r = libusb_get_endpoint_descriptor(dev_handle, UVC_ENDPOINT_IN, &ep_desc); if (r < 0) { // 获取端点描述符失败 return r; } // 其他操作 ``` 4. 控制UVC相机: ```cpp // 发送控制命令 unsigned char control_data[CONTROL_DATA_SIZE] = {0x00, 0x01, 0x02, ...}; int r = libusb_control_transfer(dev_handle, UVC_REQUEST_TYPE, UVC_REQUEST, UVC_VALUE, UVC_INDEX, control_data, CONTROL_DATA_SIZE, TIMEOUT); if (r < 0) { // 发送控制命令失败 return r; } // 其他操作 ``` 5. 关闭UVC相机和释放资源: ```cpp libusb_release_interface(dev_handle, UVC_INTERFACE); libusb_close(dev_handle); ``` 希望以上代码能够帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值