您的位置:首页 > 其它

基于V4L2摄像头采集图片程序设计

2016-09-20 23:47 323 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: