4412 使用usb摄像头拍照YUYV格式
一、内核设置
Linux内核中已经带有很完善的USB摄像头驱动,支持几乎所有的USB摄像头,我们只需要配置内核,选择上相应的Sensor型号即可。
Device Drivers --->
<*> Multimedia support --->
<*> Video For Linux
[*] Enable Video For Linux API (DEPRECATED)
[*] Video capture adapters --->
[*] V4L USB devices --->
<*> USB Video Class (UVC)
[*] UVC input events device support
[*] GSPCA based webcams --->
二、编写V4L2的应用程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h> #include <asm/types.h>
#include <linux/videodev2.h> #define CAMERA_DEVICE "/dev/video0"
#define CAPTURE_FILE "frame.jpg" #define VIDEO_WIDTH 640
#define VIDEO_HEIGHT 480
#define VIDEO_FORMAT V4L2_PIX_FMT_YUYV
#define BUFFER_COUNT 4 typedef struct VideoBuffer {
void *start;
size_t length;
}VideoBuffer; int fd; //摄像头文件描述符 void open_camera(char *path);
void get_camera_info();
void get_vedio_info(); //打开设备
void open_camera(char *path)
{
fd = open(CAMERA_DEVICE, O_RDWR, );
if(fd < ) {
printf("Open %s failed\n", CAMERA_DEVICE);
exit(EXIT_FAILURE);
}
} //获取驱动信息
void get_camera_info()
{
struct v4l2_capability cap;
ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
if(ret < ) {
printf("VIDIOC_QUERYCAP failed (%d)\n", ret);
return ret;
}
// Print capability informations
printf("Capbility Informations:\n");
printf("*\tdriver: %s\n", cap.driver);
printf("*\tcard: %s\n", cap.card);
printf("*\tbus_info: %s\n", cap.bus_info);
printf("*\tversion: %08X\n", cap.version);
printf("*\tcapabilities: %08X\n", cap.capabilities);
} //获取视频格式
void get_vedio_info()
{
struct v4l2_format fmt;
memset(&fmt, , sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
if(ret < ) {
printf("VIDIOC_G_FMT failed (%d)\n", ret);
return ret;
}
// Print Stream Format
printf("Stream Format Informations:\n");
printf("*\ttype: %d\n", fmt.type);
printf("*\twidth: %d\n", fmt.fmt.pix.width);
printf("*\theight: %d\n", fmt.fmt.pix.height); char fmtstr[];
memset(fmtstr, , );
memcpy(fmtstr, &fmt.fmt.pix.pixelformat, );
printf("*\tpixelformat: %s\n", fmtstr);
printf("*\tfield: %d\n", fmt.fmt.pix.field);
printf("*\tbytesperline: %d\n", fmt.fmt.pix.bytesperline);
printf("*\tsizeimage: %d\n", fmt.fmt.pix.sizeimage);
printf("*\tcolorspace: %d\n", fmt.fmt.pix.colorspace);
printf("*\tpriv: %d\n", fmt.fmt.pix.priv);
// printf("*\traw_data: %s\n", fmt.fmt.raw_data); /* 显示所有支持的格式 */
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index = ;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("Support format:\n");
while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -) {
printf("\t%d.%s\n", fmtdesc.index+, fmtdesc.description);
fmtdesc.index++;
}
} int main()
{
int i, ret;
open_camera(CAMERA_DEVICE); get_camera_info(); get_vedio_info(); //请求分配内存
struct v4l2_requestbuffers reqbuf;
reqbuf.count = BUFFER_COUNT;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
if(ret < ) {
printf("VIDIOC_REQBUFS failed (%d)\n", ret);
return ret;
}
//获取空间
VideoBuffer *buffers = calloc(reqbuf.count, sizeof(*buffers));
if(!buffers) {
//映射
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
} for(i=;i<reqbuf.count;i++) {
struct v4l2_buffer buf;
memset(&buf, , sizeof(buf));
buf.index = i;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd, VIDIOC_QUERYBUF, &buf);
if(ret < ) {
printf("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
return ret;
}
// mmap buffer
buffers[i].length = buf.length;
buffers[i].start = (char *)mmap(, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
if(buffers[i].start == MAP_FAILED) {
printf("mmap (%d) failed: %s\n", i, strerror(errno));
return -;
} // Queen buffer
ret = ioctl(fd, VIDIOC_QBUF, &buf);
if(ret < ) {
printf("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
return -;
} printf("Frame buffer: %d: address=0x%x, length=%d\n", i,
(unsigned int)buffers[i].start, buffers[i].length);
} // 开始录制
struct v4l2_buffer buf;
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.index = ;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd, VIDIOC_STREAMON, &type);
if (ret < ) {
printf("VIDIOC_STREAMON failed (%d)\n", ret);
return ret;
} // Get frame
ret = ioctl(fd, VIDIOC_DQBUF, &buf);
if (ret < ) {
printf("VIDIOC_DQBUF failed (%d)\n", ret);
return ret;
} // Process the frame
FILE *fp = fopen(CAPTURE_FILE, "wb");
if (fp < ) {
printf("open frame data file failed\n");
return -;
}
fwrite(buffers[buf.index].start, , buf.length, fp);
fclose(fp);
printf("Capture one frame saved in %s\n", CAPTURE_FILE); // Re-queen buffer
ret = ioctl(fd, VIDIOC_QBUF, &buf);
if (ret < ) {
printf("VIDIOC_QBUF failed (%d)\n", ret);
return ret;
} // Release the resource
for(i=;i<;i++) {
munmap(buffers[i].start, buffers[i].length);
} close(fd);
printf("Camera test Done.\n");
return ;
}
三、使用软件打开
不过要选择对应的格式:
4412 使用usb摄像头拍照YUYV格式的更多相关文章
- 2.5 USB摄像头驱动程序框架
学习目标:根据vivi驱动架构和linux-2.6.31/linux-2.6.31.14/drivers/media/video/uvc/Uvc_driver.c驱动源码,分析usb摄像头驱动程序框架 ...
- USB摄像头驱动框架分析(五)
一.USB摄像头驱动框架如下所示:1.构造一个usb_driver2.设置 probe: 2.1. 分配video_device:video_device_alloc ...
- 25、写一个USB摄像头驱动程序(有ioctrl分析)
videobuf2-core.h中的vb2_buffer,记录了v4l2_buffer ,驱动可以对vb2_buffer的v4l2_buffer进行操控, vb2_buffer是v4l2框架层的代码, ...
- vue实现PC端调用摄像头拍照人脸录入、移动端调用手机前置摄像头人脸录入、及图片旋转矫正、压缩上传base64格式/文件格式
进入正题 1. PC端调用摄像头拍照上传base64格式到后台,这个没什么花里胡哨的骚操作,直接看代码 (canvas + video) <template> <div> &l ...
- 荣品四核4412开发板的USB摄像头问题
RP4412开发板是荣品电子研发的一款三星四核Exynos4412评估板开发板,支持WIFI+LAN上网.蓝牙4.0.4G上网.500万自动对焦摄像头.GPS.网卡.音频,1080P HDMI音视频同 ...
- 树莓派3 之 USB摄像头安装和使用
需求 如果你想在树莓上拍照或者录影,你可以安装树莓派的摄像头(有点贵).如果你不想要为摄像头模块花费额外的金钱,那有另外一个方法,就是你常见的USB 摄像头.你可能已经在PC上安装过了.我买的如图的这 ...
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集【转】
转自:http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一直想把USB摄像头接到Zedboard上,搭建 ...
- 2.7 usb摄像头之usb摄像头描述符打印
学习目标:参考lsusb源码,打印USB摄像头的设备描述符.配置描述符.接口联合描述符.端点描述符: 一.lsusb命令和源码 使用命令lsusb可以看看设备的id,并执行 # lsusb -v -d ...
- DIY远程移动图像监测(tiny6410+USB摄像头+motion+yeelink+curl)
看到有博客上采用motion搭建移动图像监测系统,感觉很强大,但大多缺少远程监测能力,大多局限于局域网.OK,笔者手头刚好有一个30W像素的USB摄像头,那么借用yeelink服务,也来DIY一把,哈 ...
随机推荐
- Jmeter响应中中文乱码怎么解决?
在jmeter的bin目录下有一个jmeter.properties的文件,打开它,搜索sampleresult.default.encoding,把它的注释打开,也就是把最前面的#去掉,改成samp ...
- 006-spring-data-elasticsearch 3.0.0.0使用【四】-spring-data之Elasticsearch Repositories
续 二.Elasticsearch Repositories 2.1.简介 2.1.1.Spring命名空间 Spring Data Elasticsearch模块包含一个允许定义存储库bean的自定 ...
- 使用spring配置类代替xml配置文件注册bean类
spring配置类,即在类上加@Configuration注解,使用这种配置类来注册bean,效果与xml文件是完全一样的,只是创建springIOC容器的方式不同: //通过xml文件创建sprin ...
- Docker安装及部署实例.Net Core
1.什么是Docker Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱 ...
- 类Calendar
/* * Calendar类概述及其方法 * * Calendar类概述 * Calendar类是一个抽象类,它为特定瞬间与一组诸如YEAR.MONTH.DAY_OF_MONTH.HOUR等 * 日历 ...
- IDEA中Java目录结构
IDEA中Java的目录结构 1.首先新建Project,选择Empty,新建空的项目 2.选择Module时候,需要选择JDK,JDK只需要选择到Java Home目录就可以了 3.创建好Modul ...
- hasattr() getattr() setattr() 函数使用详解??
hasattr(object, name)函数: 判断一个对象里面是否有name属性或者name方法,返回bool值,有name属性(方法)返回True,否则返回False. **注意:name要使用 ...
- log.info()传入多个参数的方法
不知道项目里用的是啥 ** 版本的 log4j 居然不能传入变长参数 logger.info(String.format("%s %s %s", username, feature ...
- C#如何在Socket传递负数,比如-51
1.关于计算机中的原码.反码和补码定义 1.原码 将最高位作为符号位(以0代表正,1代表负),其余各位代表数值本身的绝对值(以二进制表示).为了简单起见,我们用1个字节来表示一个整数. + ...
- polyfill.io 试用
Polyfill 可以为旧浏览器提供和标准 API 一样的功能.比如你想要 IE 浏览器实现 Promise 和 fetch 功能,你需要手动引入 es6-promise.whatwg-fetch.而 ...