UP

您所在的位置:网站首页 嵌入式摄像头视频采集 UP

UP

2024-07-03 23:23| 来源: 网络整理| 查看: 265

UP-MOBNET-Ⅱ型实验箱摄像机视频采集实验

文章目录 实验箱型号实验内容和材料准备实验环境准备试验箱烧写linux系统redHat配置交叉编译环境 V4l2视频采集原理编写摄像机驱动程序和测试程序camer.hcamer.cmain.cMakefile 特别强调交叉编译驱动程序移植和演示程序

实验箱型号 名称移动互联网教学科研平台Ⅱ型型号UP-MOBNET-Ⅱ编号03019024批号32017040520 实验内容和材料准备 实验内容:       实验了解v4l2视频采集过程和原理、熟悉试验箱开发环境和烧写流程、交叉编译原理和程序移植。 硬件:       UP-MobNet-II 型平台、12V 电源线、串口线、USB 数据线 软件:       Xshell、fastboot.exe、fastboot.bat、WinImage.exe

实验环境准备 整体流程: 实验环境准备 实验箱Linux环境 交叉编译环境 交叉编译程序 程序移植 测试程序

试验箱烧写linux系统 UP-MobNet-II 型出厂程序烧写 注:出厂烧写文件镜像及工具存放在光盘的 IMG 文件夹下!且 u-boot 一般用户无需更改,该烧写步骤可以略过。 该试验箱u-boot不需要改动;出厂时BootLoader已经写好 1. 连线: 将产品附带串口线一端连接到 PC 机端串口,另一端连接到 UP-MobNet-II 型平台串口 0(RS232-0 即开发板左侧起靠近网口的串口)上。 将产品附带 USB 数据线连接 PC 机 USB 口与 UP-MobNet-II 型平台 OTG 接口。 其中串口大概是4、电源开关是1、网线口是2、usb数据线口(OTG接口)是3

在这里插入图片描述

2. 跳线: 备注:核心板内侧为 1,外侧为 0,跳线模式出厂已经默认跳到 iNAND 模式,根据需要更改。 这里试验箱跳线一般已经调好,不需要改动 3. 使用Xshell登录UP-MobNet-II 型系统串口终端

(如果这时间有需要安装驱动,在Win10中可以下载驱动精灵,其可以帮助管理所需要的驱动)

首先查看电脑的端口号: 电脑->管理->设备管理器(Win10需要在查看中打开显示隐藏设备)->端口(COM) Xshell连接UP-MobNet-II : Xshell->文件->新建->连接->协议serial->串口->选择自己的COM->波特率115200->连接 确定连接后,连接电源。按下 UP-MobNet-II 型平台左上角 POWER 电源键,系统上电。Xshell 进入开发板的 U-BOOT 功能界面(3秒等待),(3秒内)按下回车,进入 U-BOOT 界面 在 u-boot 界面下,输入 fastboot 命令. 因为该板子BootLoader出厂写好了不需要烧写 u-boot.bin 直接烧写系统镜像 zImage、rootfs_up4412.cramfs: 双击光盘/IMG/fastboot.bat 文件->选择'2'kernel 烧写 zImage(完成后)->选择‘3’system 烧写 rootfs_up4412.cramfs 完成烧写,重启实验平台,加载启动信息

如下图所示:

查看端口号:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Xshell连接实验箱:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

进入Uboot模式

在这里插入图片描述

使用fastboot工具

在这里插入图片描述

在这里插入图片描述

烧写完成,加载启动信息

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

redHat配置交叉编译环境 将光盘中交叉编译工具的源码 arm-2009q3.tar.bz2 拷贝到/usr/local/arm(没有该目录就新建一个)目录下,并解压: #tar jxvf arm-2009q3.tar.bz2 2. 修改环境变量: #vim ~/.bashrc 在文件末添加 export PATH=/usr/local/arm/arm-2009q3/bin:$PATH 编译器安装成功。 #source ~/.bashrc 测试 arm-none-linux-gnueabi-gcc -v 注意,如果是64位Linux系统(ubuntu20),需要再安装额外的一些软件。如下操作。  .安装32位库(64位系统需要)   因为ia32-libs数据库的问题需安装32位库   依次执行下列命令即可 1. sudo dpkg --add-architecture i386 2. sudo apt-get update 3. sudo apt-get dist-upgrade ubuntu 20安装以上库之后,还是提示找不到arm-none-linux-gnueabi-gcc错误。之后安装libc6-i386库,解决问题。 apt-get install libc6-i386 测试 arm-none-linux-gnueabi-gcc -v

arm-none-linux-gnueabi-gcc -v

在这里插入图片描述

V4l2视频采集原理 打开视频设备 设定属性 设定采集方式 处理数据 关闭视频设备

采集方式 打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux编程中,一般使用ioctl函数来对设备的I/O通道进行管理: extern int ioctl (int __fd, unsigned long int __request, …) __THROW; __fd:设备的ID,例如刚才用open函数打开视频通道后返回的cameraFd; __request:具体的命令标志符。 在进行V4L2开发中,一般会用到以下的命令标志符:

