主题 : Linux下摄像头图像采集问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 28880
精华: 0
发帖: 13
金钱: 65 两
威望: 13 点
综合积分: 26 分
注册时间: 2010-09-18
最后登录: 2011-03-02
楼主  发表于: 2010-09-18 16:32

 Linux下摄像头图像采集问题

最近在弄Linux下的摄像头图像采集问题,开始的时候是学了会v4l(video for Linux),没弄成功,接着学习v4l2,网上给出了官方的示例程序,不过没有对图像进行处理或者保存,关键函数process_image() 只在屏幕打印一个点,表示摄像头取得一帧图像。想自己把这个函数写完整得以应用,发现不懂的东西太多,试了好几次都没成功,有朋友做过吗?求指导啊,急。。。。。。



下面是官方示例代码中的未实现的函数:

static void  process_image (const void * p)
{
      fputc ('.', stdout);
      fflush (stdout);
}



下面是一个网友提供的实现函数,貌似也没成功



static void process_image(const void * p)
{
      fputc('.', stdout);
      fflush(stdout);
      FILE * fp;
      static int nCnt=0;
      unsigned char *address;
      char filename[128];
      sprintf(filename, "pic%d.jpg", nCnt++);
      fp=fopen(filename,"w");
if(fp==NULL){
perror("open file failure");
exit(-1);
}

fprintf(fp,"P6\n%d %d\n255\n",MAX_W,MAX_H);
address =(unsigned char *)p;
if(address==NULL){
perror("get mapaddress Failed!");
exit(-1);
}
fwrite(address, MAX_W, 3*MAX_H, fp);
fclose(fp);
}

这个网友肯定是想得到jpg格式的图片,我猜想  fprintf(fp,"P6\n%d %d\n255\n",MAX_W,MAX_H); 是在图片文件前先写图片的格式头,后面的是写图片数据,不过,jpg图片的格式头,是这样的吗?我用UltraEdit打开任意一张jpg图片,写在最前面的表示格式的,都是FF D8 FF E0 开始的啊?不是"P6\n.....对应的16进制。。。
级别: 新手上路
UID: 16042
精华: 0
发帖: 47
金钱: 245 两
威望: 49 点
综合积分: 94 分
注册时间: 2010-03-13
最后登录: 2012-03-23
1楼  发表于: 2010-09-24 10:12
你直接把获取到的缓冲区整个保存为jpg为扩展名的文件就可以了,一般不用转换,因为大多webcam都是MJPG输出的.
需要注意的是有的摄像头的第一帧是损坏的,第二帧开始才是正确的数据,至少我的是这样.
另外你可以尝试输出下缓冲区的前几个字节,如你所说"FF D8 ..."是对的.
级别: 新手上路
UID: 28880
精华: 0
发帖: 13
金钱: 65 两
威望: 13 点
综合积分: 26 分
注册时间: 2010-09-18
最后登录: 2011-03-02
2楼  发表于: 2010-09-24 14:18
引用第1楼gdglacier于2010-09-24 10:12发表的  :
你直接把获取到的缓冲区整个保存为jpg为扩展名的文件就可以了,一般不用转换,因为大多webcam都是MJPG输出的.
需要注意的是有的摄像头的第一帧是损坏的,第二帧开始才是正确的数据,至少我的是这样.
另外你可以尝试输出下缓冲区的前几个字节,如你所说"FF D8 ..."是对的.

这个,我试过了,没有成功 。 我用v4l-info命令查看摄像头信息,是YUYV格式的,貌似要格式转换,这方面了解得少,还没成功,纠结。。。。
级别: 新手上路
UID: 29178
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
综合积分: 8 分
注册时间: 2010-09-24
最后登录: 2010-09-29
3楼  发表于: 2010-09-24 16:20
学习学习
级别: 新手上路
UID: 16042
精华: 0
发帖: 47
金钱: 245 两
威望: 49 点
综合积分: 94 分
注册时间: 2010-03-13
最后登录: 2012-03-23
4楼  发表于: 2010-09-25 00:05

 回 2楼(hdacer2) 的帖子

