Linux开发板调用摄像头(V4L2编程,含YUYV解码RGB)

本文介绍了如何在Linux开发板上使用V4L2 API进行摄像头调用,包括YUYV格式的视频数据解码成RGB,并在开发板屏幕上显示。详细步骤涵盖了设备打开、属性设置、帧格式设定、缓冲区管理、数据循环获取、解码及显示,最后是设备关闭。代码可直接在Linux环境下编译运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Linux的V4L2编程部分参考:

        Linux之V4L2基础编程 - emouse - 博客园

使用YUY2(YUV)与RGB之间相互转化参考:

        (转)RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解 - 神一样的魔鬼 - 博客园

        本文是基于Linux开发板的V4L2摄像头调用程序,包括YUYV解码为RGB,以及将摄像头数据显示在开发板屏幕上。代码未封装,可直接在linux下编译使用。

        工作流程:打开设备 —> 检查和设置设备属性 —> 设置帧格式 —> 设置一种输入输出方法(缓冲区管理) —> 循环获取数据 —> 数据解码 —> 显示在lcd上 —> 关闭设备。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include <pthread.h>
#include <linux/fb.h>
#include <stdbool.h>

unsigned int *lcdptr = NULL;  //lcd映射内存首地址
int lcd_width;  //lcd屏幕宽
int lcd_height;   //lcd屏幕高

int camera_width = 640;  //camere屏幕宽
int camera_height = 480;   //camera屏幕高

void lcd_show_rgb(unsigned char *rgbdata,int width,int height);   //在lcd上显示
int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB);  //YUYV格式转换为RGB格式

int main(void)
{
	int lcdfd = open("/dev/fb0", O_RDWR); //打开 LCD屏幕
	if(lcdfd < 0)
	{
		perror("/dev/fb0");
		exit(-1);
	}
	//获取屏幕宽高
	struct fb_var_screeninfo lcdvar;
	ioctl(lcdfd, FBIOGET_VSCREENINFO , &lcdvar);
	lcd_width = lcdvar.xres;  
	lcd_height = lcdvar.yres; 
	//4 = 透明度 + RGB
	lcdptr = (unsigned int *)mmap( NULL, lcd_width*lcd_height*4 ,    	 	//映射fb内存空间长度 	 
					PROT_READ | PROT_WRITE,	//可读可写
					MAP_SHARED,     		//进程间共享机制
					lcdfd, 				//lcd的文件描述符
					0);
					
	
	//1.打开摄像头设备
	int fd = open("/dev/video1",O_RDWR);  //video0 或 video1
	if(fd < 0)
	{
		perror("打开设备失败");
		return -1;
	}
	
	//2.获取摄像头支持的格式 ioctl(文件描述符,命令,与命令对应的结构体)
	//查询并显示所有支持的格式:VIDIOC_ENUM_FMT ,获取对应结构体
  /*struct v4l2_fmtdesc
	{
		u32 index; // 要查询的格式序号,应用程序设置
		enum v4l2_buf_type type; // 帧类型,应用程序设置
		u32 flags; // 是否为压缩格式
		u8 description[32]; // 格式名称
		u32 pixelformat; // 格式
		u32 reserved[4]; // 保留
	};
	*/
	
	
	//3.配置摄像头采集格式
	//查看或设置当前格式: VIDIOC_G_FMT, VIDIOC_S_FMT
	/* 
	struct v4l2_format
	{
		enum v4l2_buf_type type; // 帧类型,应用程序设置
		union fmt
		{
			struct v4l2_pix_format pix; // 视频设备使用
			struct v4l2_window win;
			struct v4l2_vbi_format vbi;
			struct v4l2_sliced_vbi_format sliced;
			u8 raw_data[200];
		}; 
	}; 
	
	struct v4l2_pix_format
	{
		u32 width; // 帧宽,单位像素
		u32 height; // 帧高,单位像素
		u32 pixelformat; // 帧格式
		enum v4l2_field field;
		u32 bytesperline;
		u32 sizeimage;
		enum v4l2_colorspace colorspace;
		u32 priv;
	};
	*/
	struct v4l2_format vfmt; 
	vfmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; //设置类型摄像头采集
	vfmt.fmt.pix.width = camera_width;  //设置宽
	vfmt.fmt.pix.height = camera_height;   //设置高
	vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;  //根据摄像头设置格式
	int ret;
	ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);
	if(ret < 0)
	{
		perror("设置格式失败");
	}	
	printf("Current data format information:\n\twidth:%d\n\theigh
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值