树莓派学习专题<8>:使用V4L2驱动获取摄像头数据--获取摄像头支持的分辨率
树莓派学习专题<8>:使用V4L2驱动获取摄像头数据--获取摄像头支持的分辨率
- 1. 获取摄像头支持的分辨率
- 2. 代码分析
- 3. 树莓派实测
1. 获取摄像头支持的分辨率
使用如下代码获取摄像头支持的输出分辨率。
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 类型的参数。
该结构体的定义:
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 */};
- index 为序号,从0开始指定。
- pixel_format 像素格式。根据前述的 VIDIOC_ENUM_FMT 命令获取到的摄像头支持的格式填写。例如 **V4L2_PIX_FMT_YUYV ** 。
- type 为摄像头像素支持的分辨率类型。其可能有3个取值:
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 。此点纯属猜测。
- struct v4l2_frmsize_discrete 类型如下。此时摄像头支持特定宽高的分辨率。
struct v4l2_frmsize_discrete {__u32 width; /* Frame width [pixel] */__u32 height; /* Frame height [pixel] */};
- struct v4l2_frmsize_stepwise 类型如下。此时摄像头支持一定步进的分辨率。
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. 树莓派实测
材料:
- Raspberry Pi 4B计算机;
- IMX219摄像头组件。
运行上述代码,打印结果:
--Frame resolution descriptor ----------------------------
-- 1. YUYV type : STEPWISEmin_width : 32max_width : 3280step_width : 2min_height : 32max_height : 2464step_height : 2
----------------------------------------------------------
可见,树莓派IMX219摄像头,当输出格式指定为YUYV时,输出宽度可在32到3280之间,以2为步进调节;输出高度可在32至2464之间,以2为步进调节。
需要注意的是,指定不同的pixel_format 时,可能获取到不同的分辨率支持。