YUYV也不难,而且简省了解码过程能有效提高系统性能,一半来说YUV422比较常见.无非就是横向纵向的采样率不一样罢了,自己画个4x4的图一看就明白了.
你把YUV转RGB,然后保存为BMP格式就可以看结果了,或者转为RGB565直接写到LCD的Framebuffer实时显示.需要注意的是
BMP文件格式相当简单,就是一个头加上连续像素的BGR,不过要注意顺序是从下到上,google一下马上就能搞定.
级别: 新手上路
UID: 28880
精华: 0
发帖: 13
金钱: 65 两
威望: 13 点
综合积分: 26 分
注册时间: 2010-09-18
最后登录: 2011-03-02
5楼  发表于: 2010-09-25 15:42

 Re:回 2楼(hdacer2) 的帖子

引用第4楼gdglacier于2010-09-25 00:05发表的 回 2楼(hdacer2) 的帖子 :
YUYV也不难,而且简省了解码过程能有效提高系统性能,一半来说YUV422比较常见.无非就是横向纵向的采样率不一样罢了,自己画个4x4的图一看就明白了.
你把YUV转RGB,然后保存为BMP格式就可以看结果了,或者转为RGB565直接写到LCD的Framebuffer实时显示.需要注意的是
BMP文件格式相当简单,就是一个头加上连续像素的BGR,不过要注意顺序是从下到上,google一下马上就能搞定.


我的摄像头出来的就是YUV422的。关键就是YUV转RGB不了解,对这方面没有深入学习过,还望朋友你给点指导
级别: 新手上路
UID: 15288
精华: 0
发帖: 19
金钱: 105 两
威望: 21 点
综合积分: 38 分
注册时间: 2010-03-03
最后登录: 2017-09-13
6楼  发表于: 2010-09-26 10:53

 回 5楼(hdacer2) 的帖子

YUV422转rgb?那要损耗相当多的cpu资源,可以直接把yuv422压缩成jpeg,因为rgb到jpg中间也要转成yuv
级别: 新手上路
UID: 28880
精华: 0
发帖: 13
金钱: 65 两
威望: 13 点
综合积分: 26 分
注册时间: 2010-09-18
最后登录: 2011-03-02
7楼  发表于: 2010-09-26 11:32

 Re:回 5楼(hdacer2) 的帖子

引用第6楼explsz于2010-09-26 10:53发表的 回 5楼(hdacer2) 的帖子 :
YUV422转rgb?那要损耗相当多的cpu资源,可以直接把yuv422压缩成jpeg,因为rgb到jpg中间也要转成yuv

朋友,关键问题就是这里啊,这部分不了解,还望得到你的指导
级别: 新手上路
UID: 15288
精华: 0
发帖: 19
金钱: 105 两
威望: 21 点
综合积分: 38 分
注册时间: 2010-03-03
最后登录: 2017-09-13
8楼  发表于: 2010-09-26 13:22

 Re:Re:回 5楼(hdacer2) 的帖子

引用第7楼hdacer2于2010-09-26 11:32发表的 Re:回 5楼(hdacer2) 的帖子 :

朋友,关键问题就是这里啊,这部分不了解,还望得到你的指导


这个不难,确认图像格式是yuv422p吗?
网上有个函数,可以把yuv422p压缩成jpeg。
qq7504935
级别: 新手上路
UID: 28880
精华: 0
发帖: 13
金钱: 65 两
威望: 13 点
综合积分: 26 分
注册时间: 2010-09-18
最后登录: 2011-03-02
9楼  发表于: 2010-09-26 14:27

 Re:Re:Re:回 5楼(hdacer2) 的帖子

引用第8楼explsz于2010-09-26 13:22发表的 Re:Re:回 5楼(hdacer2) 的帖子 :


这个不难,确认图像格式是yuv422p吗?
网上有个函数,可以把yuv422p压缩成jpeg。
qq7504935


恩,谢谢