这里给出两种方案,第一种方案是调用了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;
}
文章评论