最近在研究FFmpeg,比较惊讶的是网上一大堆资料都是在说如何从已有的视频中截取一帧图像,却很少说到如何直接从摄像头中捕获一帧图像,其实我一直有个疑问,就是在Linux下,大家是用什么库来采集摄像头的(opencv?)?还是自己写v4l2的代码来实现?我之前一直都是用v4l2来采集摄像头的。经过一些时间的研究,最后成功地用FFmpeg实现了从摄像头采集一帧图像,实现代码也非常简单。不多说,上代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
void captureOneFrame()
{
AVFormatContext *fmtCtx = NULL;
AVFormatParameters inputFmtParameter;
AVPacket *pcaket;
//输入格式(V4L2)
AVInputFormat *inputFmt = av_find_input_format ("video4linux2");
if (inputFmt == NULL)
{
printf("can not find_input_format\n");
return;
}
memset (&inputFmtParameter, 0, sizeof(inputFmtParameter));
//采集图像的高度
inputFmtParameter.height = 240;
//采集图像的宽度
inputFmtParameter.width = 320;
//打开摄像头设备
if (av_open_input_file ( &fmtCtx, "/dev/video0", inputFmt,
sizeof(inputFmtParameter),&inputFmtParameter) < 0)
{
printf("can not open_input_file\n");
return;
}
//从摄像头获取一帧图像
av_read_frame(fmtCtx, pcaket);
//输出图像的大小
printf("data length = %d\n",pcaket->size);
FILE *fp;
//打开(新建)文件
fp = fopen("out.yuv", "wb");
if (fp < 0)
{
printf("open frame data file failed\n");
return ;
}
//将数据写入文件
fwrite(pcaket->data, 1, pcaket->size, fp);
//关闭文件
fclose(fp);
//关闭设备文件
av_close_input_file(fmtCtx);
}
int main()
{
avcodec_init();
avcodec_register_all();
avdevice_register_all();
captureOneFrame();
return 0;
}
注意:采集出来的图像的是YV12格式的。用YUV格式查看软件看下效果:
转自:http://www.cnblogs.com/lknlfy/archive/2012/03/31/2426788.html