Ubuntu系统下控制usb摄像头的参数

背景:

在工业检测中,按照检测的性质,可以分为定量的测量和定性的判断。在定量测量领域,一般使用高分辨的工业摄像头,并配备低畸变的镜头。对于运动目标的测量,还需要配合光源,编码器等实现高质量目标图片的获取。比如产品加工精度测量等。在定性的判断领域,不需要精确的测量,判断结论只有少数几个分类。比如在加工领域,判断某个零件是否装配好,判断特定区域颜色是否和要求相同等。在这种情况下,不需要使用高精度的工业相机,一般常用的USB2.0相机可以完成这一任务。
本文的背景是要完成一个接线端子上线头是否插接到位的判断。
在这里插入图片描述

只需要判断线头是否被插到指定位置,所以这是一个定性的工业检测问题。

如果想要进行工业检测,必须对usb相机的参数进行控制。笔者原来在windows下实现了用FFmpeg库读取usb摄像头,(https://blog.csdn.net/iamqianrenzhan/article/details/84830277) 但是这个库不支持usb摄像头的参数控制。后来查到要实现参数控制,需要使用windows下的VFW,DircetShow或者MediaFoundation库。但是考虑到微软的库学习成本较高,在windows下使用opencv进行摄像头参数的控制。在Ubuntu下,可以使用V4L2库进行摄像头参数的控制。

本文要介绍的就是如何在Ubuntu系统下控制usb摄像头的参数。

实现

总共4个函数,分别是打开相机,打印相机参数,获取相机信息,设置相机参数。

int fd = v4l2cameraopen(&cap);
printcamerapara(fd);
get_v4l2_info(fd);
set_v4l2_para(fd);

打开相机

int v4l2cameraopen(struct v4l2_capability *cap)
{
    //struct v4l2_capability newcap;
    int fd=-1;
    int rel=-1;
    fd= open("/dev/video0",O_RDWR,0);
    if(fd==-1)
    {
        perror("fd");
        exit(EXIT_FAILURE);
    }
    rel= ioctl(fd,VIDIOC_QUERYCAP,cap);
    if(rel==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }

    printf("*********************Querycap Success**************************\n");

    if(cap->capabilities & V4L2_CAP_VIDEO_CAPTURE)
        printf("*****************capture is on*****************************\n");

    if(cap->capabilities & V4L2_CAP_STREAMING)
        printf("*****************Stream is on******************************\n");

    printf("\n");
    printf("\n");
    printf("*************************Capabilities**************************\n");
    printf(">:[Driver:%s]\n>:[card:%s]\n>:[bus_info:%s]\n>:[version:%d]\n",
           cap->driver,cap->card,cap->bus_info,cap->version);
    printf("**************************************************************\n");
    printf("\n");
    printf("\n");

    return fd;
}

打印相机参数

void printcamerapara(int fd)
{
    int i = 0;
    struct v4l2_queryctrl qctrl;
    struct v4l2_control ctrl;
    for(i=V4L2_CID_BASE;i<V4L2_CID_LASTP1;i++)
    {
        qctrl.id=i;
        if(ioctl(fd,VIDIOC_QUERYCTRL,&qctrl)==0)
        {
            ctrl.id=qctrl.id;
            if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)<0)
                perror("**********************get ctrl failed**************\n");
            printf(">:[name:%s]\t[id:%08x]\n",qctrl.name,qctrl.id);
            printf(">:[type:%d]\n",qctrl.type);
            printf(">:[min:%d]\t[max:%d]\n",qctrl.minimum,qctrl.maximum);
            printf(">:[value:%d]\t[stp:%d]\n",ctrl.value,qctrl.step);
            printf(">:[default_value:%d]\n",qctrl.default_value);
            printf("\n");
        }
    }

    printf("------------------------------------------------------------------\n");

    for(i=V4L2_CID_CAMERA_CLASS_BASE;i<V4L2_CID_CAMERA_CLASS_BASE+32;i++)
    {
        qctrl.id=i;
        if(ioctl(fd,VIDIOC_QUERYCTRL,&qctrl)==0)
        {
            ctrl.id=qctrl.id;
            if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)<0)
                perror("**********************get ctrl failed**************\n");
            printf(">:[name:%s]\t[id:%08x]\n",qctrl.name,qctrl.id);
            printf(">:[type:%d]\n",qctrl.type);
            printf(">:[min:%d]\t[max:%d]\n",qctrl.minimum,qctrl.maximum);
            printf(">:[value:%d]\t[stp:%d]\n",ctrl.value,qctrl.step);
            printf(">:[default_value:%d]\n",qctrl.default_value);
            printf("\n");
        }
    }

    printf("------------------------------------------------------------------\n");
}

