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


相关推荐
姚家湾几秒前
闲聊人工智能对媒体的影响
人工智能·媒体
程序员安仔7 分钟前
Trae 新版发布!除了支持联网搜索、 MCP 外,还能创建智能体!
人工智能·trae
天天扭码8 分钟前
一分钟解决 | 高频面试算法题——滑动窗口最大值(单调队列)
前端·算法·面试
新智元13 分钟前
Transformer 原作打脸 DeepSeek 观点?一句 Wait 就能引发反思,RL 都不用
人工智能·openai
timer_01727 分钟前
百度 Al 智能体心响 App 上线
人工智能
tan77º30 分钟前
【算法】BFS-解决FloodFill问题
算法·leetcode·宽度优先
Clocky730 分钟前
图像预处理-绘制图像轮廓与凸包
人工智能·计算机视觉
Java中文社群30 分钟前
聊聊SpringAI流式输出的底层实现?
java·人工智能·后端
知识烤冷面31 分钟前
【力扣刷题实战】找到字符串中所有字母异位词
数据结构·算法·leetcode
奋斗者1号35 分钟前
机器学习超参数优化全解析
人工智能·机器学习