首页 > 代码库 > 嵌入式专题: 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 ;>