树莓派学习专题<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 时,输出宽度可在32 到3280 之间,以2 为步进调节;输出高度可在32 至2464 之间,以2为步进调节。

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


相关推荐
小陈phd4 分钟前
深入理解agent学习笔记(十一)——用户记忆系统
笔记·学习
伯奥克客服5 分钟前
AI视频过滤器工程选型指南:接口、离线推理与联动控制
人工智能·音视频
落樱弥城5 分钟前
FlashAttention 完全解析:从 Roofline 诊断到 CUDA 实现
人工智能·算法
无心水6 分钟前
8、系统架构设计基础知识 核心考点与学习笔记
笔记·学习·系统架构·架构师·软考·软考架构师·软考高级架构师
JJJennie7777 分钟前
大模型网关部署方案?MAI Gateway从部署到上线全流程
人工智能·gateway·ai网关
隔窗听雨眠7 分钟前
从行为引导到基础设施约束:AGI代理风险缓解的工程化路径
网络·人工智能·agi
tellmewhoisi9 分钟前
深度学习21:PyTorch:激活函数(Sigmoid,Tanh,ReLU,Softmax)
人工智能·pytorch·深度学习
ahccqw9 分钟前
Opencv 基础常用API
人工智能·opencv·计算机视觉
FelixZhang02814 分钟前
不懂金融或不会编程,如何开始量化?从策略搭建到回测验证
人工智能·python·算法·数学建模·均值算法·自然语言处理·金融
可乐ea15 分钟前
Kimi K3.1 Pro 选型:1M 上下文和每任务成本怎么算
人工智能·计算机视觉·ai智能体·上下文窗口·大模型选型·kimik3.1pro·agent成本