个人技术分享

文章目录

一、V4L2应用开发

1、识别摄像头

(1)开发过程中的第一步要先确定硬件是否正常工作,方便进行后续开发。
插入USB摄像头,查看摄像头是否生成,注意会生成2个设备,其中一个可以捕获图像。至于为什么会有2个,自行百度了解。

ls -l /dev/video*

请添加图片描述
(2)查看USB摄像头的设备ID

lsusb

请添加图片描述
(3)通过ID号 查看设备厂商等信息

sudo cat /sys/kernel/debug/usb/devices |grep 1908 -A 5

请添加图片描述
(4)下载v4l2-utils工具,v4l2-utils 是一个包含一系列与 Video4Linux2 (V4L2) 框架相关的实用程序和库的集合。它们的作用是帮助开发者、系统管理员和用户进行 V4L2 设备的管理、测试、配置和诊断。

sudo apt install v4l2-utils

主要用到的是v4l2-ctl指令,可以查看指令帮助集

v4l2-ctl -h

请添加图片描述
通过v4l2工具,查看摄像头 参数

v4l2-ctl -d  /dev/video0 --all

(5)安装guvcview工具,进行视频显示,实现件监控效果

sudo apt-get install guvcview

开始视频显示,设备节点是video0 还是video1需要都尝试下,错误的节点会直接报弹窗报错

guvcview -d /dev/video1 

弹窗报错图如下,需要重新切换正确节点
请添加图片描述
视频采集出现如下错误,解决方法

V4L2_CORE: Could not grab image (select timeout): Resource temporarily unavailable

虚拟机–>设置–>usb控制器—>usb兼容性,选择3.0以上即可

显示结果如下请添加图片描述
视频显示工具2,可自行安装测试

sudo apt-get install cheese
cheese -d /dev/video1  
2、查看摄像头设备的能力

现给出部分源码,后续会给出整个源码
结构体:struct v4l2_capability
内核源码路径include\uapi\linux\videodev2.h
请添加图片描述

/* Values for 'capabilities' field */
#define V4L2_CAP_VIDEO_CAPTURE		0x00000001  /* Is a video capture device */
#define V4L2_CAP_STREAMING              0x04000000  /* streaming I/O ioctls */
#define V4L2_CAP_READWRITE              0x01000000  /* read/write systemcalls */
/*查看 摄像头设备的能力*/	
int get_capability(int fd){
   
	int ret=0;
	struct v4l2_capability cap;	
	
	memset(&cap, 0, sizeof(struct v4l2_capability)); 
	
	ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);  /*查看设备能力信息*/
	if (ret < 0) {
   
	    printf("VIDIOC_QUERYCAP failed (%d)\n", ret);
	    return ret;
	}
	printf("Driver Info: \n  Driver Name:%s \n  Card Name:%s \n  Bus info:%s \n",cap.driver,cap.card,cap.bus_info);
	printf("Device capabilities: \n"); 	
	if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
    /*支持视频捕获(截取一帧图像保存)*/
	  printf("  support video capture \n");
	}

	if (cap.capabilities & V4L2_CAP_STREAMING) {
    /*支持视频流操作(mmap映射到同一缓冲区队列后的入队出队 即流入流出)*/
	  printf("  support streaming i/o\n");
	}

	if(cap.capabilities & V4L2_CAP_READWRITE) {
    /*支持读写(需内核到应用空间拷贝 慢)*/
	  printf("  support read i/o\n");
	}
	return ret;
}

编译后输出,如果需要放到开发板上,需使用交叉编译工具链
请添加图片描述

3、查看支持视频格式

结构体:struct v4l2_fmtdesc
请添加图片描述

int get_suppurt_video_format(int fd){
   
	int ret=0;
	struct v4l2_fmtdesc fmtdesc;
	
	printf("List device support video format:  \n");
	
	memset(&fmtdesc, 0, sizeof(fmtdesc));
	fmtdesc.index = 0;
	fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	while ((ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0) 	/*枚举出支持的视频格式*/
	{
   
		fmtdesc.index++;
		printf("  { pixelformat = ''%c%c%c%c'', description = ''%s'' }\n",
		          fmtdesc.pixelformat & 0xFF, (fmtdesc.pixelformat >> 8) & 0xFF, (fmtdesc.pixelformat >> 16) & 0xFF, 
		          (fmtdesc.pixelformat >> 24) & 0xFF, fmtdesc.description);
	}		
    return ret;
}

请添加图片描述

4、设置视频格式

结构体:v4l2_formatv4l2_pix_format
请添加图片描述
请添加图片描述

#define VIDEO_WIDTH  320  //采集图像的宽度
#define VIDEO_HEIGHT 240  //采集图像的高度	

nt set_video_format(int fd){
   	
	int ret = 0;
	struct v4l2_format fmt;
	
	memset(&fmt, 0, sizeof(fmt));
	fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	fmt.fmt.pix.width       = VIDEO_WIDTH; 
	fmt.fmt.pix.height      = VIDEO_HEIGHT;
	fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; /*支持mipg的摄像头最好*/
                                                 /*普通摄像头会默认设置V4L2_PIX_FMT_YUYV格式 要用到jpeg库*/
	fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;		/*视频帧的扫描方式*/

	/*设置视频格式	*/
	ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
	if (ret < 0