Linux 下V4l2摄像头采集图片,实现yuyv转RGB,RGB转BMP,RGB伸缩,jpeglib 库实现压缩RGB到内存中,JPEG经UDP发送功

本文介绍了在Linux环境下使用V4l2库进行摄像头图像采集的完整流程,包括驱动支持、摄像头操作步骤,如打开设备、设置图片格式、YUYV转RGB、RGB转BMP、RGB缩放及JPEG压缩。通过JPEGlib库将RGB图像压缩到内存,并利用UDP发送JPEG数据。
摘要由CSDN通过智能技术生成

    最近自己所在小组做了一个智能家居系统,本人主要负责摄像头图像采集部分,需要完成的功能是实现摄像头数据采集,而且图片需要在LCD上显示,需要经过网络远程发送,自己小白一个,做之前什么都不懂,经历各种查资料请教过后总算出效果了,感触颇深。这期间CSDN上各位大神的各种博客对自己帮助很大,在此一并谢过!!!!!同时也发现很多博客都只包含一个小部分,感觉如果有一个篇完整的介绍可能对新手会有帮助,因此在此简单介绍摄像头采集整个流程。第一次发博客,恳请各位大神多多指教,如有不妥之处,还请见谅。

    废话少说,直接进正题。首先要说明的是我们的摄像头是在ARM Cortex-A8要下运行的,出来的图像结果与PC机上会有一定的不同,请各位注意。

1、驱动支持

    在那位法国牙医的无私奉献下,Linux内核几乎支持所有的USB摄像头,不过要想自己的Linux内核支持USB免驱摄像头,还需要先配置内核,

Device Drivers  --->
  <*> Multimedia support  --->
 
<*>   Video For Linux
 
[ ]   Enable Video For Linux API 1 (DEPRECATED)
  [*]   Video capture adapters  ---> 
      [*]   V4L USB devices  ---> 
     
<*>   USB Video Class (UVC) 
  [*]     UVC input events device support

    这样在板子上插入摄像头后终端就会有显示:

[root@farsight /]# usb 1-1.1: new full speed USB device using s3c2410-ohci and a ddress 4
uvcvideo: Found UVC 1.00 device Webcam C110 (046d:0829)
input: Webcam C110 as /class/input/input2

    同时输入命令:lsusb 也会有相应信息,在此不就不详细展开了,网上有很多资料。最主要的是此时进入/dev 目录下,ls 会新增加一个设备,我的是video0,不同情况下需自己确认,这个设备名很重要。至此,Linux内核对摄像头的驱动支持就没问题了。


2、开始操作摄像头

    经典操作v4l2的方法一共也就那么步,大致为:打开设备->查看设备功能->设置图片格式->申请帧缓冲->内存映射->帧缓冲入列->开始采集->读数据(包括处理数据)->帧缓冲重新入列->关闭设备。看着名字挺霸气的,其实每一步都是调用内核驱动提供的出来的接口就可以了。

2.1 打开设备

    fd = open(dev_name, O_RDWR, 0 );//打开设备文件,阻塞模式
    if (fd < 0){
        perror("open /dev/video0  fialed! ");
        return -1;
    }

打开一个open就OK了,注意此处用的是阻塞模式,如果是非阻塞模式O_NONBLOCK的话,即使摄像头尚未捕获到信息,驱动依旧会把缓存(DQBUFF)里的东西返回给应用程序,感觉这样有点不合理,也懂内核为何要这样设计。

2.2  查看设备功能

<span style="font-size:14px;">struct v4l2_capability cap;
	ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);//查看设备功能
	if (ret < 0){
		perror("requre VIDIOC_QUERYCAP fialed! \n");
		return -1;
	}
	printf("driver:\t\t%s\n",cap.driver);
    printf("card:\t\t%s\n",cap.card);
    printf("bus_info:\t%s\n",cap.bus_info);
    printf("version:\t%d\n",cap.version);
    printf("capabilities:\t%x\n",cap.capabilities);
			
    if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE){
		printf("Device %s: supports capture.\n",dev_name);
	}
	if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING){
		printf("Device %s: supports streaming.\n",dev_name);
	}</span>

         查看设备功能也没什么好说的,看代码就OK啦。

2.3  设置图片格式

