树莓派学习专题<8>:使用V4L2驱动获取摄像头数据--获取摄像头支持的分辨率

树莓派学习专题<8>:使用V4L2驱动获取摄像头数据--获取摄像头支持的分辨率

  • [1. 获取摄像头支持的分辨率](#1. 获取摄像头支持的分辨率)
  • [2. 代码分析](#2. 代码分析)
  • [3. 树莓派实测](#3. 树莓派实测)

1. 获取摄像头支持的分辨率

使用如下代码获取摄像头支持的输出分辨率。

c 复制代码
	struct v4l2_frmsizeenum stFrameSize ;
	/**********************************************
	 * other codes 
	 * ********************************************/
    stFrameSize.index        = 0 ;
    stFrameSize.pixel_format = V4L2_PIX_FMT_YUYV ;
    
    printf("--Frame resolution descriptor ----------------------------\n") ;
    
    while(-1 != ioctl(g_iFDVideo, VIDIOC_ENUM_FRAMESIZES, &stFrameSize))
    {
        printf("-- %d. %c%c%c%c ", 
               stFrameSize.index + 1, 
               (stFrameSize.pixel_format >>  0) & 0xff, 
               (stFrameSize.pixel_format >>  8) & 0xff, 
               (stFrameSize.pixel_format >> 16) & 0xff, 
               (stFrameSize.pixel_format >> 24) & 0xff) ;

        if(V4L2_FRMSIZE_TYPE_DISCRETE == stFrameSize.type)
        {
            printf("type : DISCRETE\n\t\t width : %d\n\t\t height : %d\n", 
                   stFrameSize.discrete.width, 
                   stFrameSize.discrete.height) ;
        }
        else if(V4L2_FRMSIZE_TYPE_CONTINUOUS == stFrameSize.type)
        {
            printf("type : CONTINUOUS\n") ;
        }
        else if(V4L2_FRMSIZE_TYPE_STEPWISE == stFrameSize.type)
        {
            printf("type : STEPWISE\n"
                   "\t\t min_width   : %d\n"
                   "\t\t max_width   : %d\n"
                   "\t\t step_width  : %d\n"
                   "\t\t min_height  : %d\n"
                   "\t\t max_height  : %d\n"
                   "\t\t step_height : %d\n", 
                   stFrameSize.stepwise.min_width,
                   stFrameSize.stepwise.max_width,
                   stFrameSize.stepwise.step_width,
                   stFrameSize.stepwise.min_height,
                   stFrameSize.stepwise.max_height,
                   stFrameSize.stepwise.step_height) ;
        }

        stFrameSize.index++ ;
    }
    
    printf("----------------------------------------------------------\n\n\n") ;

2. 代码分析

使用 VIDIOC_ENUM_FRAMESIZES 命令来获取摄像头支持的分辨率。该命令需要一个 struct v4l2_frmsizeenum 类型的参数。

该结构体的定义:

c 复制代码
	struct v4l2_frmsizeenum {
		__u32			index;		/* Frame size number */
		__u32			pixel_format;	/* Pixel format */
		__u32			type;		/* Frame size type the device supports. */
	
		union {					/* Frame size */
			struct v4l2_frmsize_discrete	discrete;
			struct v4l2_frmsize_stepwise	stepwise;
		};
	
		__u32   reserved[2];			/* Reserved space for future use */
	};
  1. index 为序号,从0开始指定。
  2. pixel_format 像素格式。根据前述的 VIDIOC_ENUM_FMT 命令获取到的摄像头支持的格式填写。例如 **V4L2_PIX_FMT_YUYV ** 。
  3. type 为摄像头像素支持的分辨率类型。其可能有3个取值:
c 复制代码
	enum v4l2_frmsizetypes {
		V4L2_FRMSIZE_TYPE_DISCRETE	= 1,
		V4L2_FRMSIZE_TYPE_CONTINUOUS	= 2,
		V4L2_FRMSIZE_TYPE_STEPWISE	= 3,
	};

如果是类型 V4L2_FRMSIZE_TYPE_DISCRETE ,则结构体 v4l2_frmsizeenum 中,联合体取 discrete 。说明该摄像头支持特定值的分辨率(特定的宽、高)。

如果是类型 V4L2_FRMSIZE_TYPE_STEPWISE ,则结构体 v4l2_frmsizeenum 中,联合体取 stepwise 。说明该摄像头支持一系列步进的分辨率。

大多数CIS(CMOS image sensor)都支持 stepwise ,即分辨率是可调的。因此如果接口是MIPI-CSI,估计大多数都是 stepwise 类型。如果是USB摄像头,摄像头内部带有主控,限制了分辨率,因此可能是 discrete 。此点纯属猜测。

  1. struct v4l2_frmsize_discrete 类型如下。此时摄像头支持特定宽高的分辨率。
c 复制代码
	struct v4l2_frmsize_discrete {
		__u32			width;		/* Frame width [pixel] */
		__u32			height;		/* Frame height [pixel] */
	};
  1. struct v4l2_frmsize_stepwise 类型如下。此时摄像头支持一定步进的分辨率。
c 复制代码
	struct v4l2_frmsize_stepwise {
		__u32			min_width;	/* Minimum frame width [pixel] */
		__u32			max_width;	/* Maximum frame width [pixel] */
		__u32			step_width;	/* Frame width step size [pixel] */
		__u32			min_height;	/* Minimum frame height [pixel] */
		__u32			max_height;	/* Maximum frame height [pixel] */
		__u32			step_height;	/* Frame height step size [pixel] */
	};

其中,:
min_width 为最小宽度,max_width 为最大宽度,step_width 为宽度步进值。
min_height 为最小高度,max_height 为最大高度,step_height 为高度步进值。

3. 树莓派实测

材料:

  1. Raspberry Pi 4B计算机;
  2. IMX219摄像头组件。
    运行上述代码,打印结果:
c 复制代码
--Frame resolution descriptor ----------------------------
-- 1. YUYV type : STEPWISE
		 min_width   : 32
		 max_width   : 3280
		 step_width  : 2
		 min_height  : 32
		 max_height  : 2464
		 step_height : 2
----------------------------------------------------------

可见,树莓派IMX219 摄像头,当输出格式指定为YUYV 时,输出宽度可在323280 之间,以2 为步进调节;输出高度可在322464 之间,以2为步进调节。

需要注意的是,指定不同的pixel_format 时,可能获取到不同的分辨率支持。


相关推荐
zl_vslam5 小时前
SLAM中的非线性优-3D图优化之绝对位姿SE3约束右扰动(十七)
人工智能·算法·计算机视觉·3d
光羽隹衡5 小时前
计算机视觉——Opencv(基础操作一)
人工智能·opencv·计算机视觉
玄微云5 小时前
当暖心服务遇见硬核AI:玄微子AI让孕产关怀更有温度
大数据·人工智能·科技·物联网·产康门店
Cestb0n5 小时前
某果app 加密校验算法逆向分析
python·算法·逆向安全
Warren2Lynch5 小时前
AI赋能企业架构:TOGAF智能建模新时代
人工智能·架构
机器学习之心5 小时前
MATLAB基于近红外光谱检测的菠萝含水率预测(多种预处理+PLS)
人工智能·算法·matlab·近红外光谱检测
张心独酌5 小时前
学习Rust:实现RESTful 任务管理 API(Todo API)
学习·rust·restful
sunxunyong5 小时前
openwork实测
人工智能
isNotNullX5 小时前
什么是可信数据空间?为什么可信数据空间是数据共享的关键?
大数据·人工智能·数据安全·数据空间
星爷AG I5 小时前
9-1 视觉通路(AGI基础理论)
人工智能·agi