VIDIOC_REQBUFS:分配内存 VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址 VIDIOC_QUERYCAP:查询驱动功能 VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式 VIDIOC_S_FMT:设置当前驱动的频捕获格式 VIDIOC_G_FMT:读取当前驱动的频捕获格式 VIDIOC_TRY_FMT:验证当前驱动的显示格式 VIDIOC_CROPCAP:查询驱动的修剪能力 VIDIOC_S_CROP:设置视频信号的边框 VIDIOC_G_CROP:读取视频信号的边框 VIDIOC_QBUF:把数据放回缓存队列 VIDIOC_DQBUF:把数据从缓存中读取出来 VIDIOC_STREAMON:开始视频显示函数 VIDIOC_STREAMOFF:结束视频显示函数 VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。 这些IO调用,有些是必须的,有些是可选择的。 操作流程 1. 打开设备文件。 int fd=open(”/dev/video0″,O_RDWR); 2. 取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability v4l2_std_id std; do { ret= ioctl(fd, VIDIOC_QUERYSTD, &std); } while (ret == -1 && errno == EAGAIN); switch (std) { case V4L2_STD_NTSC: //…… case V4L2_STD_PAL: //…… }

操作流程

打开设备文件。 int fd=open(”/dev/video0″,O_RDWR); 取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability v4l2_std_id std; do { ret= ioctl(fd, VIDIOC_QUERYSTD, &std); } while (ret == -1 && errno == EAGAIN); switch (std) { case V4L2_STD_NTSC: //…… case V4L2_STD_PAL: //…… } 选择视频输入,一个视频设备可以有多个视频输入。

VIDIOC_S_INPUT,struct v4l2_input(可不要)

设置视频的制式和帧格式,制式包括PAL,NTSC,帧的格式个包括宽度和高度等。 VIDIOC_S_STD,VIDIOC_S_FMT,struct v4l2_std_id,struct v4l2_format struct v4l2_format fmt; v4l2_format 结构如下: struct v4l2_format { enum v4l2_buf_type type; // 数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE union { struct v4l2_pix_format pix; struct v4l2_window win; struct v4l2_vbi_format vbi; __u8 raw_data[200]; } fmt; }; struct v4l2_pix_format { __u32 width; // 宽,必须是16 的倍数 __u32 height; // 高,必须是16 的倍数 __u32 pixelformat; // 视频数据存储类型,例如是YUV 4 :2 :2 还是RGB enum v4l2_field field; __u32 bytesperline; __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; };

样例:

memset ( &fmt, 0, sizeof(fmt) ); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = 320; fmt.fmt.pix.height = 240; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; if (ioctl(fd, VIDIOC_S_FMT, &fmt) 8)&0xFF,(cap.version)&0xFF); //选择视频输入 struct v4l2_input input; CLEAN(input); input.index = 0; if ( ioctl_(fd, VIDIOC_S_INPUT,&input) == -1){ printf("VIDIOC_S_INPUT IS ERROR! LINE:%d\n",__LINE__); return -1; } /*查看摄像头支持的视频格式*/ struct v4l2_fmtdesc fmtdesc; // struct v4l2_frmsizeenum frmsize; fmtdesc.index = 0; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; printf("fm:\n"); while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1){ //列举出所有支持的格式 printf("%d.%s %c%c%c%c\n", fmtdesc.index + 1, fmtdesc.description, fmtdesc.pixelformat & 0xFF, (fmtdesc.pixelformat >> 8) & 0xFF, (fmtdesc.pixelformat >> 16) & 0xFF, (fmtdesc.pixelformat >> 24) & 0xFF); #if 0 frmsize.pixel_format = fmtdesc.pixelformat; frmsize.index = 0; while(ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) != -1){ printf("%dx%d\n",frmsize.discrete.width, frmsize.discrete.height); frmsize.index++; } #endif fmtdesc.index++; } /*查看摄像头支持的分辨率*/ //设置帧格式 struct v4l2_format fmt; CLEAN(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = WIDTH; fmt.fmt.pix.height = HEIGHT; //视频格式 // fmt.fmt.pix.pixelformat = pixformat; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420; // fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (ioctl_(fd, VIDIOC_S_FMT, &fmt) == -1) { printf("VIDIOC_S_FMT IS ERROR! LINE:%d\n",__LINE__); return -1; } fmt.type = V4L2_BUF_TYPE_PRIVATE; if (ioctl_(fd, VIDIOC_S_FMT, &fmt) == -1){ printf("VIDIOC_S_FMT IS ERROR! LINE:%d\n", __LINE__); return -1; } //查看帧格式 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if ( ioctl_(fd, VIDIOC_G_FMT, &fmt) == -1){ printf("VIDIOC_G_FMT IS ERROR! LINE:%d\n", __LINE__); return -1; } printf("width:%d\nheight:%d\npixelformat:%c%c%c%c field:%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF, (fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF, fmt.fmt.pix.field ); #if 0 /*设置流相关  帧率*/ struct v4l2_streamparm parm; CLEAN(parm); parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME; //是否可以被timeperframe参数控制帧率 parm.parm.capture.timeperframe.denominator = 30; //时间间隔分母 parm.parm.capture.timeperframe.numerator = 1; //分子 if (ioctl_(fd, VIDIOC_S_PARM, &parm) == -1){ // printf("VIDIOC_S_PARM IS ERROR! \n"); perror("VIDIOC_S_PARM"); return -1; } if (ioctl_(fd, VIDIOC_G_PARM, (struct v4l2_streamparm*)&parm) == -1){ printf("VIDIOC_G_PARM IS ERROR! \n"); return -1; } #endif #if 1 /*YUYV*/ __u32 min = fmt.fmt.pix.width * 2; if ( fmt.fmt.pix.bytesperline Mail: [email protected] > Created Time: 2020年11月21日 星期六 18时46分19秒 ************************************************************************/ #include #include"camer.h" #define DEVICE_NAME "/dev/video0" #define FILE_NAME "./out.yuv" int main(int argc,char *argv[]) { int ret = 0; int i; ret = open_device(DEVICE_NAME); if (ret == -1) exit(EXIT_FAILURE); open_file(FILE_NAME); init_device(); init_mmap(); start_stream(); for (i = 0 ; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3