struct v4l2_format fmt;
	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	fmt.fmt.pix.width = WIDTH;
	fmt.fmt.pix.height = HEIGHT;
	fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
	fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
	if(-1 == ioctl(fd, VIDIOC_S_FMT, &fmt)){//设置图片格式
		perror("set format failed!");
		return -1;
	}
	if(-1 == ioctl(fd, VIDIOC_G_FMT, &fmt)){//得到图片格式
		perror("set format failed!");
		return -1;
	}

	printf("fmt.type:\t\t%d\n",fmt.type);
	printf("pix.pixelformat:\t%c%c%c%c\n", \
			fmt.fmt.pix.pixelformat & 0xFF,\
			(fmt.fmt.pix.pixelformat >> 8) & 0xFF, \
			(fmt.fmt.pix.pixelformat >> 16) & 0xFF,\
			(fmt.fmt.pix.pixelformat >> 24) & 0xFF);
	printf("pix.width:\t\t%d\n",fmt.fmt.pix.width);
	printf("pix.height:\t\t%d\n",fmt.fmt.pix.height);
	printf("pix.field:\t\t%d\n",fmt.fmt.pix.field);

      也是一个命令就完成:VIDIOC_S_FMT,其中WIDTH,HEGHT 是定义的宏,后面很多地方都要用这两个参数,定义成宏比传参方便。V4L2_PIX_FMT_YUYV 指定输出格式为YUYV,关于YUYV,RGB等等什么什么格式,网上也有很详细的介绍,比如这篇

  • 11
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: v4l2是一个用于视频采集和输出设备的Linux内核模块,它提供了一些基本的对视频设备进行控制和操作的能。其yuyv是一种视频格式,它采用了压缩而不是无损的方式来编码视频。 在v4l2,我们可以通过以下步骤来进行yuyv的无损换为bmp格式: 1. 打开视频设备:使用v4l2函数打开视频设备文件,例如/dev/video0。 2. 查询和设置视频设备参数:使用v4l2函数获取并设置视频设备的参数,包括帧大小、格式等。在这个步骤,我们需要设置yuyv作为输入格式。 3. 请求帧缓冲:使用v4l2函数向视频设备请求一块内存作为帧缓冲区,用于存储采集到的视频帧数据。 4. 启动视频流:使用v4l2函数启动视频流,开始采集视频帧数据。 5. 采集视频帧:使用v4l2函数从视频设备读取采集到的视频帧数据,并将其存储在帧缓冲区。 6. 将yuyv格式换为bmp格式:对于每一帧的数据,我们可以根据yuyv的编码规则,进行逐像素的解码。然后,将解码后的RGB像素数据存储在一个新的缓冲区。 7. 将RGB数据写入bmp文件:使用标准C函数,我们可以将RGB像素数据以bmp格式的形式写入一个新的file.bmp文件。 8. 停止视频流和释放资源:使用v4l2函数停止视频流,释放请求的帧缓冲区,关闭视频设备文件。 通过以上步骤,便可以实现v4l2的yuyv无损换为bmp格式的能。 ### 回答2: v4l2是Linux系统用于视频设备的驱动程序框架,支持多种不同的视频格式。其yuyv是一种常见的视频格式,也被称为YUV422。 YUYV是一种压缩格式,其每个像素占据16位(2个字节)的空间。这个格式使用了颜色子采样技术,即每两个像素共享一组颜色样本。这种格式在保留一定图像质量的同时,减少了存储和传输数据的大小。 要将YUYV格式的视频数据无损换为BMP格式的图像,需要以下步骤: 1. 从视频设备获取YUYV格式的原始视频数据。 2. 解压缩YUYV数据,将每个像素的Y、U、V分量分开。其,Y是亮度分量,U、V是色度分量。 3. 根据BMP格式的要求,将YUV分量换为RGB分量。这个过程通常使用色彩空间换算法,如YUV到RGB的矩阵运算。 4. 将RGB分量组装为BMP图像的像素数据,按照BMP文件格式的要求进行排列和存储。 5. 将像素数据保存为BMP格式的文件,以便后续使用或显示。 无损换意味着换后的BMP图像将保持与原始YUYV数据相同的色彩和图像质量。 需要注意的是,以上步骤的具体实现可能因不同的编程语言、和平台而有所差异。可以使用像OpenCV这样的开源图像处理来进行YUYVBMP换操作。通过使用适当的API和函数,可以在编程实现这种无损换过程。 ### 回答3: V4L2是视频4 Linux 2的缩写,是一个用于Linux系统的视频设备驱动程序接口。YUYV是一种被广泛用作视频流格式的压缩格式,它将颜色信息和亮度信息进行压缩,从而可以更高效地传输和存储。 要将V4L2的YUYV无损换为BMP格式,我们需要了解YUYVBMP的格式和数据结构。 首先,V4L2驱动程序会将图像从摄像头读取并以YUYV格式存储。YUYV格式使用4个字节来存储2个像素的数据。每个像素由一个Y(亮度)值和一对U和V(颜色差值)值组成。 接下来,我们需要将YUYV格式的数据解码并换为BMP格式。在这个换过程,我们需要考虑颜色空间的换和像素排列顺序的调整。 首先,我们将YUYV数据的每个像素解码并计算出RGB值。这个过程涉及到颜色空间的换,需要用到YUV到RGB换公式。 然后,我们将解码后的RGB值按照BMP格式的像素排列方式进行调整,即将像素依次排列在内存。 最后,我们将调整后的像素数据写入BMP文件,以生成一个无损换的BMP图像。 需要注意的是,YUYV格式是一种压缩格式,换为BMP格式后虽然不会有质量损失,但是图像文件的大小可能会增大。另外,换过程还需要考虑字节对齐等细节问题。 总之,将V4L2的YUYV格式无损换为BMP格式需要进行颜色空间换和像素排列调整等步骤。通过这些步骤我们可以得到一个无损的BMP图像文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值