首页 > 代码库 > 嵌入式专题: UVC摄像头摄像
嵌入式专题: UVC摄像头摄像
所谓的CMOS摄像头,驱动往往是一坨shit,想做摄像头应用,还是上UVC摄像头吧。
这个类里展示UVC摄像头的各种参数的设置。需要注意的是,如果帧率上不去,往往是由于曝光时间太长导致。这个关系是这样的,曝光越长,图片成像质量越好,但帧率自然就下去了。
#ifndef _UVC_CAMERA_H#define _UVC_CAMERA_Hclass UvcCamera{public: UvcCamera(); ~UvcCamera(); int Open(const char* dev, int width, int height); void Close(); int WaitForFrame(int ms); int ReadFrame(void* outbuf);private: int EnumFormats(); int SetFrameRate(int fps); int SetOther();private: int m_fd; struct bufinfo { void * start; size_t length; }; bufinfo m_bufs[10]; int m_bufcount;};#endif
#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>#include "UvcCamera.h"#define CLEAR(x) memset (&(x), 0, sizeof (x))UvcCamera::UvcCamera(){}UvcCamera::~UvcCamera(){}int UvcCamera::Open(const char* dev, int width, int height){ int ret , i; //打开设备 // m_fd = open (dev, O_RDWR /* required */ | O_NONBLOCK , 0); m_fd = open (dev, O_RDWR); if(m_fd < 0) { printf("failed to open capture device !\n"); return -1; } // 设置帧率 EnumFormats(); //获取摄像头参数 struct v4l2_capability cap; ret = ioctl (m_fd, VIDIOC_QUERYCAP, &cap); if(ret < 0) { printf("failed to query capability (%d)",ret); return -1; } //设置图像格式 struct v4l2_format v_fmt; CLEAR (v_fmt); v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v_fmt.fmt.pix.width = width; v_fmt.fmt.pix.height = height; v_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; v_fmt.fmt.pix.field = V4L2_FIELD_ANY; //V4L2_FIELD_INTERLACED; ret = ioctl (m_fd, VIDIOC_S_FMT, &v_fmt); if(ret < 0) { printf("failed to set format (%d) \n", ret); return -1; } ret = ioctl (m_fd, VIDIOC_G_FMT, &v_fmt); if(ret < 0) { printf("failed to set format (%d) \n", ret); return -1; } printf("real size: %d x %d \n", v_fmt.fmt.pix.width, v_fmt.fmt.pix.height); SetOther(); SetFrameRate(15); //cout << "the frame rate:" << (parm->parm.capture.timeperframe.numerator*1000)/(parm->parm.capture.timeperfr ame.denominator) << endl;// imgdata_size = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; //计算图片大小// printf("bytes per line: %d \n", fmt.fmt.pix.bytesperline); struct v4l2_requestbuffers v_req; CLEAR (v_req); v_req.count = 4; v_req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v_req.memory = V4L2_MEMORY_MMAP; ioctl (m_fd, VIDIOC_REQBUFS, &v_req); //申请缓冲,count是申请的数量 if (v_req.count < 2) { printf("Insufficient buffer memory\n"); return -1; } m_bufcount = v_req.count; for(i=0; i<m_bufcount; i++) { struct v4l2_buffer v_buf; //驱动中的一帧 CLEAR (v_buf); v_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v_buf.memory = V4L2_MEMORY_MMAP; v_buf.index = i; if (-1 == ioctl (m_fd, VIDIOC_QUERYBUF, &v_buf)) //映射用户空间 { printf ("VIDIOC_QUERYBUF error\n"); } printf("vbuf.length: %d \n", v_buf.length); void* ptr = mmap (NULL /* start anywhere */, //通过mmap建立映射关系 v_buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, m_fd, v_buf.m.offset); if(ptr == MAP_FAILED) { printf("mmap failed \n"); } else { m_bufs[i].length = v_buf.length; m_bufs[i].start = ptr; } } for (i = 0; i < m_bufcount; i++) { struct v4l2_buffer v_buf; CLEAR (v_buf); v_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v_buf.memory = V4L2_MEMORY_MMAP; v_buf.index = i; if (-1 == ioctl (m_fd, VIDIOC_QBUF, &v_buf))//申请到的缓冲进入列队 { printf ("VIDIOC_QBUF failed\n"); } } // 开始捕捉图像数据 enum v4l2_buf_type v_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (m_fd, VIDIOC_STREAMON, &v_type)) { printf ("VIDIOC_STREAMON failed\n"); return -1; } return 0;}void UvcCamera::Close(){ int i; for (i = 0; i < m_bufcount; ++i) { if (-1 == munmap (m_bufs[i].start, m_bufs[i].length)) { printf ("munmap error"); } } close(m_fd);}int UvcCamera::SetOther(){ printf("......... EXPOSURE ............\n"); if(1) { struct v4l2_control ctrl; ctrl.id = V4L2_CID_EXPOSURE_AUTO; if( 0 != ioctl(m_fd, VIDIOC_G_CTRL, &ctrl)) { printf("failed ....\n"); return -1; } printf("EXPOSURE mode (old) = %d \n", ctrl.value); ctrl.value = http://www.mamicode.com/V4L2_EXPOSURE_MANUAL ;>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。