树莓派学习专题<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 时,可能获取到不同的分辨率支持。


相关推荐
YF云飞31 分钟前
数据仓库进化:Agent驱动数智化新范式
数据仓库·人工智能·ai
多打代码31 分钟前
2025.09.05 用队列实现栈 & 有效的括号 & 删除字符串中的所有相邻重复项
python·算法
悠哉悠哉愿意1 小时前
【数学建模学习笔记】机器学习分类:KNN分类
学习·机器学习·数学建模
ningmengjing_1 小时前
理解损失函数:机器学习的指南针与裁判
人工智能·深度学习·机器学习
四谎真好看1 小时前
Java 学习笔记(进阶篇2)
java·笔记·学习
程序猿炎义1 小时前
【NVIDIA AIQ】自定义函数实践
人工智能·python·学习
小陈phd1 小时前
高级RAG策略学习(四)——上下文窗口增强检索RAG
人工智能·学习·langchain
居然JuRan1 小时前
阿里云多模态大模型岗三面面经
人工智能
THMAIL1 小时前
深度学习从入门到精通 - BERT与预训练模型:NLP领域的核弹级技术详解
人工智能·python·深度学习·自然语言处理·性能优化·bert
nju_spy2 小时前
Kaggle - LLM Science Exam 大模型做科学选择题
人工智能·机器学习·大模型·rag·南京大学·gpu分布计算·wikipedia 维基百科