得到相机信息:

void get_v4l2_info(int fd)
{
    struct v4l2_format Format;
    printf("************************Get format info********************************\n");
    Format.type= V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if(ioctl(fd,VIDIOC_G_FMT,&Format)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[width:%d]\t[pixelformat:%d]\n",Format.fmt.pix.width,Format.fmt.pix.height);
    printf(">:[format:%d]\t[field:%d]\n",Format.fmt.pix.pixelformat,Format.fmt.pix.field);
    printf(">:[bytesperline:%d]\t[sizeimage:%d]\n",Format.fmt.pix.bytesperline,Format.fmt.pix.sizeimage);
    printf(">:[colorspace:%d]\n",Format.fmt.pix.colorspace);
    printf("***********************************************************************\n");
    printf("\n");

    printf("************************Get Stream_Parm********************************\n");
    struct v4l2_streamparm Stream_Parm;
    Stream_Parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if(ioctl(fd,VIDIOC_G_PARM,&Stream_Parm)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[Frame rate:%u] [%u]\n",Stream_Parm.parm.capture.timeperframe.numerator,Stream_Parm.parm.capture.timeperframe.denominator);
    printf(">:[capability:%d] [capturemode:%d]\n",Stream_Parm.parm.capture.capability,Stream_Parm.parm.capture.capturemode);
    printf(">:[extendemode:%d] [readbuffers:%d]\n",Stream_Parm.parm.capture.extendedmode,Stream_Parm.parm.capture.readbuffers);
    printf("***********************************************************************\n");
    printf("\n");

    struct v4l2_control ctrl;
    ctrl.id=V4L2_CID_EXPOSURE_AUTO;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:Get Exposure Auto:[%d]\n",ctrl.value);

    ctrl.id=V4L2_CID_EXPOSURE_ABSOLUTE;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:Get Exposure Absolute:[%d]\n",ctrl.value);

    ctrl.id=V4L2_CID_EXPOSURE_AUTO_PRIORITY;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[Get Exposure Auto Priority:%d] \n",ctrl.value);

    ctrl.id=V4L2_CID_AUTO_WHITE_BALANCE;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[Get white balance auto value:%d] \n",ctrl.value);

    ctrl.id=V4L2_CID_WHITE_BALANCE_TEMPERATURE;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[Get white balance value:%d] \n",ctrl.value);

    ctrl.id=V4L2_CID_BRIGHTNESS;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[Get brightness value:%d] \n",ctrl.value);

    ctrl.id=V4L2_CID_CONTRAST;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[Get contrast value:%d] \n",ctrl.value);

    ctrl.id=V4L2_CID_SATURATION;
    if(ioctl(fd,VIDIOC_G_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    printf(">:[Get saturation value:%d] \n",ctrl.value);

}

设置相机参数:

void set_v4l2_para(int fd)
{
    struct v4l2_control ctrl;
    printf("Set white balance Temperature Auto……………………\n");
    ctrl.id=V4L2_CID_AUTO_WHITE_BALANCE;
    ctrl.value=0;   //value   0 manual  1 auto
    if(ioctl(fd,VIDIOC_S_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    sleep(1);
    printf("done\n");

    printf("Set white balance Temperature……………………\n");
    ctrl.id=V4L2_CID_WHITE_BALANCE_TEMPERATURE;
    ctrl.value=4000;  //value
    if(ioctl(fd,VIDIOC_S_CTRL,&ctrl)==-1)
    {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    sleep(1);
    printf("done2\n");

    printf("Set Exposure Auto ………………\n");
    ctrl.id=V4L2_CID_EXPOSURE_AUTO;
    ctrl.value=1;   //1 manual
    if(ioctl(fd,VIDIOC_S_CTRL,&ctrl)==-1)
    {
        printf("failed\n");
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    sleep(1);
    printf("done3\n");

    printf("Set Exposure Absolute ………………\n");
    ctrl.id = V4L2_CID_EXPOSURE_ABSOLUTE;
    ctrl.value = 100;   //4
    if(ioctl(fd,VIDIOC_S_CTRL,&ctrl)==-1)
    {
        printf("failed\n");
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    sleep(1);
    printf("done4\n");
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仟人斩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值