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


相关推荐
正在走向自律6 分钟前
Python 数据分析与可视化:开启数据洞察之旅(5/10)
开发语言·人工智能·python·数据挖掘·数据分析
LuvMyLife7 分钟前
基于Win在VSCode部署运行OpenVINO模型
人工智能·深度学习·计算机视觉·openvino
fancy16616619 分钟前
力扣top100 矩阵置零
人工智能·算法·矩阵
gaosushexiangji24 分钟前
基于千眼狼高速摄像机与三色掩模的体三维粒子图像测速PIV技术
人工智能·数码相机·计算机视觉
moxiaoran575329 分钟前
uni-app学习笔记五-vue3响应式基础
笔记·学习·uni-app
元亓亓亓1 小时前
LeetCode热题100--240.搜索二维矩阵--中等
算法·leetcode·矩阵
中电金信1 小时前
重构金融数智化产业版图:中电金信“链主”之道
大数据·人工智能
奋斗者1号1 小时前
Docker 部署 - Crawl4AI 文档 (v0.5.x)
人工智能·爬虫·机器学习
说码解字1 小时前
ExoPlayer 如何实现音画同步
开发语言·学习·音视频
陈奕昆1 小时前
五、【LLaMA-Factory实战】模型部署与监控:从实验室到生产的全链路实践
开发语言·人工智能·python·llama·大模型微调