基于V4L2摄像头采集图片程序设计
#ifndef __COMMON_H #define __COMMON_H //该头文件定义的是摄像头在屏幕上显示的宽度和高度 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include <stdint.h> typedef unsigned char U8; typedef unsigned int U32; typedef unsigned short U16; #define WIDTH 800 #define HEIGHT 600 #endif //__COMMON_H
#ifndef __VIDEOCAPTURE_H #define __VIDEOCAPTURE_H #include"common.h" #include<sys/mman.h> #include<fcntl.h> #include<linux/videodev2.h> #define VIDEODEVNAME ("/dev/video0") #define COUNT 4 //需要调用的摄像头相关的接口,包括初始化,开始,结束,采取一帧的数据并保存 int initCamera(); void unInitCamera(); int startCamera(); int stopCamera(); int getOneFrame(U8* pcYuvBuffer); #endif //__VIDEOCAPTURE_H
#include"videoCapture.h" static U8* pcYuv[COUNT]={NULL}; static int vidDevFd = -1; static int nLength = 0; static struct v4l2_buffer dequeBuffer; static struct v4l2_buffer queueBuffer; //初始化摄像头程序 int initCamera() { //open /dev/video* //open video device vidDevFd = open(VIDEODEVNAME, O_RDONLY); if (vidDevFd < 0) { fprintf(stderr, "open %s failed %s\n",VIDEODEVNAME, strerror(errno)); return -1; } //printf("vidDevFd = %d!\n", vidDevFd); //设置视频格式 //set video device format struct v4l2_format vidDevFmt; vidDevFmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; vidDevFmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; vidDevFmt.fmt.pix.width = WIDTH; vidDevFmt.fmt.pix.height = HEIGHT; if (0 != ioctl(vidDevFd, VIDIOC_S_FMT, &vidDevFmt)) { fprintf(stderr, "VIDIOC_S_FMT failed %s\n", strerror(errno)); unInitCamera(); return -1; } //request buffers //max count need to be considered struct v4l2_requestbuffers reqBuffer; reqBuffer.count = COUNT; reqBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqBuffer.memory = V4L2_MEMORY_MMAP; if (0 != ioctl(vidDevFd, VIDIOC_REQBUFS, &reqBuffer)) { fprintf(stderr, "VIDIOC_REQBUFS failed %s\n", strerror(errno)); unInitCamera(); return -1; } //query buffers int i = 0; struct v4l2_buffer qryBuffer; qryBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; qryBuffer.memory = V4L2_MEMORY_MMAP; for (i = 0; i < COUNT; i++) { qryBuffer.index = i; if (0 != ioctl(vidDevFd, VIDIOC_QUERYBUF, &qryBuffer)) { fprintf(stderr, "VIDIOC_QUERYBUF failed %s\n", strerror(errno)); unInitCamera(); return -1; } printf("qryBuffer.m.offset=%d, qryBuffer.lenght=%d\n", qryBuffer.m.offset, qryBuffer.length); //mmap video device memory allocated by VIDIOC_REQBUFS pcYuv[i] = mmap(NULL, qryBuffer.length, PROT_READ, MAP_SHARED, vidDevFd, qryBuffer.m.offset); nLength = qryBuffer.length; //queue buffers struct v4l2_buffer queBuffer; queBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; queBuffer.memory = V4L2_MEMORY_MMAP; queBuffer.index = qryBuffer.index; if (0 != ioctl(vidDevFd, VIDIOC_QBUF, &queBuffer)) { fprintf(stderr, "init VIDIOC_QBUF failed %s\n", strerror(errno)); unInitCamera(); return -1; } } dequeBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; dequeBuffer.memory = V4L2_MEMORY_MMAP; queueBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; queueBuffer.memory = V4L2_MEMORY_MMAP; return 0; } //取消摄像头 void unInitCamera() { int i = 0; for (i = 0; i < COUNT; i++) { if (NULL != pcYuv[i]) { if (-1 == munmap(pcYuv[i], nLength)); { //fprintf(stderr,"munmap error:%s!\n",strerror(errno)); } pcYuv[i] = NULL; } } if (vidDevFd >= 0) close(vidDevFd); } //摄像头开始 int startCamera() { //start camera int nArg = 1; if (0 != ioctl(vidDevFd, VIDIOC_STREAMON, &nArg)) { fprintf(stderr, "VIDIOC_STREAMON failed %s\n", strerror(errno)); unInitCamera(); return -1; } return 0; } //停止摄像头 int stopCamera() { //stop camera int nArg = 1; if (0 != ioctl(vidDevFd, VIDIOC_STREAMOFF, &nArg)) { fprintf(stderr, "VIDIOC_STREAMOFF failed %s\n", strerror(errno)); unInitCamera(); return -1; } return 0; } //获取Frame int getOneFrame(unsigned char* pcYuyvBuffer) { if (0 != ioctl(vidDevFd, VIDIOC_DQBUF, &dequeBuffer)) { fprintf(stderr, "VIDIOC_DQBUF failed %s\n", strerror(errno)); unInitCamera(); return -1; } //get frame memcpy(pcYuyvBuffer, pcYuv[dequeBuffer.index], dequeBuffer.length); printf("len=%d\n",dequeBuffer.length); //queue queueBuffer.index = dequeBuffer.index; if (0 != ioctl(vidDevFd, VIDIOC_QBUF, &queueBuffer)) { fprintf(stderr, "VIDIOC_QBUF failed %s\n", strerror(errno)); unInitCamera(); return -1; } return 0; }
#include"videoCapture.h" int main(void ) { int nRet = 0; //char yuyv[WIDTH*HEIGHT*2]; char* pcYuvBuffer = NULL; if(-1 == initCamera()) { printf("initCamera failed!\n"); goto ERR; } if (-1 == startCamera()) { printf("startCamera failed!\n"); goto ERR; } pcYuvBuffer = (char*)malloc((WIDTH*HEIGHT*2)*sizeof(char)); if (NULL == pcYuvBuffer) { printf("malloc YUYV buffer failed!\n"); goto ERR; } int nDstFd = open("mytest.yuv", O_CREAT|O_EXCL|O_RDWR|O_TRUNC, 0777); if (nDstFd == -1) { fprintf(stderr, "open mytest.yuv failed:%s\n", strerror(errno)); } int nFrameNum = 0; while(1) { if (20 == nFrameNum) break; memset(pcYuvBuffer, 0, WIDTH*HEIGHT*2); //if (-1 == getOneFrame(yuyv)) if (-1 == getOneFrame(pcYuvBuffer)) { printf("getOneFrame error!\n"); goto ERR; } //if (-1 == write(nDstFd, yuyv, WIDTH*HEIGHT*2)) if (-1 == write(nDstFd, pcYuvBuffer, WIDTH*HEIGHT*2)) { fprintf(stderr, "write error:%s\n", strerror(errno)); goto ERR; } nFrameNum++; } if (-1 == stopCamera()) { printf("stopCamera error!\n"); } ERR: if (NULL != pcYuvBuffer) { free(pcYuvBuffer); pcYuvBuffer = NULL; } unInitCamera(); close(nDstFd); nDstFd = -1; return 0; }
基于V4L2摄像头采集图片程序设计的更多相关文章
- Linux 下V4l2摄像头采集图片,实现yuyv转RGB,RGB转BMP,RGB伸缩,jpeglib 库实现压缩RGB到内存中,JPEG经UDP发送功(转)
./configure CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld --host=arm-linux --prefix=/usr/loca ...
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集【转】
转自:http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一直想把USB摄像头接到Zedboard上,搭建 ...
- 14、USB摄像头(V4L2接口)的图片采集
参考网站http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一.一些知识 1.V4L和V4L2. V4L是 ...
- 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)
编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的. 基于现有资料 ...
- 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)持续更新
编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的. 基于现有资料 ...
- 基于视频压缩的实时监控系统-sprint1基于epoll架构的采集端程序设计
part1:产品功能 part2:epoll机制 select与epoll区别 1.select与epoll没有太大的区别.除了select有文件描述符限制(1024个),select每次调用都需 ...
- V4L2视频采集原理
一.简介 Video for Linuxtwo(Video4Linux2)简称V4L2,是V4L的改进版.V4L2是linux操作系统下用于采集图片.视频和音频数据的API接口,配合适当的视频采集设备 ...
- linux之V4L2摄像头应用流程【转】
本文转载自:http://blog.csdn.net/tommy_wxie/article/details/11486907 对于v4l2,上次是在调试收音机驱动的时候用过,其他也就只是用i2c配置一 ...
- Linux之V4L2视频采集编程详解
V4L2(Video For Linux Two) 是内核提供给应用程序访问音.视频驱动的统一接口. Linux系统中,视频设备被当作一个设备文件来看待,设备文件存放在 /dev目录下,完整路径的设 ...
随机推荐
- 【bzoj4443 scoi2015】小凸玩矩阵
题目描述 小凸和小方是好朋友,小方给了小凸一个 nn × mm (n \leq m)(n≤m) 的矩阵 AA ,并且要求小凸从矩阵中选出 nn 个数,其中任意两个数都不能在同一行或者同一列.现在小凸想 ...
- bzoj2442[Usaco2011 Open]修剪草坪 单调队列优化dp
2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1159 Solved: 593[Submit] ...
- BZOJ3065(替罪羊树套线段树)
以前看到这题都瑟瑟发抖,终于过了心情舒畅. 按下标为关键字建替罪羊树,每个结点开一个权值线段树,维护的这个结点代表的子树的信息. 这题还得垃圾回收,自己yy的,不知对不对.. #include < ...
- IOS UITextView支持输入、复制、粘贴、剪切自定义表情
UITextView是ios的富文本编辑控件,除了文字还可以插入图片等.今天主要介绍一下UITextView对自定义表情的处理. 1.首先识别出文本中的表情文本,然后在对应的位置插入NSTextAtt ...
- STM32 基于定时器的PWM发生器
脉冲宽度调制(PWM),是英文"Pulse Width Modulation" 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就 ...
- JavaScript中的类
JavaScript类的相关知识 1.例子 /* 例1 */// 定义一个构造函数function Range(from, to){ this.from = from; this.to = ...
- Java面试17|Java基础
Linux上配置Java基础环境: https://www.cnblogs.com/kerrycode/archive/2015/08/27/4762921.html 1.final相关 (1)fin ...
- PHP MySQL 创建数据表
PHP 创建 MySQL 表 一个数据表有一个唯一名称,并有行和列组成. 使用 MySQLi 和 PDO 创建 MySQL 表 CREATE TABLE 语句用于创建 MySQL 表. 我们将创建一个 ...
- Java内存泄漏分析系列之七:使用MAT的Histogram和Dominator Tree定位溢出源
原文地址:http://www.javatang.com 基础概念 先列出几个基础的概念: Shallow Heap 和 Retained Heap Shallow Heap表示对象本身占用内存的大小 ...
- 20160218.CCPP体系详解(0028天)
程序片段(01):加法.c 内容概要:字符串计算表达式 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <st ...